gas/testsuite/

* gas/m68k/mcf-coproc.d: New.
	* gas/m68k/mcf-coproc.s: New.
	* gas/m68k/all.exp: Add it.

	gas/
	* config/tc-m68k.c (m68k_ip): Add j & K operand types.
	(install_operand): Add E encoding.
	(md_begin): Check and skip initial '.' arg character.
	(get_num): Add 0..511 case.

	include/
	* opcode/m68k.h: Document j K & E.

	opcodes/
	* m68k-dis.c (fetch_arg): Add E.  Replace length switch with
	direct masking.
	(print_ins_arg): Add j & K operand types.
	(match_insn_m68k): Check and skip initial '.' arg character.
	(m68k_scan_mask): Likewise.
	* m68k-opc.c (m68k_opcodes): Add coprocessor instructions.
This commit is contained in:
Nathan Sidwell 2007-07-03 07:54:19 +00:00
parent ae4a729bff
commit afa2158f09
11 changed files with 248 additions and 42 deletions

View File

@ -1,3 +1,10 @@
2007-07-03 Nathan Sidwell <nathan@codesourcery.com>
* config/tc-m68k.c (m68k_ip): Add j & K operand types.
(install_operand): Add E encoding.
(md_begin): Check and skip initial '.' arg character.
(get_num): Add 0..511 case.
2007-07-03 Alan Modra <amodra@bigpond.net.au>
PR 4713

View File

