mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
* config/tc-alpha.c (alpha_ip): Delay calls to emit_add64 until after any
remaining operands are also known to match.
This commit is contained in:
@ -2,6 +2,9 @@ Fri Jan 6 16:59:41 1995 Ken Raeburn <raeburn@cujo.cygnus.com>
|
|||||||
|
|
||||||
* gasp.c: Include string.h. Put config.h before other includes.
|
* gasp.c: Include string.h. Put config.h before other includes.
|
||||||
|
|
||||||
|
* config/tc-alpha.c (alpha_ip): Delay calls to emit_add64 until
|
||||||
|
after any remaining operands are also known to match.
|
||||||
|
|
||||||
Fri Dec 30 18:21:41 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
|
Fri Dec 30 18:21:41 1994 Ken Raeburn <raeburn@cujo.cygnus.com>
|
||||||
|
|
||||||
* listing.c (list_symbol_table): Build a format string based on
|
* listing.c (list_symbol_table): Build a format string based on
|
||||||
|
@ -130,7 +130,7 @@ static void emit_ldah_num PARAMS ((int, bfd_vma, int));
|
|||||||
static void emit_addq_r PARAMS ((int, int, int));
|
static void emit_addq_r PARAMS ((int, int, int));
|
||||||
static void emit_lda_n PARAMS ((int, bfd_vma, int));
|
static void emit_lda_n PARAMS ((int, bfd_vma, int));
|
||||||
static void emit_add64 PARAMS ((int, int, bfd_vma));
|
static void emit_add64 PARAMS ((int, int, bfd_vma));
|
||||||
static int in_range PARAMS ((bfd_vma, int, int));
|
static int in_range_signed PARAMS ((bfd_vma, int));
|
||||||
|
|
||||||
const pseudo_typeS md_pseudo_table[] =
|
const pseudo_typeS md_pseudo_table[] =
|
||||||
{
|
{
|
||||||
@ -430,9 +430,9 @@ s_base ()
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int in_range (val, nbits, unsignedness)
|
static int in_range_signed (val, nbits)
|
||||||
bfd_vma val;
|
bfd_vma val;
|
||||||
int nbits, unsignedness;
|
int nbits;
|
||||||
{
|
{
|
||||||
/* Look at top bit of value that would be stored, figure out how it
|
/* Look at top bit of value that would be stored, figure out how it
|
||||||
would be extended by the hardware, and see if that matches the
|
would be extended by the hardware, and see if that matches the
|
||||||
@ -445,27 +445,40 @@ static int in_range (val, nbits, unsignedness)
|
|||||||
stored_value = val & mask;
|
stored_value = val & mask;
|
||||||
top_bit = stored_value & (one << nbits - 1);
|
top_bit = stored_value & (one << nbits - 1);
|
||||||
missing_bits = val & ~mask;
|
missing_bits = val & ~mask;
|
||||||
if (unsignedness)
|
/* will sign-extend */
|
||||||
|
if (top_bit)
|
||||||
{
|
{
|
||||||
return missing_bits == 0;
|
/* all remaining bits beyond mask should be one */
|
||||||
|
missing_bits |= mask;
|
||||||
|
return missing_bits + 1 == 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* will sign-extend */
|
/* all other bits should be zero */
|
||||||
if (top_bit)
|
return missing_bits == 0;
|
||||||
{
|
|
||||||
/* all remaining bits beyond mask should be one */
|
|
||||||
missing_bits |= mask;
|
|
||||||
return missing_bits + 1 == 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* all other bits should be zero */
|
|
||||||
return missing_bits == 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int in_range_unsigned (val, nbits)
|
||||||
|
bfd_vma val;
|
||||||
|
int nbits;
|
||||||
|
{
|
||||||
|
/* Look at top bit of value that would be stored, figure out how it
|
||||||
|
would be extended by the hardware, and see if that matches the
|
||||||
|
original supplied value. */
|
||||||
|
bfd_vma mask;
|
||||||
|
bfd_vma one = 1;
|
||||||
|
bfd_vma top_bit, stored_value, missing_bits;
|
||||||
|
|
||||||
|
mask = (one << nbits) - 1;
|
||||||
|
stored_value = val & mask;
|
||||||
|
top_bit = stored_value & (one << nbits - 1);
|
||||||
|
missing_bits = val & ~mask;
|
||||||
|
return missing_bits == 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
s_gprel32 ()
|
s_gprel32 ()
|
||||||
{
|
{
|
||||||
@ -509,8 +522,6 @@ create_literal_section (secp, name)
|
|||||||
| SEC_DATA);
|
| SEC_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define create_lita_section() create_literal_section (&lita_sec, ".lita")
|
|
||||||
|
|
||||||
static valueT
|
static valueT
|
||||||
get_lit8_offset (val)
|
get_lit8_offset (val)
|
||||||
bfd_vma val;
|
bfd_vma val;
|
||||||
@ -648,7 +659,7 @@ md_begin ()
|
|||||||
|
|
||||||
/* So .sbss will get used for tiny objects. */
|
/* So .sbss will get used for tiny objects. */
|
||||||
bfd_set_gp_size (stdoutput, 8);
|
bfd_set_gp_size (stdoutput, 8);
|
||||||
create_lita_section ();
|
create_literal_section (&lita_sec, ".lita");
|
||||||
/* For handling the GP, create a symbol that won't be output in the
|
/* For handling the GP, create a symbol that won't be output in the
|
||||||
symbol table. We'll edit it out of relocs later. */
|
symbol table. We'll edit it out of relocs later. */
|
||||||
gp = symbol_create ("<GP value>", lita_sec, 0x8000, &zero_address_frag);
|
gp = symbol_create ("<GP value>", lita_sec, 0x8000, &zero_address_frag);
|
||||||
@ -1136,14 +1147,14 @@ emit_add64 (in, out, num)
|
|||||||
{
|
{
|
||||||
bfd_signed_vma snum = num;
|
bfd_signed_vma snum = num;
|
||||||
|
|
||||||
if (in_range (num, 16, 0))
|
if (in_range_signed (num, 16))
|
||||||
{
|
{
|
||||||
emit_lda_n (out, num, in);
|
emit_lda_n (out, num, in);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((num & 0xffff) == 0
|
if ((num & 0xffff) == 0
|
||||||
&& in == ZERO
|
&& in == ZERO
|
||||||
&& in_range (snum >> 16, 16, 0))
|
&& in_range_signed (snum >> 16, 16))
|
||||||
{
|
{
|
||||||
emit_ldah_num (out, snum >> 16, in);
|
emit_ldah_num (out, snum >> 16, in);
|
||||||
return;
|
return;
|
||||||
@ -1151,21 +1162,21 @@ emit_add64 (in, out, num)
|
|||||||
/* I'm not sure this one is getting invoked when it could. */
|
/* I'm not sure this one is getting invoked when it could. */
|
||||||
if ((num & 1) == 0 && in == ZERO)
|
if ((num & 1) == 0 && in == ZERO)
|
||||||
{
|
{
|
||||||
if (in_range (snum >> 1, 16, 0))
|
if (in_range_signed (snum >> 1, 16))
|
||||||
{
|
{
|
||||||
emit_lda_n (out, snum >> 1, in);
|
emit_lda_n (out, snum >> 1, in);
|
||||||
emit_addq_r (out, out, out);
|
emit_addq_r (out, out, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (num & 0x1fffe == 0
|
else if (num & 0x1fffe == 0
|
||||||
&& in_range (snum >> 17, 16, 0))
|
&& in_range_signed (snum >> 17, 16))
|
||||||
{
|
{
|
||||||
emit_ldah_num (out, snum >> 17, in);
|
emit_ldah_num (out, snum >> 17, in);
|
||||||
emit_addq_r (out, out, out);
|
emit_addq_r (out, out, out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (in_range (num, 32, 0))
|
if (in_range_signed (num, 32))
|
||||||
{
|
{
|
||||||
bfd_vma lo = num & 0xffff;
|
bfd_vma lo = num & 0xffff;
|
||||||
if (lo & 0x8000)
|
if (lo & 0x8000)
|
||||||
@ -1202,12 +1213,6 @@ emit_add64 (in, out, num)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note that for now, this function is called recursively (by way of
|
|
||||||
calling md_assemble again). Some of the macros defined as part of
|
|
||||||
the assembly language are currently rewritten as sequences of
|
|
||||||
strings to be assembled. See, for example, the handling of "divq".
|
|
||||||
|
|
||||||
For efficiency, this should be fixed someday. */
|
|
||||||
static int
|
static int
|
||||||
alpha_ip (str, insns)
|
alpha_ip (str, insns)
|
||||||
char *str;
|
char *str;
|
||||||
@ -1223,6 +1228,8 @@ alpha_ip (str, insns)
|
|||||||
unsigned int mask;
|
unsigned int mask;
|
||||||
int match = 0, num_gen = 1;
|
int match = 0, num_gen = 1;
|
||||||
int comma = 0;
|
int comma = 0;
|
||||||
|
int do_add64, add64_in, add64_out;
|
||||||
|
bfd_vma add64_addend;
|
||||||
|
|
||||||
for (s = str;
|
for (s = str;
|
||||||
islower (*s) || *s == '_' || *s == '/' || *s == '4' || *s == '8';
|
islower (*s) || *s == '_' || *s == '/' || *s == '4' || *s == '8';
|
||||||
@ -1248,7 +1255,7 @@ alpha_ip (str, insns)
|
|||||||
}
|
}
|
||||||
if ((pattern = (struct alpha_opcode *) hash_find (op_hash, str)) == NULL)
|
if ((pattern = (struct alpha_opcode *) hash_find (op_hash, str)) == NULL)
|
||||||
{
|
{
|
||||||
as_warn ("Unknown opcode: `%s'", str);
|
as_bad ("Unknown opcode: `%s'", str);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (comma)
|
if (comma)
|
||||||
@ -1257,6 +1264,7 @@ alpha_ip (str, insns)
|
|||||||
argsStart = s;
|
argsStart = s;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
do_add64 = 0;
|
||||||
opcode = pattern->match;
|
opcode = pattern->match;
|
||||||
num_gen = 1;
|
num_gen = 1;
|
||||||
for (i = 0; i < MAX_INSNS; i++)
|
for (i = 0; i < MAX_INSNS; i++)
|
||||||
@ -1465,24 +1473,14 @@ alpha_ip (str, insns)
|
|||||||
insns[0].reloc[0].code = BFD_RELOC_26;
|
insns[0].reloc[0].code = BFD_RELOC_26;
|
||||||
goto immediate;
|
goto immediate;
|
||||||
|
|
||||||
#if 0
|
case 't': /* 12 bit displacement, for PALcode */
|
||||||
case 't': /* 12 bit 0...11 */
|
insns[0].reloc[0].code = BFD_RELOC_12_PCREL;
|
||||||
insns[0].reloc = RELOC_0_12;
|
|
||||||
goto immediate;
|
goto immediate;
|
||||||
|
|
||||||
case '8': /* 8 bit 0...7 */
|
case '8': /* 8 bit 0...7 */
|
||||||
insns[0].reloc = RELOC_0_8;
|
insns[0].reloc[0].code = BFD_RELOC_8;
|
||||||
goto immediate;
|
goto immediate;
|
||||||
|
|
||||||
case 'I': /* 26 bit immediate */
|
|
||||||
insns[0].reloc = RELOC_0_25;
|
|
||||||
#else
|
|
||||||
case 't':
|
|
||||||
case '8':
|
|
||||||
abort ();
|
|
||||||
#endif
|
|
||||||
/*FALLTHROUGH*/
|
|
||||||
|
|
||||||
immediate:
|
immediate:
|
||||||
if (*s == ' ')
|
if (*s == ' ')
|
||||||
s++;
|
s++;
|
||||||
@ -1523,8 +1521,10 @@ alpha_ip (str, insns)
|
|||||||
else if (at_ok && macro_ok)
|
else if (at_ok && macro_ok)
|
||||||
{
|
{
|
||||||
/* Constant value supplied, but it's too large. */
|
/* Constant value supplied, but it's too large. */
|
||||||
emit_add64 (ZERO, AT,
|
do_add64 = 1;
|
||||||
insns[0].reloc[0].exp.X_add_number);
|
add64_in = ZERO;
|
||||||
|
add64_out = AT;
|
||||||
|
add64_addend = insns[0].reloc[0].exp.X_add_number;
|
||||||
opcode &= ~ 0x1000;
|
opcode &= ~ 0x1000;
|
||||||
opcode |= (AT << SB);
|
opcode |= (AT << SB);
|
||||||
insns[0].reloc[0].code = BFD_RELOC_NONE;
|
insns[0].reloc[0].code = BFD_RELOC_NONE;
|
||||||
@ -1534,19 +1534,22 @@ alpha_ip (str, insns)
|
|||||||
}
|
}
|
||||||
else if (insns[0].reloc[0].code == BFD_RELOC_16
|
else if (insns[0].reloc[0].code == BFD_RELOC_16
|
||||||
&& insns[0].reloc[0].exp.X_op == O_constant
|
&& insns[0].reloc[0].exp.X_op == O_constant
|
||||||
&& !in_range (insns[0].reloc[0].exp.X_add_number,
|
&& !in_range_signed (insns[0].reloc[0].exp.X_add_number,
|
||||||
16, 0))
|
16))
|
||||||
{
|
{
|
||||||
bfd_vma val = insns[0].reloc[0].exp.X_add_number;
|
bfd_vma val = insns[0].reloc[0].exp.X_add_number;
|
||||||
if (OPCODE (opcode) == 0x08)
|
if (OPCODE (opcode) == 0x08)
|
||||||
{
|
{
|
||||||
emit_add64 (ZERO, AT, val);
|
do_add64 = 1;
|
||||||
|
add64_in = ZERO;
|
||||||
|
add64_out = AT;
|
||||||
|
add64_addend = val;
|
||||||
opcode &= ~0x1000;
|
opcode &= ~0x1000;
|
||||||
opcode |= (AT << SB);
|
opcode |= (AT << SB);
|
||||||
insns[0].reloc[0].code = BFD_RELOC_NONE;
|
insns[0].reloc[0].code = BFD_RELOC_NONE;
|
||||||
}
|
}
|
||||||
else if (OPCODE (opcode) == 0x09
|
else if (OPCODE (opcode) == 0x09
|
||||||
&& in_range (val >> 16, 16, 0))
|
&& in_range_signed (val >> 16, 16))
|
||||||
{
|
{
|
||||||
/* ldah with high operand - convert to low */
|
/* ldah with high operand - convert to low */
|
||||||
insns[0].reloc[0].exp.X_add_number >>= 16;
|
insns[0].reloc[0].exp.X_add_number >>= 16;
|
||||||
@ -1667,7 +1670,10 @@ alpha_ip (str, insns)
|
|||||||
top = val - low;
|
top = val - low;
|
||||||
if (top)
|
if (top)
|
||||||
{
|
{
|
||||||
emit_add64 (ZERO, AT, top);
|
do_add64 = 1;
|
||||||
|
add64_in = ZERO;
|
||||||
|
add64_out = AT;
|
||||||
|
add64_addend = top;
|
||||||
opcode |= AT << SB;
|
opcode |= AT << SB;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1821,7 +1827,7 @@ alpha_ip (str, insns)
|
|||||||
note_gpreg (PV);
|
note_gpreg (PV);
|
||||||
|
|
||||||
jsr = &insns[num_gen++];
|
jsr = &insns[num_gen++];
|
||||||
jsr->opcode = (0x68004000 /* jsr */
|
jsr->opcode = (pattern->match
|
||||||
| (mask << SA)
|
| (mask << SA)
|
||||||
| (PV << SB)
|
| (PV << SB)
|
||||||
| 0);
|
| 0);
|
||||||
@ -2136,6 +2142,11 @@ alpha_ip (str, insns)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_add64)
|
||||||
|
{
|
||||||
|
emit_add64 (add64_in, add64_out, add64_addend);
|
||||||
|
}
|
||||||
|
|
||||||
insns[0].opcode = opcode;
|
insns[0].opcode = opcode;
|
||||||
return num_gen;
|
return num_gen;
|
||||||
}
|
}
|
||||||
@ -2361,7 +2372,7 @@ s_alpha_set (x)
|
|||||||
else if (!strcmp ("volatile", s))
|
else if (!strcmp ("volatile", s))
|
||||||
/* ignore */ ;
|
/* ignore */ ;
|
||||||
else
|
else
|
||||||
as_warn ("Tried to set unrecognized symbol: %s", name);
|
as_warn ("Tried to .set unrecognized mode `%s'", name);
|
||||||
*input_line_pointer = ch;
|
*input_line_pointer = ch;
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
@ -2531,6 +2542,13 @@ md_apply_fix (fixP, valueP)
|
|||||||
*p |= (value & 0x1f);
|
*p |= (value & 0x1f);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
case BFD_RELOC_12_PCREL:
|
||||||
|
*p++ = value & 0xff;
|
||||||
|
value >>= 8;
|
||||||
|
*p &= 0xf0;
|
||||||
|
*p |= (value & 0x0f);
|
||||||
|
goto done;
|
||||||
|
|
||||||
case BFD_RELOC_ALPHA_LITERAL:
|
case BFD_RELOC_ALPHA_LITERAL:
|
||||||
case BFD_RELOC_ALPHA_LITUSE:
|
case BFD_RELOC_ALPHA_LITUSE:
|
||||||
return 2;
|
return 2;
|
||||||
@ -2551,7 +2569,8 @@ md_apply_fix (fixP, valueP)
|
|||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
as_fatal ("unknown relocation type %d?", fixP->fx_r_type);
|
as_fatal ("unhandled relocation type %s",
|
||||||
|
bfd_get_reloc_code_name (fixP->fx_r_type));
|
||||||
return 9;
|
return 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user