GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
RAMBAR0, RAMBAR1, RAMBAR, MBAR,
0
};
+static const enum m68k_register mcf51qe_ctrl[] = {
+ VBR,
+ 0
+};
static const enum m68k_register mcf5206_ctrl[] = {
CACR, ACR0, ACR1, VBR, RAMBAR0, RAMBAR_ALT, MBAR,
0
0
};
static const enum m68k_register mcf52235_ctrl[] = {
- VBR, FLASHBAR, RAMBAR, RAMBAR1,
+ VBR, CACR, ACR0, ACR1, FLASHBAR, RAMBAR, RAMBAR1,
0
};
static const enum m68k_register mcf5225_ctrl[] = {
0
};
static const enum m68k_register mcf5253_ctrl[] = {
- VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, MBAR,
+ VBR, CACR, ACR0, ACR1, RAMBAR0, RAMBAR1, RAMBAR, MBAR, MBAR2,
0
};
static const enum m68k_register mcf5271_ctrl[] = {
ROMBAR /* ROMBAR0 */, RAMBAR /* RAMBAR1 */,
0
};
+static const enum m68k_register mcf5407_ctrl[] = {
+ CACR, ASID, ACR0, ACR1, ACR2, ACR3,
+ VBR, PC, RAMBAR0, RAMBAR1, MBAR,
+ /* Legacy names */
+ TC /* ASID */,
+ ITT0 /* ACR0 */, ITT1 /* ACR1 */, DTT0 /* ACR2 */, DTT1 /* ACR3 */,
+ MBAR1 /* MBAR */, RAMBAR /* RAMBAR1 */,
+ 0
+};
static const enum m68k_register mcf54455_ctrl[] = {
CACR, ASID, ACR0, ACR1, ACR2, ACR3, MMUBAR,
VBR, PC, RAMBAR1, MBAR,
0
};
static const enum m68k_register fido_ctrl[] = {
- SFC, DFC, USP, VBR, CAC, MBB,
+ SFC, DFC, USP, VBR, CAC, MBO,
0
};
#define cpu32_ctrl m68010_ctrl
((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b|mcfisa_c))
#define HAVE_LONG_BRANCH(x) \
((x) & (m68020|m68030|m68040|m68060|cpu32|fido_a|mcfisa_b))
+#define LONG_BRANCH_VIA_COND(x) (HAVE_LONG_COND(x) && !HAVE_LONG_BRANCH(x))
static struct m68k_it the_ins; /* The instruction being assembled. */
{cpu32|m68881, cpu32_ctrl, "68341", 1},
{cpu32|m68881, cpu32_ctrl, "68349", 1},
{cpu32|m68881, cpu32_ctrl, "68360", 1},
+
+ {mcfisa_a|mcfisa_c|mcfusp, mcf51qe_ctrl, "51qe", 0},
{mcfisa_a, mcf_ctrl, "5200", 0},
{mcfisa_a, mcf_ctrl, "5202", 1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5373_ctrl, "5373", -1},
{mcfisa_a|mcfisa_aa|mcfhwdiv|mcfemac|mcfusp, mcf5373_ctrl, "537x", 0},
- {mcfisa_a|mcfisa_b|mcfhwdiv|mcfmac, mcf_ctrl, "5407",0},
+ {mcfisa_a|mcfisa_b|mcfhwdiv|mcfmac, mcf5407_ctrl, "5407",0},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54450", -1},
{mcfisa_a|mcfisa_c|mcfhwdiv|mcfemac|mcfusp, mcf54455_ctrl, "54451", -1},
#define PCINDEX 8 /* PC + displacement + index. */
#define ABSTOPCREL 9 /* Absolute relax down to 16-bit PC-relative. */
+/* This relaxation is required for branches where there is no long
+ branch and we are in pcrel mode. We generate a bne/beq pair. */
+#define BRANCHBWPL 10 /* Branch byte, word or pair of longs
+ */
+
/* Note that calls to frag_var need to specify the maximum expansion
- needed; this is currently 10 bytes for DBCC. */
+ needed; this is currently 12 bytes for bne/beq pair. */
+#define FRAG_VAR_SIZE 12
/* The fields are:
How far Forward this mode will reach:
{ 32767, -32768, 2, TAB (ABSTOPCREL, LONG) },
{ 0, 0, 4, 0 },
{ 1, 1, 0, 0 },
+
+ { 127, -128, 0, TAB (BRANCHBWPL, SHORT) },
+ { 32767, -32768, 2, TAB (BRANCHBWPL, LONG) },
+ { 0, 0, 10, 0 },
+ { 1, 1, 0, 0 },
};
/* These are the machine dependent pseudo-ops. These are included so
losing++;
break;
+ case 'j':
+ if (opP->mode != IMMED)
+ losing++;
+ else if (opP->disp.exp.X_op != O_constant
+ || TRUNC (opP->disp.exp.X_add_number) - 1 > 7)
+ losing++;
+ break;
+
+ case 'K':
+ if (opP->mode != IMMED)
+ losing++;
+ else if (opP->disp.exp.X_op != O_constant
+ || TRUNC (opP->disp.exp.X_add_number) > 511)
+ losing++;
+ break;
+
/* JF these are out of order. We could put them
in order if we were willing to put up with
bunches of #ifdef m68851s in the code.
the_ins.error = buf;
/* Make sure there's a NUL at the end of the buffer -- strncpy
- won't write one when it runs out of buffer */
+ won't write one when it runs out of buffer. */
buf[space] = 0;
#define APPEND(STRING) \
(strncpy (buf, STRING, space), len = strlen (buf), buf += len, space -= len)
switch (ok_arch)
{
case mcfisa_a:
- APPEND (_("ColdFire ISA_A"));
+ APPEND ("ColdFire ISA_A");
break;
case mcfhwdiv:
- APPEND (_("ColdFire hardware divide"));
+ APPEND ("ColdFire ");
+ APPEND (_("hardware divide"));
break;
case mcfisa_aa:
- APPEND (_("ColdFire ISA_A+"));
+ APPEND ("ColdFire ISA_A+");
break;
case mcfisa_b:
- APPEND (_("ColdFire ISA_B"));
+ APPEND ("ColdFire ISA_B");
+ break;
+ case mcfisa_c:
+ APPEND ("ColdFire ISA_C");
break;
case cfloat:
- APPEND (_("ColdFire fpu"));
+ APPEND ("ColdFire fpu");
break;
case mfloat:
- APPEND (_("M68K fpu"));
+ APPEND ("M68K fpu");
break;
case mmmu:
- APPEND (_("M68K mmu"));
+ APPEND ("M68K mmu");
break;
case m68020up:
- APPEND (_("68020 or higher"));
+ APPEND ("68020 ");
+ APPEND (_("or higher"));
break;
case m68000up:
- APPEND (_("68000 or higher"));
+ APPEND ("68000 ");
+ APPEND (_("or higher"));
break;
case m68010up:
- APPEND (_("68010 or higher"));
+ APPEND ("68010 ");
+ APPEND (_("or higher"));
break;
default:
paren = 0;
#undef APPEND
if (!space)
{
- /* we ran out of space, so replace the end of the list
+ /* We ran out of space, so replace the end of the list
with ellipsis. */
buf -= 4;
while (*buf != ' ')
for (s = the_ins.args, opP = &the_ins.operands[0]; *s; s += 2, opP++)
{
int have_disp = 0;
+ int use_pl = 0;
/* This switch is a doozy.
Watch the first step; its a big one! */
case 'b': /* Unconditional branch */
have_disp = HAVE_LONG_BRANCH (current_architecture);
+ use_pl = LONG_BRANCH_VIA_COND (current_architecture);
goto var_branch;
case 's': /* Unconditional subroutine */
else
add_frag (adds (&opP->disp),
SEXT (offs (&opP->disp)),
- TAB (BRANCHBW, SZ_UNDEF));
+ (use_pl ? TAB (BRANCHBWPL, SZ_UNDEF)
+ : TAB (BRANCHBW, SZ_UNDEF)));
break;
case 'w':
if (isvar (&opP->disp))
case CAC:
tmpreg = 0xFFE;
break;
- case MBB:
+ case MBO:
tmpreg = 0xFFF;
break;
default:
tmpreg = 0;
install_operand (s[1], tmpreg);
break;
+ case 'j':
+ tmpreg = get_num (&opP->disp, 10);
+ install_operand (s[1], tmpreg - 1);
+ break;
+ case 'K':
+ tmpreg = get_num (&opP->disp, 65);
+ install_operand (s[1], tmpreg);
+ break;
default:
abort ();
}
return out;
} /* reverse_8_bits() */
-/* Cause an extra frag to be generated here, inserting up to 10 bytes
- (that value is chosen in the frag_var call in md_assemble). TYPE
- is the subtype of the frag to be generated; its primary type is
- rs_machine_dependent.
+/* Cause an extra frag to be generated here, inserting up to
+ FRAG_VAR_SIZE bytes. TYPE is the subtype of the frag to be
+ generated; its primary type is rs_machine_dependent.
The TYPE parameter is also used by md_convert_frag_1 and
md_estimate_size_before_relax. The appropriate type of fixup will
case 'd':
the_ins.opcode[0] |= val << 9;
break;
+ case 'E':
+ the_ins.opcode[1] |= val << 9;
+ break;
case '1':
the_ins.opcode[1] |= val << 12;
break;
{ "mbar2", MBAR2 }, /* mcf5249 registers. */
{ "cac", CAC }, /* fido registers. */
- { "mbb", MBB }, /* fido registers. */
+ { "mbb", MBO }, /* fido registers (obsolete). */
+ { "mbo", MBO }, /* fido registers. */
/* End of control registers. */
{ "ac", AC },
for (n = 1; n < the_ins.nfrag; n++)
wid += 2 * (the_ins.numo - the_ins.fragb[n - 1].fragoff);
/* frag_var part. */
- wid += 10;
+ wid += FRAG_VAR_SIZE;
/* Make sure the whole insn fits in one chunk, in particular that
the var part is attached, as we access one byte before the
variable frag for byte branches. */
the_ins.reloc[m].pic_reloc));
fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
}
- (void) frag_var (rs_machine_dependent, 10, 0,
+ (void) frag_var (rs_machine_dependent, FRAG_VAR_SIZE, 0,
(relax_substateT) (the_ins.fragb[n].fragty),
the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
}
{
ins = m68k_sorted_opcodes[i];
- /* We *could* ignore insns that don't match our
- arch here by just leaving them out of the hash. */
+ /* We must enter all insns into the table, because .arch and
+ .cpu directives can change things. */
slak->m_operands = ins->args;
- slak->m_opnum = strlen (slak->m_operands) / 2;
slak->m_arch = ins->arch;
slak->m_opcode = ins->opcode;
- /* This is kludgey. */
- slak->m_codenum = ((ins->match) & 0xffffL) ? 2 : 1;
+
+ /* In most cases we can determine the number of opcode words
+ by checking the second word of the mask. Unfortunately
+ some instructions have 2 opcode words, but no fixed bits
+ in the second word. A leading dot in the operands
+ string also indicates 2 opcodes. */
+ if (*slak->m_operands == '.')
+ {
+ slak->m_operands++;
+ slak->m_codenum = 2;
+ }
+ else if (ins->match & 0xffffL)
+ slak->m_codenum = 2;
+ else
+ slak->m_codenum = 1;
+ slak->m_opnum = strlen (slak->m_operands) / 2;
+
if (i + 1 != m68k_numopcodes
&& !strcmp (ins->name, m68k_sorted_opcodes[i + 1]->name))
{
}
}
-/* Equal to MAX_PRECISION in atof-ieee.c. */
-#define MAX_LITTLENUMS 6
-
-/* Turn a string in input_line_pointer into a floating point constant
- of type TYPE, and store the appropriate bytes in *LITP. The number
- of LITTLENUMS emitted is stored in *SIZEP. An error message is
- returned, or NULL on OK. */
-
char *
md_atof (int type, char *litP, int *sizeP)
{
- int prec;
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- LITTLENUM_TYPE *wordP;
- char *t;
-
- switch (type)
- {
- case 'f':
- case 'F':
- case 's':
- case 'S':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- case 'r':
- case 'R':
- prec = 4;
- break;
-
- case 'x':
- case 'X':
- prec = 6;
- break;
-
- case 'p':
- case 'P':
- prec = 6;
- break;
-
- default:
- *sizeP = 0;
- return _("Bad call to MD_ATOF()");
- }
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * sizeof (LITTLENUM_TYPE);
- for (wordP = words; prec--;)
- {
- md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
- return 0;
+ return ieee_md_atof (type, litP, sizeP, TRUE);
}
void
case TAB (BRABSJUNC, BYTE):
case TAB (BRABSJCOND, BYTE):
case TAB (BRANCHBW, BYTE):
+ case TAB (BRANCHBWPL, BYTE):
know (issbyte (disp));
if (disp == 0)
as_bad_where (fragP->fr_file, fragP->fr_line,
case TAB (BRABSJUNC, SHORT):
case TAB (BRABSJCOND, SHORT):
case TAB (BRANCHBW, SHORT):
+ case TAB (BRANCHBWPL, SHORT):
fragP->fr_opcode[1] = 0x00;
fixP = fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
fragP->fr_offset, 1, RELAX_RELOC_PC16);
fragP->fr_offset, 1, RELAX_RELOC_PC32);
fragP->fr_fix += 4;
break;
+ case TAB (BRANCHBWPL, LONG):
+ /* Here we are converting an unconditional branch into a pair of
+ conditional branches, in order to get the range. */
+ fragP->fr_opcode[0] = 0x66; /* bne */
+ fragP->fr_opcode[1] = 0xFF;
+ fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, RELAX_RELOC_PC32);
+ fixP->fx_file = fragP->fr_file;
+ fixP->fx_line = fragP->fr_line;
+ fragP->fr_fix += 4; /* Skip first offset */
+ buffer_address += 4;
+ *buffer_address++ = 0x67; /* beq */
+ *buffer_address++ = 0xff;
+ fragP->fr_fix += 2; /* Skip second branch opcode */
+ fixP = fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
+ fragP->fr_offset, 1, RELAX_RELOC_PC32);
+ fragP->fr_fix += 4;
+ break;
case TAB (BRABSJUNC, LONG):
if (fragP->fr_opcode[0] == 0x61) /* jbsr */
{
switch (fragP->fr_subtype)
{
case TAB (BRANCHBWL, SZ_UNDEF):
+ case TAB (BRANCHBWPL, SZ_UNDEF):
case TAB (BRABSJUNC, SZ_UNDEF):
case TAB (BRABSJCOND, SZ_UNDEF):
{
50: absolute 0:127 only
55: absolute -64:63 only
60: absolute -128:127 only
+ 65: absolute 0:511 only
70: absolute 0:4095 only
80: absolute -1, 1:7 only
90: No bignums. */
if ((valueT) SEXT (offs (exp)) + 128 > 255)
goto outrange;
break;
+ case 65:
+ if ((valueT) TRUNC (offs (exp)) > 511)
+ goto outrange;
+ break;
case 70:
if ((valueT) TRUNC (offs (exp)) > 4095)
{
{EF_M68K_CF_ISA_B_NOUSP,mcfisa_a|mcfisa_b|mcfhwdiv},
{EF_M68K_CF_ISA_B, mcfisa_a|mcfisa_b|mcfhwdiv|mcfusp},
{EF_M68K_CF_ISA_C, mcfisa_a|mcfisa_c|mcfhwdiv|mcfusp},
+ {EF_M68K_CF_ISA_C_NODIV,mcfisa_a|mcfisa_c|mcfusp},
{0,0},
};
static const unsigned mac_features[][2] =