* config/tc-m68k.c (init_table): Now const. Always include 68851

data, so that "bc" is available to 68040 cache instructions.  Added
"tt0", "tt1", and 68ec030 variants.
(md_assemble): Complain if 68000 (only) and 68881 are specified.
(enum _register): Added TT0, TT1.
(m68k_ip, cases '3' and 't'): Handle new operand type codes.  Pass
line number correctly in "internal error" messages.  Don't print
architecture-mismatch message for operand errors.

From Colin Smith (colin@wrs.com):
* config/tc-m68k.c (m68k_ip, case '_'): Use addword twice rather than
install_operand.
This commit is contained in:
Ken Raeburn
1992-08-26 04:08:45 +00:00
parent b2f221a944
commit 4134a793c7

View File

@ -238,7 +238,7 @@ enum _register {
FPS, FPS,
FPC, FPC,
DRP, DRP, /* 68851 or 68030 MMU regs */
CRP, CRP,
CAL, CAL,
VAL, VAL,
@ -262,7 +262,8 @@ enum _register {
BAC5, BAC5,
BAC6, BAC6,
BAC7, BAC7,
PSR, PSR, /* aka MMUSR on 68030 (but not MMUSR on 68040)
and ACUSR on 68ec030 */
PCSR, PCSR,
IC, /* instruction cache token */ IC, /* instruction cache token */
@ -270,6 +271,8 @@ enum _register {
NC, /* no cache token */ NC, /* no cache token */
BC, /* both caches token */ BC, /* both caches token */
TT0, /* 68030 access control unit regs */
TT1,
}; };
/* Internal form of an operand. */ /* Internal form of an operand. */
@ -1176,6 +1179,11 @@ void m68k_ip (instring)
losing++; losing++;
break; break;
case '3':
if (opP->mode != MSCR || (opP->reg != TT0 && opP->reg != TT1))
losing++;
break;
case 'A': case 'A':
if(opP->mode!=AREG) if(opP->mode!=AREG)
losing++; losing++;
@ -1316,6 +1324,17 @@ void m68k_ip (instring)
losing++; losing++;
break; break;
case 't':
if (opP->mode != IMMED)
losing++;
else
{
long t = get_num (opP->con1, 80);
if (t < 0 || t > 7 || isvar (opP->con1))
losing++;
}
break;
case 'U': case 'U':
if(opP->mode!=MSCR || opP->reg!=USP) if(opP->mode!=MSCR || opP->reg!=USP)
losing++; losing++;
@ -1323,7 +1342,10 @@ void m68k_ip (instring)
/* JF these are out of order. We could put them /* JF these are out of order. We could put them
in order if we were willing to put up with in order if we were willing to put up with
bunches of #ifdef m68851s in the code */ bunches of #ifdef m68851s in the code.
Don't forget that you need these operands
to use 68030 MMU instructions. */
#ifndef NO_68851 #ifndef NO_68851
/* Memory addressing mode used by pflushr */ /* Memory addressing mode used by pflushr */
case '|': case '|':
@ -1338,8 +1360,9 @@ void m68k_ip (instring)
break; break;
case 'P': case 'P':
if (opP->mode != MSCR || (opP->reg != TC && opP->reg != CAL && if (opP->mode != MSCR
opP->reg != VAL && opP->reg != SCC && opP->reg != AC)) || (opP->reg != TC && opP->reg != CAL
&& opP->reg != VAL && opP->reg != SCC && opP->reg != AC))
losing++; losing++;
break; break;
@ -1349,8 +1372,9 @@ void m68k_ip (instring)
break; break;
case 'W': case 'W':
if (opP->mode != MSCR || (opP->reg != DRP && opP->reg != SRP && if (opP->mode != MSCR
opP->reg != CRP)) || (opP->reg != DRP && opP->reg != SRP
&& opP->reg != CRP))
losing++; losing++;
break; break;
@ -1387,7 +1411,7 @@ void m68k_ip (instring)
break; break;
default: default:
as_fatal("Internal error: Operand mode %c unknown in line %s of file \"%s\"", as_fatal("Internal error: Operand mode %c unknown in line %d of file \"%s\"",
*s, __LINE__, __FILE__); *s, __LINE__, __FILE__);
} /* switch on type of operand */ } /* switch on type of operand */
@ -1403,7 +1427,8 @@ void m68k_ip (instring)
opcode = opcode->m_next; opcode = opcode->m_next;
if (!opcode) { if (!opcode) {
if (ok_arch) if (ok_arch
&& !(ok_arch & current_architecture))
{ {
char buf[200], *cp; char buf[200], *cp;
int len; int len;
@ -1412,10 +1437,10 @@ void m68k_ip (instring)
switch (ok_arch) switch (ok_arch)
{ {
case mfloat: case mfloat:
strcpy (cp, "fpu"); strcpy (cp, "fpu (68040 or 68881/68882)");
break; break;
case mmmu: case mmmu:
strcpy (cp, "mmu"); strcpy (cp, "mmu (68030 or 68851)");
break; break;
case m68020up: case m68020up:
strcpy (cp, "68020 or higher"); strcpy (cp, "68020 or higher");
@ -2227,12 +2252,32 @@ void m68k_ip (instring)
know(opP->reg == PCSR); know(opP->reg == PCSR);
break; break;
#endif /* m68851 */ #endif /* m68851 */
case '_': case '3':
switch (opP->reg)
{
case TT0:
tmpreg = 2;
break;
case TT1:
tmpreg = 3;
break;
default:
as_fatal ("failed sanity check");
}
install_operand (s[1], tmpreg);
break;
case 't':
tmpreg = get_num (opP->con1, 20);
install_operand (s[1], tmpreg);
break;
case '_': /* used only for move16 absolute 32-bit address */
tmpreg=get_num(opP->con1,80); tmpreg=get_num(opP->con1,80);
install_operand(s[1], tmpreg); addword (tmpreg >> 16);
addword (tmpreg & 0xFFFF);
break; break;
default: default:
as_fatal("Internal error: Operand type %c unknown in line %s of file \"%s\"", s[0], __LINE__, __FILE__); as_fatal("Internal error: Operand type %c unknown in line %d of file \"%s\"",
s[0], __LINE__, __FILE__);
} }
} }
/* By the time whe get here (FINALLY) the_ins contains the complete /* By the time whe get here (FINALLY) the_ins contains the complete
@ -2537,11 +2582,10 @@ int regnum;
symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag)); symbol_table_insert(symbol_new(buf, SEG_REGISTER, regnum, &zero_address_frag));
} }
static struct { static const struct {
char *name; char *name;
int number; int number;
} init_table[] = } init_table[] = {
{
"d0", DATA0, "d0", DATA0,
"d1", DATA1, "d1", DATA1,
"d2", DATA2, "d2", DATA2,
@ -2610,7 +2654,6 @@ int number;
"srp", SRP, "srp", SRP,
"urp", URP, "urp", URP,
#ifndef NO_68851
"ac", AC, "ac", AC,
"bc", BC, "bc", BC,
"cal", CAL, "cal", CAL,
@ -2636,12 +2679,19 @@ int number;
"bac5", BAC5, "bac5", BAC5,
"bac6", BAC6, "bac6", BAC6,
"bac7", BAC7, "bac7", BAC7,
#endif
"ic", IC, "ic", IC,
"dc", DC, "dc", DC,
"nc", NC, "nc", NC,
"tt0", TT0,
"tt1", TT1,
/* 68ec030 versions of same */
"ac0", TT0,
"ac1", TT1,
/* 68ec030 access control unit, identical to 030 MMU status reg */
"acusr", PSR,
0, 0,
}; };
@ -2652,9 +2702,7 @@ init_regtable()
{ {
int i; int i;
for (i = 0; init_table[i].name; i++) for (i = 0; init_table[i].name; i++)
{
insert_reg(init_table[i].name, init_table[i].number); insert_reg(init_table[i].name, init_table[i].number);
}
} }
@ -2668,47 +2716,58 @@ md_assemble(str)
int m,n = 0; int m,n = 0;
char *to_beg_P; char *to_beg_P;
int shorts_this_frag; int shorts_this_frag;
static int done_first_time;
if (!done_first_time)
if (cpu_of_arch (current_architecture) == 0)
{ {
enum m68k_architecture cpu_type; done_first_time = 1;
if (cpu_of_arch (current_architecture) == 0)
{
enum m68k_architecture cpu_type;
#ifndef TARGET_CPU #ifndef TARGET_CPU
cpu_type = m68020; cpu_type = m68020;
#else #else
if (strcmp (TARGET_CPU, "m68000") == 0) if (strcmp (TARGET_CPU, "m68000") == 0)
cpu_type = m68000; cpu_type = m68000;
else if (strcmp (TARGET_CPU, "m68010") == 0) else if (strcmp (TARGET_CPU, "m68010") == 0)
cpu_type = m68010; cpu_type = m68010;
else if (strcmp (TARGET_CPU, "m68020") == 0 else if (strcmp (TARGET_CPU, "m68020") == 0
|| strcmp (TARGET_CPU, "m68k") == 0) || strcmp (TARGET_CPU, "m68k") == 0)
cpu_type = m68020; cpu_type = m68020;
else if (strcmp (TARGET_CPU, "m68030") == 0) else if (strcmp (TARGET_CPU, "m68030") == 0)
cpu_type = m68030; cpu_type = m68030;
else if (strcmp (TARGET_CPU, "m68040") == 0) else if (strcmp (TARGET_CPU, "m68040") == 0)
cpu_type = m68040; cpu_type = m68040;
else else
cpu_type = m68020; cpu_type = m68020;
#endif #endif
/* If float or mmu were specified, just default cpu. */ /* If float or mmu were specified, just default cpu. */
if (current_architecture != 0) if (current_architecture != 0)
current_architecture |= cpu_type; current_architecture |= cpu_type;
else else
{ {
if ((cpu_type & m68020up) != 0) if ((cpu_type & m68020up) != 0)
current_architecture = (cpu_type current_architecture = (cpu_type
#ifndef NO_68881 #ifndef NO_68881
| m68881 | m68881
#endif #endif
#ifndef NO_68851 #ifndef NO_68851
| m68851 | m68851
#endif #endif
); );
else else
current_architecture = cpu_type; current_architecture = cpu_type;
}
} }
if (cpu_of_arch (current_architecture) == m68000
&& (current_architecture & m68881) != 0)
{
as_bad ("incompatible processors 68000 and 68881 specified");
}
done_first_time = 1;
} }
memset((char *)(&the_ins), '\0', sizeof(the_ins)); /* JF for paranoia sake */ memset((char *)(&the_ins), '\0', sizeof(the_ins)); /* JF for paranoia sake */