aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Hunt <hunt@redhat.com>1996-08-27 01:28:29 +0000
committerMartin Hunt <hunt@redhat.com>1996-08-27 01:28:29 +0000
commit67f0d0ea4ce159e13786d6cdd4990754e702eb82 (patch)
treef9c9bd8a75d3502067446456b3a9867594ee88ea
parent3017263b6894d2b28b6822513b20616fdf6865b1 (diff)
downloadgdb-67f0d0ea4ce159e13786d6cdd4990754e702eb82.zip
gdb-67f0d0ea4ce159e13786d6cdd4990754e702eb82.tar.gz
gdb-67f0d0ea4ce159e13786d6cdd4990754e702eb82.tar.bz2
Mon Aug 26 18:24:51 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* tc-d10v.c: Fixed ".word". Fixed problem with range checking on addresses. Improved error messages.
-rw-r--r--gas/config/tc-d10v.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/gas/config/tc-d10v.c b/gas/config/tc-d10v.c
index 5729e56..e95b3c8 100644
--- a/gas/config/tc-d10v.c
+++ b/gas/config/tc-d10v.c
@@ -69,7 +69,7 @@ static int write_2_short PARAMS ((struct d10v_opcode *opcode1, unsigned long ins
struct d10v_opcode *opcode2, unsigned long insn2, int exec_type, Fixups *fx));
static unsigned long do_assemble PARAMS ((char *str, struct d10v_opcode **opcode));
static unsigned long d10v_insert_operand PARAMS (( unsigned long insn, int op_type,
- offsetT value, int left));
+ offsetT value, int left, fixS *fix));
static int parallel_ok PARAMS ((struct d10v_opcode *opcode1, unsigned long insn1,
struct d10v_opcode *opcode2, unsigned long insn2));
@@ -446,11 +446,12 @@ get_operands (exp)
}
static unsigned long
-d10v_insert_operand (insn, op_type, value, left)
+d10v_insert_operand (insn, op_type, value, left, fix)
unsigned long insn;
int op_type;
offsetT value;
int left;
+ fixS *fix;
{
int shift, bits;
@@ -462,7 +463,7 @@ d10v_insert_operand (insn, op_type, value, left)
/* truncate to the proper number of bits */
if (check_range (value, bits, d10v_operands[op_type].flags))
- as_bad("operand out of range: %d",value);
+ as_bad_where (fix->fx_file, fix->fx_line, "operand out of range: %d", value);
value &= 0x7FFFFFFF >> (31 - bits);
insn |= (value << shift);
@@ -1054,8 +1055,20 @@ find_opcode (opcode, myops)
{
int bits = d10v_operands[next_opcode->operands[opnum]].bits;
int flags = d10v_operands[next_opcode->operands[opnum]].flags;
- if (!check_range (myops[opnum].X_add_number, bits, flags))
- return next_opcode;
+ if (flags & OPERAND_ADDR)
+ bits += 2;
+ if (myops[opnum].X_op == O_constant)
+ {
+ if (!check_range (myops[opnum].X_add_number, bits, flags))
+ return next_opcode;
+ }
+ else
+ {
+ int value = obstack_next_free(&frchain_now->frch_obstack) - frag_now->fr_literal -
+ S_GET_VALUE(myops[opnum].X_add_symbol);
+ if (!check_range (value, bits, flags))
+ return next_opcode;
+ }
next_opcode++;
}
as_fatal ("value out of range");
@@ -1230,7 +1243,7 @@ md_apply_fix3 (fixp, valuep, seg)
}
}
- /* printf("md_apply_fix: value=0x%x type=0x%x where=0x%x\n", value, fixp->fx_r_type,fixp->fx_where); */
+ /* printf("md_apply_fix: value=0x%x type=0x%x where=0x%x size=%d line=%d\n", value, fixp->fx_r_type,fixp->fx_where,fixp->fx_size, fixp->fx_line); */
op_type = fixp->fx_r_type;
if (op_type & 2048)
@@ -1262,12 +1275,18 @@ md_apply_fix3 (fixp, valuep, seg)
case BFD_RELOC_32:
bfd_putb32 ((bfd_vma) value, (unsigned char *) where);
return 1;
+ case BFD_RELOC_16:
+ if (fixp->fx_size == 2)
+ {
+ bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
+ return 1;
+ }
default:
break;
}
/* printf(" insn=%x value=%x where=%x pcrel=%x\n",insn,value,fixp->fx_where,fixp->fx_pcrel); */
- insn = d10v_insert_operand (insn, op_type, (offsetT)value, left);
+ insn = d10v_insert_operand (insn, op_type, (offsetT)value, left, fixp);
/* printf(" new insn=%x\n",insn); */
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);