sanitize out reference to MACREG

This commit is contained in:
Ian Lance Taylor
1996-06-29 16:48:44 +00:00
parent b615d67824
commit be4931bae0

View File

@ -47,6 +47,9 @@ const char line_comment_chars[] = "#";
void cons (); void cons ();
int Hmode; int Hmode;
/* start-sanitize-h8s */
int Smode;
/* end-sanitize-h8s */
#define PSIZE (Hmode ? L_32 : L_16) #define PSIZE (Hmode ? L_32 : L_16)
#define DMODE (L_16) #define DMODE (L_16)
#define DSYMMODE (Hmode ? L_24 : L_16) #define DSYMMODE (Hmode ? L_24 : L_16)
@ -57,9 +60,19 @@ void
h8300hmode () h8300hmode ()
{ {
Hmode = 1; Hmode = 1;
/* start-sanitize-h8s */
Smode = 0;
/* end-sanitize-h8s */
} }
/* start-sanitize-h8s */
void
h8300smode ()
{
Smode = 1;
Hmode = 1;
}
/* end-sanitize-h8s */
void void
sbranch (size) sbranch (size)
int size; int size;
@ -76,6 +89,9 @@ const pseudo_typeS md_pseudo_table[] =
{ {
{"h8300h", h8300hmode, 0}, {"h8300h", h8300hmode, 0},
/* start-sanitize-h8s */
{"h8300s", h8300smode, 0},
/* end-sanitize-h8s */
{"sbranch", sbranch, L_8}, {"sbranch", sbranch, L_8},
{"lbranch", sbranch, L_16}, {"lbranch", sbranch, L_16},
@ -212,6 +228,14 @@ parse_reg (src, mode, reg, direction)
*reg = 0; *reg = 0;
return 3; return 3;
} }
/* start-sanitize-h8s */
if (src[0] == 'e' && src[1] == 'x' && src[2] == 'r')
{
*mode = EXR;
*reg = 0;
return 3;
}
/* end-sanitize-h8s */
if (src[0] == 'f' && src[1] == 'p') if (src[0] == 'f' && src[1] == 'p')
{ {
*mode = PSIZE | REG | direction; *mode = PSIZE | REG | direction;
@ -225,7 +249,7 @@ parse_reg (src, mode, reg, direction)
*mode = L_32 | REG | direction; *mode = L_32 | REG | direction;
*reg = src[2] - '0'; *reg = src[2] - '0';
if (!Hmode) if (!Hmode)
as_warn ("Reg only legal for H8/300-H"); as_warn ("Reg not valid for H8/300");
return 3; return 3;
} }
@ -235,7 +259,7 @@ parse_reg (src, mode, reg, direction)
*mode = L_16 | REG | direction; *mode = L_16 | REG | direction;
*reg = src[1] - '0' + 8; *reg = src[1] - '0' + 8;
if (!Hmode) if (!Hmode)
as_warn ("Reg only legal for H8/300-H"); as_warn ("Reg not valid for H8/300");
return 2; return 2;
} }
@ -303,6 +327,10 @@ skip_colonthing (ptr, exp, mode)
{ {
*mode |= L_24; *mode |= L_24;
} }
else if (*ptr == '3')
{
*mode |= L_32;
}
else if (*ptr == '1') else if (*ptr == '1')
{ {
*mode |= L_16; *mode |= L_16;
@ -377,6 +405,41 @@ get_operand (ptr, op, dst, direction)
op->mode = E; op->mode = E;
/* start-sanitize-h8s */
/* Gross. Gross. ldm and stm have a format not easily handled
by get_operand. We deal with it explicitly here. */
if (src[0] == 'e' && src[1] == 'r' && isdigit(src[2])
&& src[3] == '-' && src[4] == 'e' && src[5] == 'r' && isdigit(src[6]))
{
int low, high;
low = src[2] - '0';
high = src[6] - '0';
if (high < low)
as_bad ("Invalid register list for ldm/stm\n");
if (low % 2)
as_bad ("Invalid register list for ldm/stm\n");
if (high - low > 4)
as_bad ("Invalid register list for ldm/stm\n");
if (high - low != 2
&& low % 4)
as_bad ("Invalid register list for ldm/stm\n");
/* Even sicker. We encode two registers into op->reg. One
for the low register to save, the other for the high
register to save; we also set the high bit in op->reg
so we know this is "very special". */
op->reg = 0x80000000 | (high << 8) | low;
op->mode = REG;
*ptr = src + 7;
return;
}
/* end-sanitize-h8s */
len = parse_reg (src, &op->mode, &op->reg, direction); len = parse_reg (src, &op->mode, &op->reg, direction);
if (len) if (len)
{ {
@ -523,6 +586,16 @@ get_operand (ptr, op, dst, direction)
return; return;
} }
/* start-sanitize-h8s */
else if (strncmp (src, "mach", 4) == 0
|| strncmp (src, "macl", 4) == 0)
{
op->reg = src[3] == 'l';
op->mode = MACREG;
*ptr = src + 4;
return;
}
/* end-sanitize-h8s */
else else
{ {
src = parse_exp (src, &op->exp); src = parse_exp (src, &op->exp);
@ -614,6 +687,12 @@ get_specific (opcode, operands)
unsigned int this_index = opcode->idx; unsigned int this_index = opcode->idx;
/* There's only one ldm/stm and it's easier to just
get out quick for them. */
if (strcmp (opcode->name, "stm.l") == 0
|| strcmp (opcode->name, "ldm.l") == 0)
return this_try;
while (this_index == opcode->idx && !found) while (this_index == opcode->idx && !found)
{ {
unsigned int i; unsigned int i;
@ -679,18 +758,28 @@ get_specific (opcode, operands)
else if ((op & (DISP | IMM | ABS)) else if ((op & (DISP | IMM | ABS))
&& (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS))) && (op & (DISP | IMM | ABS)) == (x & (DISP | IMM | ABS)))
{ {
/* Got a diplacement,will fit if no size or same size as try */ /* Promote a L_24 to L_32 if it makes us match. */
if (op & ABS && op & L_8) if ((x & L_24) && (op & L_32))
{
x &= ~L_24;
x |= L_32;
}
/* Promote an L8 to L_16 if it makes us match. */
if (op & ABS && op & L_8 && op & DISP)
{ {
/* We want an 8 bit abs here, but one which looks like 16 bits will do fine */
if (x & L_16) if (x & L_16)
found= 1; found= 1;
} }
else else if ((x & SIZE) != 0
if ((x & SIZE) != 0 && ((op & SIZE) != (x & SIZE)))
&& ((op & SIZE) != (x & SIZE)))
found = 0; found = 0;
} }
/* start-sanitize-h8s */
else if ((op & MACREG) != (x & MACREG))
{
found = 0;
}
/* end-sanitize-h8s */
else if ((op & MODE) != (x & MODE)) else if ((op & MODE) != (x & MODE))
{ {
found = 0; found = 0;
@ -738,11 +827,21 @@ check_operand (operand, width, string)
} }
/* RELAXMODE has one of 3 values:
0 Output a "normal" reloc, no relaxing possible for this insn/reloc
1 Output a relaxable 24bit absolute mov.w address relocation
(may relax into a 16bit absolute address).
2 Output a relaxable 16/24 absolute mov.b address relocation
(may relax into an 8bit absolute address). */
static void static void
do_a_fix_imm (offset, operand, relaxing) do_a_fix_imm (offset, operand, relaxmode)
int offset; int offset;
struct h8_op *operand; struct h8_op *operand;
int relaxing; int relaxmode;
{ {
int idx; int idx;
int size; int size;
@ -796,30 +895,34 @@ do_a_fix_imm (offset, operand, relaxing)
{ {
case L_24: case L_24:
case L_32:
size = 4; size = 4;
where = -1; where = (operand->mode & SIZE) == L_24 ? -1 : 0;
idx = relaxing ? R_MOVLB1 : R_RELLONG; if (relaxmode == 2)
idx = R_MOV24B1;
else if (relaxmode == 1)
idx = R_MOVL1;
else
idx = R_RELLONG;
break; break;
default: default:
as_bad("Can't work out size of operand.\n"); as_bad("Can't work out size of operand.\n");
case L_32:
size = 4;
where = 0;
idx = R_RELLONG;
break;
case L_16: case L_16:
size = 2; size = 2;
where = 0; where = 0;
idx = relaxing ? R_MOVB1 : R_RELWORD; if (relaxmode == 2)
idx = R_MOV16B1;
else
idx = R_RELWORD;
operand->exp.X_add_number = (short)operand->exp.X_add_number;
break; break;
case L_8: case L_8:
size = 1; size = 1;
where = 0; where = 0;
idx = R_RELBYTE; idx = R_RELBYTE;
operand->exp.X_add_number = (char)operand->exp.X_add_number;
} }
/* Sign extend any expression */
operand->exp.X_add_number = (short)operand->exp.X_add_number;
fix_new_exp (frag_now, fix_new_exp (frag_now,
offset + where, offset + where,
size, size,
@ -846,14 +949,12 @@ build_bytes (this_try, operand)
int absat; int absat;
int immat; int immat;
int nib; int nib;
int movb = 0;
char asnibbles[30]; char asnibbles[30];
char *p = asnibbles; char *p = asnibbles;
if (!(this_try->inbase || Hmode)) if (!(this_try->inbase || Hmode))
{ as_warn ("Opcode `%s' not available in H8/300 mode", this_try->name);
as_warn ("Opcode `%s' only available in this mode on H8/300-H",
this_try->name);
}
while (*nibble_ptr != E) while (*nibble_ptr != E)
{ {
@ -919,7 +1020,7 @@ build_bytes (this_try, operand)
break; break;
case 4: case 4:
if (!Hmode) if (!Hmode)
as_warn ("#4 only valid in h8/300 mode."); as_warn ("#4 not valid on H8/300.");
nib = 9; nib = 9;
break; break;
@ -931,21 +1032,53 @@ build_bytes (this_try, operand)
operand[0].mode = 0; operand[0].mode = 0;
} }
if (c & MEMRELAX)
{
operand[d].mode |= MEMRELAX;
}
if (c & B31) if (c & B31)
{ {
nib |= 0x8; nib |= 0x8;
} }
/* start-sanitize-h8s */
if (c & MACREG)
{
nib = 2 + operand[d].reg;
}
/* end-sanitize-h8s */
} }
nibble_count++; nibble_count++;
*p++ = nib; *p++ = nib;
} }
/* start-sanitize-h8s */
/* Disgusting. Why, oh why didn't someone ask us for advice
on the assembler format. */
if (strcmp (this_try->name, "stm.l") == 0
|| strcmp (this_try->name, "ldm.l") == 0)
{
int high, low;
high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf;
low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf;
asnibbles[2] = high - low;
asnibbles[7] = (this_try->name[0] == 'l') ? high : low;
}
/* end-sanitize-h8s */
for (i = 0; i < this_try->length; i++) for (i = 0; i < this_try->length; i++)
{ {
output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1]; output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1];
} }
/* Note if this is a movb instruction -- there's a special relaxation
which only applies to them. */
if (strcmp (this_try->name, "mov.b") == 0)
movb = 1;
/* output any fixes */ /* output any fixes */
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
@ -953,11 +1086,13 @@ build_bytes (this_try, operand)
if (x & (IMM | DISP)) if (x & (IMM | DISP))
{ {
do_a_fix_imm (output - frag_now->fr_literal + immat, operand + i, 0); do_a_fix_imm (output - frag_now->fr_literal + immat,
operand + i, x & MEMRELAX != 0);
} }
else if (x & ABS) else if (x & ABS)
{ {
do_a_fix_imm (output - frag_now->fr_literal + absat, operand + i, 0); do_a_fix_imm (output - frag_now->fr_literal + absat,
operand + i, x & MEMRELAX ? movb + 1 : 0);
} }
else if (x & PCREL) else if (x & PCREL)
{ {