* config/tc-z8k.c (parse_reg): Invalid registers generate an error

now, not only a warning.  Add some more checks to detect invalid
	registers.
	(get_operand): For CLASS_IR remember register size in mode struct.
	(get_specific): Handle new CLASS_IRO type.  Add register size
	checks for CLASS_IR and CLASS_IRO.
        (md_apply_fix3): Fix undefined usage of buf.
This commit is contained in:
Christian Groessler 2003-06-19 13:44:42 +00:00
parent 83615de03f
commit f590b86e1e
2 changed files with 42 additions and 14 deletions

View File

@ -1,3 +1,13 @@
2003-06-19 Christian Groessler <chris@groessler.org>
* config/tc-z8k.c (parse_reg): Invalid registers generate an error
now, not only a warning. Add some more checks to detect invalid
registers.
(get_operand): For CLASS_IR remember register size in mode struct.
(get_specific): Handle new CLASS_IRO type. Add register size
checks for CLASS_IR and CLASS_IRO.
(md_apply_fix3): Fix undefined usage of buf.
2003-06-19 Alan Modra <amodra@bigpond.net.au> 2003-06-19 Alan Modra <amodra@bigpond.net.au>
* config/tc-ppc.c (ppc_csect): Pass alignment to ppc_change_csect. * config/tc-ppc.c (ppc_csect): Pass alignment to ppc_change_csect.

View File

@ -193,8 +193,8 @@ struct z8k_exp {
}; };
typedef struct z8k_op { typedef struct z8k_op {
/* 'b','w','r','q'. */ /* CLASS_REG_xxx. */
char regsize; int regsize;
/* 0 .. 15. */ /* 0 .. 15. */
unsigned int reg; unsigned int reg;
@ -311,7 +311,9 @@ parse_reg (src, mode, reg)
res = whatreg (reg, src + 2); res = whatreg (reg, src + 2);
regno = *reg; regno = *reg;
if (regno > 14) if (regno > 14)
as_warn (_("register rr%d, out of range."), regno); as_bad (_("register rr%d out of range"), regno);
if (regno & 1)
as_bad (_("register rr%d does not exist"), regno);
} }
else if (src[1] == 'h') else if (src[1] == 'h')
{ {
@ -321,7 +323,7 @@ parse_reg (src, mode, reg)
res = whatreg (reg, src + 2); res = whatreg (reg, src + 2);
regno = *reg; regno = *reg;
if (regno > 7) if (regno > 7)
as_warn (_("register rh%d, out of range."), regno); as_bad (_("register rh%d out of range"), regno);
} }
else if (src[1] == 'l') else if (src[1] == 'l')
{ {
@ -331,7 +333,7 @@ parse_reg (src, mode, reg)
res = whatreg (reg, src + 2); res = whatreg (reg, src + 2);
regno = *reg; regno = *reg;
if (regno > 7) if (regno > 7)
as_warn (_("register rl%d, out of range."), regno); as_bad (_("register rl%d out of range"), regno);
*reg += 8; *reg += 8;
} }
else if (src[1] == 'q') else if (src[1] == 'q')
@ -342,7 +344,9 @@ parse_reg (src, mode, reg)
res = whatreg (reg, src + 2); res = whatreg (reg, src + 2);
regno = *reg; regno = *reg;
if (regno > 12) if (regno > 12)
as_warn (_("register rq%d, out of range."), regno); as_bad (_("register rq%d out of range"), regno);
if (regno & 3)
as_bad (_("register rq%d does not exist"), regno);
} }
else else
{ {
@ -352,7 +356,7 @@ parse_reg (src, mode, reg)
res = whatreg (reg, src + 1); res = whatreg (reg, src + 1);
regno = *reg; regno = *reg;
if (regno > 15) if (regno > 15)
as_warn (_("register r%d, out of range."), regno); as_bad (_("register r%d out of range"), regno);
} }
} }
return res; return res;
@ -578,7 +582,7 @@ get_interrupt_operand (ptr, mode, dst)
; ;
} }
/* No interrupt type specified, opcode won't do anything. */ /* No interrupt type specified, opcode won't do anything. */
as_warn (_("opcode has no effect.")); as_warn (_("opcode has no effect"));
the_interrupt = 0x0; the_interrupt = 0x0;
return; return;
} }
@ -666,10 +670,8 @@ get_operand (ptr, mode, dst)
} }
else if (*src == '@') else if (*src == '@')
{ {
int d;
mode->mode = CLASS_IR; mode->mode = CLASS_IR;
src = parse_reg (src + 1, &d, &mode->reg); src = parse_reg (src + 1, &mode->regsize, &mode->reg);
} }
else else
{ {
@ -871,6 +873,11 @@ get_specific (opcode, operands)
{ {
unsigned int mode = operands[i].mode; unsigned int mode = operands[i].mode;
if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO))
{
mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO;
}
if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK)) if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
{ {
/* It could be a pc rel operand, if this is a da mode /* It could be a pc rel operand, if this is a da mode
@ -907,8 +914,18 @@ get_specific (opcode, operands)
{ {
default: default:
break; break;
case CLASS_X: case CLASS_IRO:
if (operands[i].regsize != CLASS_REG_WORD)
as_bad (_("invalid indirect register size"));
reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
break;
case CLASS_IR: case CLASS_IR:
if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG)
|| (!segmented_mode && operands[i].regsize != CLASS_REG_WORD))
as_bad (_("invalid indirect register size"));
reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
break;
case CLASS_X:
case CLASS_BA: case CLASS_BA:
case CLASS_BX: case CLASS_BX:
case CLASS_DISP: case CLASS_DISP:
@ -951,7 +968,7 @@ check_operand (operand, width, string)
if ((operand->exp.X_add_number & ~width) != 0 && if ((operand->exp.X_add_number & ~width) != 0 &&
(operand->exp.X_add_number | width) != (~0)) (operand->exp.X_add_number | width) != (~0))
{ {
as_warn (_("operand %s0x%x out of range."), as_warn (_("operand %s0x%x out of range"),
string, operand->exp.X_add_number); string, operand->exp.X_add_number);
} }
} }
@ -1479,7 +1496,8 @@ md_apply_fix3 (fixP, valP, segment)
if (val > 8191 || val < -8192) if (val > 8191 || val < -8192)
as_bad (_("relative call out of range")); as_bad (_("relative call out of range"));
val = -val; val = -val;
*buf++ = (buf[0] & 0xf0) | ((val >> 8) & 0xf); *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
buf++;
*buf++ = val & 0xff; *buf++ = val & 0xff;
break; break;