unsigned int mask = 0;
int match = 0;
int comma = 0;
+ long immediate_max = 0;
for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
;
#ifndef NO_V9
case 'I':
the_insn.reloc = RELOC_11;
+ immediate_max = 0x03FF;
goto immediate;
case 'j':
the_insn.reloc = RELOC_10;
+ immediate_max = 0x01FF;
goto immediate;
case 'k':
case 'i': /* 13 bit immediate */
the_insn.reloc = RELOC_BASE13;
+ immediate_max = 0x0FFF;
/*FALLTHROUGH */
s+=3;
/* start-sanitize-v9 */
#ifndef NO_V9
- } else if (c == 'h'
+ } else if (c == 'u'
&& s[2] == 'h'
&& s[3] == 'i') {
the_insn.reloc = RELOC_HHI22;
s += 4;
- } else if (c == 'h'
+ } else if (c == 'u'
&& s[2] == 'l'
&& s[3] == 'o') {
the_insn.reloc = RELOC_HLO10;
}
(void)getExpression(s);
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;
case 'a':
as_bad("relocation overflow.");
} /* on overflow */
- buf[2] = (val >> 8) & 0x7;
+ buf[2] |= (val >> 8) & 0x7;
buf[3] = val & 0xff;
break;
as_bad("relocation overflow.");
} /* on overflow */
- buf[2] = (val >> 8) & 0x3;
+ buf[2] |= (val >> 8) & 0x3;
buf[3] = val & 0xff;
break;
if (val & ~0x00001fff) {
as_bad("relocation overflow");
} /* on overflow */
- buf[2] = (val >> 8) & 0x1f;
+ buf[2] |= (val >> 8) & 0x1f;
buf[3] = val & 0xff;
break;
case RELOC_BASE10:
#endif
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[3] = val;
break;