aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@cygnus>1995-01-06 22:02:27 +0000
committerKen Raeburn <raeburn@cygnus>1995-01-06 22:02:27 +0000
commit71f9b3c097ca1014ba4897a80bebc23027e3ec51 (patch)
tree15792e2c219c31dfb6927766f4c429c802d8d045 /gas
parent2a6978af8d044b6fc99a658515696500514abf49 (diff)
downloadgdb-71f9b3c097ca1014ba4897a80bebc23027e3ec51.zip
gdb-71f9b3c097ca1014ba4897a80bebc23027e3ec51.tar.gz
gdb-71f9b3c097ca1014ba4897a80bebc23027e3ec51.tar.bz2
* config/tc-alpha.c (alpha_ip): Delay calls to emit_add64 until after any
remaining operands are also known to match.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog3
-rw-r--r--gas/config/tc-alpha.c129
2 files changed, 77 insertions, 55 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1586440..29cd584 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
+ * 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>
* listing.c (list_symbol_table): Build a format string based on
diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c
index 3453e65..81453c9 100644
--- a/gas/config/tc-alpha.c
+++ b/gas/config/tc-alpha.c
@@ -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_lda_n PARAMS ((int, bfd_vma, int));
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[] =
{
@@ -430,9 +430,9 @@ s_base ()
demand_empty_rest_of_line ();
}
-static int in_range (val, nbits, unsignedness)
+static int in_range_signed (val, nbits)
bfd_vma val;
- int nbits, unsignedness;
+ 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
@@ -445,27 +445,40 @@ static int in_range (val, nbits, unsignedness)
stored_value = val & mask;
top_bit = stored_value & (one << nbits - 1);
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
{
- /* will sign-extend */
- if (top_bit)
- {
- /* 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;
- }
+ /* 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
s_gprel32 ()
{
@@ -509,8 +522,6 @@ create_literal_section (secp, name)
| SEC_DATA);
}
-#define create_lita_section() create_literal_section (&lita_sec, ".lita")
-
static valueT
get_lit8_offset (val)
bfd_vma val;
@@ -648,7 +659,7 @@ md_begin ()
/* So .sbss will get used for tiny objects. */
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
symbol table. We'll edit it out of relocs later. */
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;
- if (in_range (num, 16, 0))
+ if (in_range_signed (num, 16))
{
emit_lda_n (out, num, in);
return;
}
if ((num & 0xffff) == 0
&& in == ZERO
- && in_range (snum >> 16, 16, 0))
+ && in_range_signed (snum >> 16, 16))
{
emit_ldah_num (out, snum >> 16, in);
return;
@@ -1151,21 +1162,21 @@ emit_add64 (in, out, num)
/* I'm not sure this one is getting invoked when it could. */
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_addq_r (out, out, out);
return;
}
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_addq_r (out, out, out);
return;
}
}
- if (in_range (num, 32, 0))
+ if (in_range_signed (num, 32))
{
bfd_vma lo = num & 0xffff;
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
alpha_ip (str, insns)
char *str;
@@ -1223,6 +1228,8 @@ alpha_ip (str, insns)
unsigned int mask;
int match = 0, num_gen = 1;
int comma = 0;
+ int do_add64, add64_in, add64_out;
+ bfd_vma add64_addend;
for (s = str;
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)
{
- as_warn ("Unknown opcode: `%s'", str);
+ as_bad ("Unknown opcode: `%s'", str);
return -1;
}
if (comma)
@@ -1257,6 +1264,7 @@ alpha_ip (str, insns)
argsStart = s;
for (;;)
{
+ do_add64 = 0;
opcode = pattern->match;
num_gen = 1;
for (i = 0; i < MAX_INSNS; i++)
@@ -1465,24 +1473,14 @@ alpha_ip (str, insns)
insns[0].reloc[0].code = BFD_RELOC_26;
goto immediate;
-#if 0
- case 't': /* 12 bit 0...11 */
- insns[0].reloc = RELOC_0_12;
+ case 't': /* 12 bit displacement, for PALcode */
+ insns[0].reloc[0].code = BFD_RELOC_12_PCREL;
goto immediate;
case '8': /* 8 bit 0...7 */
- insns[0].reloc = RELOC_0_8;
+ insns[0].reloc[0].code = BFD_RELOC_8;
goto immediate;
- case 'I': /* 26 bit immediate */
- insns[0].reloc = RELOC_0_25;
-#else
- case 't':
- case '8':
- abort ();
-#endif
- /*FALLTHROUGH*/
-
immediate:
if (*s == ' ')
s++;
@@ -1523,8 +1521,10 @@ alpha_ip (str, insns)
else if (at_ok && macro_ok)
{
/* Constant value supplied, but it's too large. */
- emit_add64 (ZERO, AT,
- insns[0].reloc[0].exp.X_add_number);
+ do_add64 = 1;
+ add64_in = ZERO;
+ add64_out = AT;
+ add64_addend = insns[0].reloc[0].exp.X_add_number;
opcode &= ~ 0x1000;
opcode |= (AT << SB);
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
&& insns[0].reloc[0].exp.X_op == O_constant
- && !in_range (insns[0].reloc[0].exp.X_add_number,
- 16, 0))
+ && !in_range_signed (insns[0].reloc[0].exp.X_add_number,
+ 16))
{
bfd_vma val = insns[0].reloc[0].exp.X_add_number;
if (OPCODE (opcode) == 0x08)
{
- emit_add64 (ZERO, AT, val);
+ do_add64 = 1;
+ add64_in = ZERO;
+ add64_out = AT;
+ add64_addend = val;
opcode &= ~0x1000;
opcode |= (AT << SB);
insns[0].reloc[0].code = BFD_RELOC_NONE;
}
else if (OPCODE (opcode) == 0x09
- && in_range (val >> 16, 16, 0))
+ && in_range_signed (val >> 16, 16))
{
/* ldah with high operand - convert to low */
insns[0].reloc[0].exp.X_add_number >>= 16;
@@ -1667,7 +1670,10 @@ alpha_ip (str, insns)
top = val - low;
if (top)
{
- emit_add64 (ZERO, AT, top);
+ do_add64 = 1;
+ add64_in = ZERO;
+ add64_out = AT;
+ add64_addend = top;
opcode |= AT << SB;
}
else
@@ -1821,7 +1827,7 @@ alpha_ip (str, insns)
note_gpreg (PV);
jsr = &insns[num_gen++];
- jsr->opcode = (0x68004000 /* jsr */
+ jsr->opcode = (pattern->match
| (mask << SA)
| (PV << SB)
| 0);
@@ -2136,6 +2142,11 @@ alpha_ip (str, insns)
break;
}
+ if (do_add64)
+ {
+ emit_add64 (add64_in, add64_out, add64_addend);
+ }
+
insns[0].opcode = opcode;
return num_gen;
}
@@ -2361,7 +2372,7 @@ s_alpha_set (x)
else if (!strcmp ("volatile", s))
/* ignore */ ;
else
- as_warn ("Tried to set unrecognized symbol: %s", name);
+ as_warn ("Tried to .set unrecognized mode `%s'", name);
*input_line_pointer = ch;
demand_empty_rest_of_line ();
}
@@ -2531,6 +2542,13 @@ md_apply_fix (fixP, valueP)
*p |= (value & 0x1f);
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_LITUSE:
return 2;
@@ -2551,7 +2569,8 @@ md_apply_fix (fixP, valueP)
return 2;
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;
}