@ -1965,6 +1965,22 @@ m68k_ip (char *instring)
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.
@ -3482,6 +3498,14 @@ m68k_ip (char *instring)
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 ();
}
@ -3550,6 +3574,9 @@ install_operand (int mode, int val)
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;
@ -4362,14 +4389,28 @@ md_begin (void)
{
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))
{
@ -5229,6 +5270,7 @@ md_create_long_jump (char *ptr, addressT from_addr, addressT to_addr,
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. */
@ -5284,6 +5326,10 @@ get_num (struct m68k_exp *exp, int ok)
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)
{

View File

@ -1,3 +1,9 @@
2007-07-03 Nathan Sidwell <nathan@codesourcery.com>
* gas/m68k/mcf-coproc.d: New.
* gas/m68k/mcf-coproc.s: New.
* gas/m68k/all.exp: Add it.
2007-06-29 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
* gas/cr16: New directory

View File

@ -52,6 +52,7 @@ if { [istarget m68*-*-*] || [istarget fido*-*-*] } then {
run_dump_test mode5
run_dump_test mcf-mac
run_dump_test mcf-emac
run_dump_test mcf-coproc
run_dump_test mcf-fpu
run_dump_test mcf-trap
run_dump_test mcf-wdebug

View File

@ -0,0 +1,50 @@
#objdump: -d
#as: -mcpu=5475
.*: file format .*
Disassembly of section .text:
0+ <start>:
[ 0-9a-f]+: fcc0 0050 cp0bcbusy [0-9a-f]+ <zero>
[ 0-9a-f]+: fc80 2123 cp0ldl %d0,%d2,#1,#291
[ 0-9a-f]+: fc88 a201 cp0ldl %a0,%a2,#2,#1
[ 0-9a-f]+: fc50 a401 cp0ldw %a0@,%a2,#3,#1
[ 0-9a-f]+: fc18 aa01 cp0ldb %a0@\+,%a2,#6,#1
[ 0-9a-f]+: fca0 ac01 cp0ldl %a0@-,%a2,#7,#1
[ 0-9a-f]+: fca8 ae01 0010 cp0ldl %a0@\(16\),%a2,#8,#1
[ 0-9a-f]+: fd80 2123 cp0stl %d2,%d0,#1,#291
[ 0-9a-f]+: fd88 a201 cp0stl %a2,%a0,#2,#1
[ 0-9a-f]+: fd50 a401 cp0stw %a2,%a0@,#3,#1
[ 0-9a-f]+: fd18 aa01 cp0stb %a2,%a0@\+,#6,#1
[ 0-9a-f]+: fda0 ac01 cp0stl %a2,%a0@-,#7,#1
[ 0-9a-f]+: fda8 ae01 0010 cp0stl %a2,%a0@\(16\),#8,#1
[ 0-9a-f]+: fc00 0e00 cp0nop #8
[ 0-9a-f]+: fc80 0400 cp0nop #3
[ 0-9a-f]+: fc80 1400 cp0ldl %d0,%d1,#3,#0
[ 0-9a-f]+: fc88 0400 cp0ldl %a0,%d0,#3,#0
[ 0-9a-f]+: fc90 0400 cp0ldl %a0@,%d0,#3,#0
[ 0-9a-f]+: fca8 0400 0010 cp0ldl %a0@\(16\),%d0,#3,#0
[ 0-9a-f]+ <zero>:
[ 0-9a-f]+: 4e71 nop
[ 0-9a-f]+: fec0 0050 cp1bcbusy [0-9a-f]+ <one>
[ 0-9a-f]+: fe80 2123 cp1ldl %d0,%d2,#1,#291
[ 0-9a-f]+: fe88 a201 cp1ldl %a0,%a2,#2,#1
[ 0-9a-f]+: fe50 a401 cp1ldw %a0@,%a2,#3,#1
[ 0-9a-f]+: fe18 aa01 cp1ldb %a0@\+,%a2,#6,#1
[ 0-9a-f]+: fea0 ac01 cp1ldl %a0@-,%a2,#7,#1
[ 0-9a-f]+: fea8 ae01 0010 cp1ldl %a0@\(16\),%a2,#8,#1
[ 0-9a-f]+: ff80 2123 cp1stl %d2,%d0,#1,#291
[ 0-9a-f]+: ff88 a201 cp1stl %a2,%a0,#2,#1
[ 0-9a-f]+: ff50 a401 cp1stw %a2,%a0@,#3,#1
[ 0-9a-f]+: ff18 aa01 cp1stb %a2,%a0@\+,#6,#1
[ 0-9a-f]+: ffa0 ac01 cp1stl %a2,%a0@-,#7,#1
[ 0-9a-f]+: ffa8 ae01 0010 cp1stl %a2,%a0@\(16\),#8,#1
[ 0-9a-f]+: fe00 0e00 cp1nop #8
[ 0-9a-f]+: fe80 0400 cp1nop #3
[ 0-9a-f]+: fe80 1400 cp1ldl %d0,%d1,#3,#0
[ 0-9a-f]+: fe88 0400 cp1ldl %a0,%d0,#3,#0
[ 0-9a-f]+: fe90 0400 cp1ldl %a0@,%d0,#3,#0
[ 0-9a-f]+: fea8 0400 0010 cp1ldl %a0@\(16\),%d0,#3,#0
[ 0-9a-f]+ <one>:
[ 0-9a-f]+: 4e71 nop

View File

@ -0,0 +1,47 @@
start:
cp0bcbusy zero
cp0ld %d0,%d2,#1,#0x123
cp0ldl %a0,%a2,#2,#0x1
cp0ldw (%a0),%a2,#3,#0x1
cp0ldb (%a0)+,%a2,#6,#0x1
cp0ldl -(%a0),%a2,#7,#0x1
cp0ldl 16(%a0),%a2,#8,#0x1
cp0st %d2,%d0,#1,#0x123
cp0stl %a2,%a0,#2,#0x1
cp0stw %a2,(%a0),#3,#0x1
cp0stb %a2,(%a0)+,#6,#0x1
cp0stl %a2,-(%a0),#7,#0x1
cp0stl %a2,16(%a0),#8,#0x1
cp0nop #8
cp0ld %d0,%d0,#3,#0
cp0ld %d0,%d1,#3,#0
cp0ld %a0,%d0,#3,#0
cp0ld (%a0),%d0,#3,#0
cp0ld 16(%a0),%d0,#3,#0
zero: nop
cp1bcbusy one
cp1ld %d0,%d2,#1,#0x123
cp1ldl %a0,%a2,#2,#0x1
cp1ldw (%a0),%a2,#3,#0x1
cp1ldb (%a0)+,%a2,#6,#0x1
cp1ldl -(%a0),%a2,#7,#0x1
cp1ldl 16(%a0),%a2,#8,#0x1
cp1st %d2,%d0,#1,#0x123
cp1stl %a2,%a0,#2,#0x1
cp1stw %a2,(%a0),#3,#0x1
cp1stb %a2,(%a0)+,#6,#0x1
cp1stl %a2,-(%a0),#7,#0x1
cp1stl %a2,16(%a0),#8,#0x1
cp1nop #8
cp1ld %d0,%d0,#3,#0
cp1ld %d0,%d1,#3,#0
cp1ld %a0,%d0,#3,#0
cp1ld (%a0),%d0,#3,#0
cp1ld 16(%a0),%d0,#3,#0
one: nop

View File

@ -1,3 +1,7 @@
2007-07-03 Nathan Sidwell <nathan@codesourcery.com>
* opcode/m68k.h: Document j K & E.
2007-06-29 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
* dis-asm.h (print_insn_cr16): New prototype.

View File

@ -96,10 +96,15 @@ struct m68k_opcode_alias
The args field is a string containing two characters for each
operand of the instruction. The first specifies the kind of
operand; the second, the place it is stored. */
operand; the second, the place it is stored.
If the first char of args is '.', it indicates that the opcode is
two words. This is only necessary when the match field does not
have any bits set in the second opcode word. Such a '.' is skipped
for operand processing. */
/* Kinds of operands:
Characters used: AaBbCcDdEeFfGgHIiJkLlMmnOopQqRrSsTtU VvWwXxYyZz01234|*~%;@!&$?/<>#^+-
Characters used: AaBbCcDdEeFfGgHIiJjKkLlMmnOopQqRrSsTtUuVvWwXxYyZz01234|*~%;@!&$?/<>#^+-
D data register only. Stored as 3 bits.
A address register only. Stored as 3 bits.
@ -234,6 +239,8 @@ struct m68k_opcode_alias
y (modes 2,5)
z (modes 2,5,7.2)
x mov3q immediate operand.
j coprocessor ET operand.
K coprocessor command number.
4 (modes 2,3,4,5)
*/
@ -301,6 +308,7 @@ struct m68k_opcode_alias
7 second word, shifted 7
8 second word, shifted 10
9 second word, shifted 5
E second word, shifted 9
D store in both place 1 and place 3; for divul and divsl.
B first word, low byte, for branch displacements
W second word (entire), for branch displacements

View File

@ -1,3 +1,12 @@
2007-07-03 Nathan Sidwell <nathan@codesourcery.com>
* m68k-dis.c (fetch_arg): Add E. Replace length switch with
direct masking.
(print_ins_arg): Add j & K operand types.
(match_insn_m68k): Check and skip initial '.' arg character.
(m68k_scan_mask): Likewise.
* m68k-opc.c (m68k_opcodes): Add coprocessor instructions.
2007-07-02 Alan Modra <amodra@bigpond.net.au>
* Makefile.am: Run "make dep-am".

View File

@ -280,6 +280,11 @@ fetch_arg (unsigned char *buffer,
val = (buffer[1] >> 6);
break;
case 'E':
FETCH_DATA (info, buffer + 3);
val = (buffer[2] >> 1);
break;
case 'm':
val = (buffer[1] & 0x40 ? 0x8 : 0)
| ((buffer[0] >> 1) & 0x7)
@ -310,29 +315,8 @@ fetch_arg (unsigned char *buffer,
abort ();
}
switch (bits)
{
case 1:
return val & 1;
case 2:
return val & 3;
case 3:
return val & 7;
case 4:
return val & 017;
case 5:
return val & 037;
case 6:
return val & 077;
case 7:
return val & 0177;
case 8:
return val & 0377;
case 12:
return val & 07777;
default:
abort ();
}
/* bits is never too big. */
return val & ((1 << bits) - 1);
}
/* Check if an EA is valid for a particular code. This is required
@ -685,6 +669,16 @@ print_insn_arg (const char *d,
(*info->fprintf_func) (info->stream, "#%d", val);
break;
case 'j':
val = fetch_arg (buffer, place, 3, info);
(*info->fprintf_func) (info->stream, "#%d", val+1);
break;
case 'K':
val = fetch_arg (buffer, place, 9, info);
(*info->fprintf_func) (info->stream, "#%d", val);
break;
case 'M':
if (place == 'h')
{
@ -1214,6 +1208,7 @@ match_insn_m68k (bfd_vma memaddr,
unsigned char *save_p;
unsigned char *p;
const char *d;
const char *args = best->args;
struct private *priv = (struct private *) info->private_data;
bfd_byte *buffer = priv->the_buffer;
@ -1221,6 +1216,9 @@ match_insn_m68k (bfd_vma memaddr,
void (* save_print_address) (bfd_vma, struct disassemble_info *)
= info->print_address_func;
if (*args == '.')
args++;
/* Point at first word of argument data,
and at descriptor for first argument. */
p = buffer + 2;
@ -1229,7 +1227,7 @@ match_insn_m68k (bfd_vma memaddr,
The only place this is stored in the opcode table is
in the arguments--look for arguments which specify fields in the 2nd
or 3rd words of the instruction. */
for (d = best->args; *d; d += 2)
for (d = args; *d; d += 2)
{
/* I don't think it is necessary to be checking d[0] here;
I suspect all this could be moved to the case statement below. */
@ -1276,8 +1274,8 @@ match_insn_m68k (bfd_vma memaddr,
three words long. */
if (p - buffer < 6
&& (best->match & 0xffff) == 0xffff
&& best->args[0] == '#'
&& best->args[1] == 'w')
&& args[0] == '#'
&& args[1] == 'w')
{
/* Copy the one word argument into the usual location for a one
word argument, to simplify printing it. We can get away with
@ -1291,15 +1289,13 @@ match_insn_m68k (bfd_vma memaddr,
FETCH_DATA (info, p);
d = best->args;
save_p = p;
info->print_address_func = dummy_print_address;
info->fprintf_func = (fprintf_ftype) dummy_printer;
/* We scan the operands twice. The first time we don't print anything,
but look for errors. */
for (; *d; d += 2)
for (d = args; *d; d += 2)
{
int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
@ -1329,7 +1325,7 @@ match_insn_m68k (bfd_vma memaddr,
info->fprintf_func = save_printer;
info->print_address_func = save_print_address;
d = best->args;
d = args;
info->fprintf_func (info->stream, "%s", best->name);
@ -1401,6 +1397,10 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
const struct m68k_opcode *opc = opcodes[major_opcode][i];
unsigned long opcode = opc->opcode;
unsigned long match = opc->match;
const char *args = opc->args;
if (*args == '.')
args++;
if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
&& ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
@ -1416,7 +1416,7 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
/* Don't use for printout the variants of divul and divsl
that have the same register number in two places.
The more general variants will match instead. */
for (d = opc->args; *d; d += 2)
for (d = args; *d; d += 2)
if (d[1] == 'D')
break;
@ -1424,7 +1424,7 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
point coprocessor instructions which use the same
register number in two places, as above. */
if (*d == '\0')
for (d = opc->args; *d; d += 2)
for (d = args; *d; d += 2)
if (d[1] == 't')
break;
@ -1432,7 +1432,7 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
wait for fmoveml. */
if (*d == '\0')
{
for (d = opc->args; *d; d += 2)
for (d = args; *d; d += 2)
{
if (d[0] == 's' && d[1] == '8')
{
@ -1446,7 +1446,7 @@ m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
/* Don't match FPU insns with non-default coprocessor ID. */
if (*d == '\0')
{
for (d = opc->args; *d; d += 2)
for (d = args; *d; d += 2)
{
if (d[0] == 'I')
{

View File

@ -30,6 +30,10 @@
be consecutive. If they aren't, the assembler will bomb at
runtime. */
/* Format strings consist of pairs of characters. The first describes
the type of the operand and the second describes the encoding.
include/opcodes/m68k.h describes them in detail. */
const struct m68k_opcode m68k_opcodes[] =
{
{"abcd", 2, one(0140400), one(0170770), "DsDd", m68000up },
@ -290,7 +294,31 @@ const struct m68k_opcode m68k_opcodes[] =
{"cmpl", 6, one(0006200), one(0177700), "#lDs", mcfisa_a },
{"cmpl", 2, one(0130610), one(0170770), "+s+d", m68000up },
{"cmpl", 2, one(0130200), one(0170700), "*lDd", m68000up | mcfisa_a },
{"cp0bcbusy",2, one (0176300), one (01777770), "BW", mcfisa_a},
{"cp1bcbusy",2, one (0177300), one (01777770), "BW", mcfisa_a},
{"cp0nop", 4, two (0176000,0), two (01777477,0170777), "jE", mcfisa_a},
{"cp1nop", 4, two (0177000,0), two (01777477,0170777), "jE", mcfisa_a},
/* These all have 2 opcode words, but no fixed bits in the second
word. We use a leading ' ' in the args string to indicate the
extra opcode word. */
{"cp0ldb", 6, one (0176000), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp1ldb", 6, one (0177000), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp0ldw", 6, one (0176100), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp1ldw", 6, one (0177100), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp0ldl", 6, one (0176200), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp1ldl", 6, one (0177200), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp0ld", 6, one (0176200), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp1ld", 6, one (0177200), one (01777700), ".pwR1jEK3", mcfisa_a},
{"cp0stb", 6, one (0176400), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp1stb", 6, one (0177400), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp0stw", 6, one (0176500), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp1stw", 6, one (0177500), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp0stl", 6, one (0176600), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp1stl", 6, one (0177600), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp0st", 6, one (0176600), one (01777700), ".R1pwjEK3", mcfisa_a},
{"cp1st", 6, one (0177600), one (01777700), ".R1pwjEK3", mcfisa_a},
{"dbcc", 2, one(0052310), one(0177770), "DsBw", m68000up },
{"dbcs", 2, one(0052710), one(0177770), "DsBw", m68000up },
{"dbeq", 2, one(0053710), one(0177770), "DsBw", m68000up },