Flag error if absolute constant is too large for an immediate field.

This commit is contained in:
Jim Wilson 1992-11-06 01:59:36 +00:00
parent 402dca80e7
commit 0cef0e20f9
2 changed files with 43 additions and 5 deletions

View File

@ -1,3 +1,9 @@
Thu Nov 5 17:55:41 1992 Jim Wilson (wilson@sphagnum.cygnus.com)
* tc-sparc.c (sparc_ip): Add code to flag error if an absolute
constant will not fit in an immediate field.
(md_apply_fix, RELOC_BASE13 case): Check for relocation overflow.
Wed Nov 4 07:50:46 1992 Ken Raeburn (raeburn@cygnus.com) Wed Nov 4 07:50:46 1992 Ken Raeburn (raeburn@cygnus.com)
* obj-coff.c (callj_table): Delete global variable. * obj-coff.c (callj_table): Delete global variable.

View File

@ -525,6 +525,7 @@ char *str;
unsigned int mask = 0; unsigned int mask = 0;
int match = 0; int match = 0;
int comma = 0; int comma = 0;
long immediate_max = 0;
for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s) for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
; ;
@ -707,10 +708,12 @@ char *str;
#ifndef NO_V9 #ifndef NO_V9
case 'I': case 'I':
the_insn.reloc = RELOC_11; the_insn.reloc = RELOC_11;
immediate_max = 0x03FF;
goto immediate; goto immediate;
case 'j': case 'j':
the_insn.reloc = RELOC_10; the_insn.reloc = RELOC_10;
immediate_max = 0x01FF;
goto immediate; goto immediate;
case 'k': case 'k':
@ -1118,6 +1121,7 @@ char *str;
case 'i': /* 13 bit immediate */ case 'i': /* 13 bit immediate */
the_insn.reloc = RELOC_BASE13; the_insn.reloc = RELOC_BASE13;
immediate_max = 0x0FFF;
/*FALLTHROUGH */ /*FALLTHROUGH */
@ -1133,13 +1137,13 @@ char *str;
s+=3; s+=3;
/* start-sanitize-v9 */ /* start-sanitize-v9 */
#ifndef NO_V9 #ifndef NO_V9
} else if (c == 'h' } else if (c == 'u'
&& s[2] == 'h' && s[2] == 'h'
&& s[3] == 'i') { && s[3] == 'i') {
the_insn.reloc = RELOC_HHI22; the_insn.reloc = RELOC_HHI22;
s += 4; s += 4;
} else if (c == 'h' } else if (c == 'u'
&& s[2] == 'l' && s[2] == 'l'
&& s[3] == 'o') { && s[3] == 'o') {
the_insn.reloc = RELOC_HLO10; the_insn.reloc = RELOC_HLO10;
@ -1185,6 +1189,30 @@ char *str;
} }
(void)getExpression(s); (void)getExpression(s);
s = expr_end; s = expr_end;
/* Check for invalid constant values. Don't
warn if constant was inside %hi or %lo,
since these truncate the constant to
fit. */
if (immediate_max != 0
&& the_insn.reloc != RELOC_LO10
&& the_insn.reloc != RELOC_HI22
/* start-sanitize-v9 */
#ifndef NO_V9
&& the_insn.reloc != RELOC_HLO10
&& the_insn.reloc != RELOC_HHI22
#endif
/* end-sanitize-v9 */
&& the_insn.exp.X_add_symbol == 0
&& the_insn.exp.X_subtract_symbol == 0
&& the_insn.exp.X_seg == SEG_ABSOLUTE
&& (the_insn.exp.X_add_number > immediate_max
|| the_insn.exp.X_add_number < ~immediate_max))
as_bad ("constant value must be between %ld and %ld",
~immediate_max, immediate_max);
/* Reset to prevent extraneous range check. */
immediate_max = 0;
continue; continue;
case 'a': case 'a':
@ -1514,7 +1542,7 @@ long val;
as_bad("relocation overflow."); as_bad("relocation overflow.");
} /* on overflow */ } /* on overflow */
buf[2] = (val >> 8) & 0x7; buf[2] |= (val >> 8) & 0x7;
buf[3] = val & 0xff; buf[3] = val & 0xff;
break; break;
@ -1524,7 +1552,7 @@ long val;
as_bad("relocation overflow."); as_bad("relocation overflow.");
} /* on overflow */ } /* on overflow */
buf[2] = (val >> 8) & 0x3; buf[2] |= (val >> 8) & 0x3;
buf[3] = val & 0xff; buf[3] = val & 0xff;
break; break;
@ -1582,7 +1610,7 @@ long val;
if (val & ~0x00001fff) { if (val & ~0x00001fff) {
as_bad("relocation overflow"); as_bad("relocation overflow");
} /* on overflow */ } /* on overflow */
buf[2] = (val >> 8) & 0x1f; buf[2] |= (val >> 8) & 0x1f;
buf[3] = val & 0xff; buf[3] = val & 0xff;
break; break;
@ -1607,6 +1635,10 @@ long val;
case RELOC_BASE10: case RELOC_BASE10:
#endif #endif
case RELOC_BASE13: case RELOC_BASE13:
if (((val > 0) && (val & ~0x00001fff))
|| ((val < 0) && (~(val - 1) & ~0x00001fff))) {
as_bad("relocation overflow");
} /* on overflow */
buf[2] |= (val >> 8) & 0x1f; buf[2] |= (val >> 8) & 0x1f;
buf[3] = val; buf[3] = val;
break; break;