diff options
author | Martin Hunt <hunt@redhat.com> | 1996-08-27 01:28:29 +0000 |
---|---|---|
committer | Martin Hunt <hunt@redhat.com> | 1996-08-27 01:28:29 +0000 |
commit | 67f0d0ea4ce159e13786d6cdd4990754e702eb82 (patch) | |
tree | f9c9bd8a75d3502067446456b3a9867594ee88ea | |
parent | 3017263b6894d2b28b6822513b20616fdf6865b1 (diff) | |
download | gdb-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.c | 33 |
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); |