From a78bc551965be8b006fcee34670ce0345ff1a374 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 3 Jan 1997 17:14:02 +0000 Subject: [PATCH] * config/tc-m68k.c (m68k_ip): Accept 'B' as a size for an immediate value. (md_assemble): If the size is 'B', set fx_signed. (md_apply_fix_2): Use fx_signed when checking for overflow. * write.h (struct fix): Add fx_signed field. * write.c (fix_new_internal): Initialize fx_no_overflow and fx_signed fields. (fixup_segment): Use fx_signed when checking for overflow. * config/obj-coff.c (fixup_segment): Check fx_no_overflow and fx_signed when checking for overflow. --- gas/ChangeLog | 14 ++++++++++++++ gas/config/obj-coff.c | 16 ++++++++++------ gas/config/tc-m68k.c | 16 +++++++++++++++- gas/write.c | 12 +++++++++--- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 90b0c583b6..fae59eec4e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +Fri Jan 3 12:09:24 1997 Ian Lance Taylor + + * config/tc-m68k.c (m68k_ip): Accept 'B' as a size for an + immediate value. + (md_assemble): If the size is 'B', set fx_signed. + (md_apply_fix_2): Use fx_signed when checking for overflow. + + * write.h (struct fix): Add fx_signed field. + * write.c (fix_new_internal): Initialize fx_no_overflow and + fx_signed fields. + (fixup_segment): Use fx_signed when checking for overflow. + * config/obj-coff.c (fixup_segment): Check fx_no_overflow and + fx_signed when checking for overflow. + Thu Jan 2 13:37:29 1997 Ian Lance Taylor * NOTES, NOTES.config: Removed. These are rarely, if ever, diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index d06212e510..695647a7e3 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -1,5 +1,5 @@ /* coff object file format - Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 1996 + Copyright (C) 1989, 90, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. This file is part of GAS. @@ -4083,17 +4083,21 @@ fixup_segment (segP, this_segment_type) #endif } /* if pcrel */ - if (!fixP->fx_bit_fixP) + if (!fixP->fx_bit_fixP && ! fixP->fx_no_overflow) { #ifndef TC_M88K /* The m88k uses the offset field of the reloc to get around this problem. */ if ((size == 1 - && (add_number & ~0xFF) - && ((add_number & ~0xFF) != (-1 & ~0xFF))) + && ((add_number & ~0xFF) + || (fixP->fx_signed && (add_number & 0x80))) + && ((add_number & ~0xFF) != (-1 & ~0xFF) + || (fixP->fx_signed && (add_number & 0x80) == 0))) || (size == 2 - && (add_number & ~0xFFFF) - && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF)))) + && ((add_number & ~0xFFFF) + || (fixP->fx_signed && (add_number & 0x8000))) + && ((add_number & ~0xFFFF) != (-1 & ~0xFFFF) + || (fixP->fx_signed && (add_number & 0x8000) == 0)))) { as_bad_where (fixP->fx_file, fixP->fx_line, "Value of %ld too large for field of %d bytes at 0x%lx", diff --git a/gas/config/tc-m68k.c b/gas/config/tc-m68k.c index 0e40fa31c0..7204ec31a6 100644 --- a/gas/config/tc-m68k.c +++ b/gas/config/tc-m68k.c @@ -1152,6 +1152,11 @@ m68k_ip (instring) && (opP->disp.exp.X_op != O_constant || ! isbyte (opP->disp.exp.X_add_number))) losing++; + else if (s[1] == 'B' + && ! isvar (&opP->disp) + && (opP->disp.exp.X_op != O_constant + || ! issbyte (opP->disp.exp.X_add_number))) + losing++; else if (s[1] == 'w' && ! isvar (&opP->disp) && (opP->disp.exp.X_op != O_constant @@ -2289,6 +2294,13 @@ m68k_ip (instring) the_ins.reloc[the_ins.nrel - 1].n = (opcode->m_codenum) * 2 + 1; break; + case 'B': + if (!issbyte (tmpreg)) + opP->error = "out of range"; + opcode->m_opcode |= tmpreg; + if (isvar (&opP->disp)) + the_ins.reloc[the_ins.nrel - 1].n = opcode->m_codenum * 2 - 1; + break; case 'w': if (!isword (tmpreg)) opP->error = "out of range"; @@ -3337,6 +3349,8 @@ md_assemble (str) get_reloc_code (n, the_ins.reloc[m].pcrel, the_ins.reloc[m].pic_reloc)); fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix; + if (the_ins.reloc[m].wid == 'B') + fixP->fx_signed = 1; } return; } @@ -3888,7 +3902,7 @@ md_apply_fix_2 (fixP, val) like "0xff" for a byte field. So extend the upper part of the range to accept such numbers. We arbitrarily disallow "-0xff" or "0xff+0xff", so that we can do any range checking at all. */ - if (!fixP->fx_pcrel) + if (! fixP->fx_pcrel && ! fixP->fx_signed) upper_limit = upper_limit * 2 + 1; if ((addressT) val > upper_limit diff --git a/gas/write.c b/gas/write.c index 18ebc49086..1ec9130cf8 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1,5 +1,5 @@ /* write.c - emit .o file - Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 1996 + Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -162,6 +162,8 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel, fixP->fx_addnumber = 0; fixP->fx_tcbit = 0; fixP->fx_done = 0; + fixP->fx_no_overflow = 0; + fixP->fx_signed = 0; #ifdef TC_FIX_TYPE TC_INIT_FIX_DATA(fixP); @@ -2560,8 +2562,12 @@ fixup_segment (fixP, this_segment_type) the host architecture. */ mask <<= size * 4; mask <<= size * 4; - if ((add_number & mask) != 0 - && (add_number & mask) != mask) + if (((add_number & mask) != 0 + || (fixP->fx_signed + && (add_number & (mask >> 1)) != 0)) + && ((add_number & mask) != mask + || (fixP->fx_signed + && (add_number & (mask >> 1)) == 0))) { char buf[50], buf2[50]; sprint_value (buf, fragP->fr_address + where);