aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorMartin Hunt <hunt@redhat.com>1996-07-31 18:50:12 +0000
committerMartin Hunt <hunt@redhat.com>1996-07-31 18:50:12 +0000
commitf8508db7d62279f5a727997780eb009caf7d91ad (patch)
treeddf4f9cbd3f26a77ccbe16a65c632984ee412ab5 /gas
parent37e05f6443e0fe873f49c437f64b86e7d6d3caf5 (diff)
downloadgdb-f8508db7d62279f5a727997780eb009caf7d91ad.zip
gdb-f8508db7d62279f5a727997780eb009caf7d91ad.tar.gz
gdb-f8508db7d62279f5a727997780eb009caf7d91ad.tar.bz2
Wed Jul 31 11:45:15 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* tc-d10v.c: Fixed bugs in short relocs and range checking.
Diffstat (limited to 'gas')
-rw-r--r--gas/config/tc-d10v.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c
index 674bbd4..c8ee06c 100644
--- a/gas/config/tc-d10v.c
+++ b/gas/config/tc-d10v.c
@@ -152,7 +152,7 @@ check_range (num, bits, flags)
int bits;
int flags;
{
- long min, max;
+ long min, max, bit1;
int retval=0;
if (flags & OPERAND_SHIFT)
@@ -167,7 +167,14 @@ check_range (num, bits, flags)
if (flags & OPERAND_SIGNED)
{
- max = (1 << (bits - 1)) - 1;
+ bit1 = (1 << (bits - 1));
+ max = bit1 -1;
+ if (num & max)
+ {
+ /* sign-extend */
+ num = ((num & (bit1 | max))^(~max))+bit1;
+ }
+
min = - (1 << (bits - 1));
if (((long)num > max) || ((long)num < min))
retval = 1;
@@ -553,7 +560,9 @@ write_1_short (opcode, insn, fx)
number_to_chars_bigendian (f, insn, 4);
for (i=0; i < fx->fc; i++)
{
- if (get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]))
+ bfd_reloc_code_real_type reloc;
+ reloc = get_reloc((struct d10v_operand *)&d10v_operands[fx->fix[i].reloc]);
+ if (reloc)
{
/*
printf("fix_new_exp: where:%x size:4\n ",f - frag_now->fr_literal);
@@ -561,6 +570,10 @@ write_1_short (opcode, insn, fx)
printf("\n");
*/
+ /* if it's an R reloc, we may have to switch it to L */
+ if ( (reloc == BFD_RELOC_D10V_10_PCREL_R) && (opcode->unit != IU) )
+ fx->fix[i].reloc |= 1024;
+
fix_new_exp (frag_now,
f - frag_now->fr_literal,
4,
@@ -624,6 +637,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
as_fatal ("Two IU instructions may not be executed in parallel");
as_warn ("Swapping instruction order");
insn = FM00 | (insn2 << 15) | insn1;
+ fx = fx->next;
}
else if (opcode2->unit == MU)
{
@@ -631,6 +645,7 @@ write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
as_fatal ("Two MU instructions may not be executed in parallel");
as_warn ("Swapping instruction order");
insn = FM00 | (insn2 << 15) | insn1;
+ fx = fx->next;
}
else
insn = FM00 | (insn1 << 15) | insn2;