package org.reasm.m68k.assembly.internal;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.hamcrest.Matcher;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.reasm.AssemblyMessage;
import org.reasm.Function;
import org.reasm.FunctionValue;
import org.reasm.StaticSymbol;
import org.reasm.Symbol;
import org.reasm.UnsignedIntValue;
import org.reasm.commons.messages.AddressingModeNotAllowedHereErrorMessage;
import org.reasm.commons.messages.FunctionCannotBeConvertedToIntegerErrorMessage;
import org.reasm.commons.messages.InvalidTokenErrorMessage;
import org.reasm.commons.messages.LossyConversionFromRealToIntegerWarningMessage;
import org.reasm.commons.messages.StringTooLongErrorMessage;
import org.reasm.commons.messages.SyntaxErrorInEffectiveAddressErrorMessage;
import org.reasm.commons.messages.ValueOutOfRangeErrorMessage;
import org.reasm.expressions.EvaluationContext;
import org.reasm.expressions.Expression;
import org.reasm.expressions.SymbolLookup;
import org.reasm.expressions.ValueExpression;
import org.reasm.m68k.InstructionSet;
import org.reasm.m68k.expressions.internal.Tokenizer;
import org.reasm.m68k.messages.AddressingModeNotSupportedErrorMessage;
import org.reasm.m68k.messages.BaseDisplacementOutOfRangeErrorMessage;
import org.reasm.m68k.messages.EndOfExpressionExpectedErrorMessage;
import org.reasm.m68k.messages.ExpressionExpectedErrorMessage;
import org.reasm.m68k.messages.InvalidScaleValueErrorMessage;
import org.reasm.m68k.messages.ScaleSpecificationNotSupportedErrorMessage;
import org.reasm.testhelpers.AssemblyMessageCollector;
import org.reasm.testhelpers.DummySymbolLookup;
import org.reasm.testhelpers.EquivalentAssemblyMessage;
import org.reasm.testhelpers.SingleSymbolLookup;
/**
* Test class for {@link EffectiveAddress}.
*
* @author Francis Gagné
*/
@SuppressWarnings("javadoc")
public class EffectiveAddressTest {
public static abstract class BaseSuccessfulTest extends BaseTestWithOutputCheck<BaseTestWithOutputCheck.DataItem> {
protected BaseSuccessfulTest(@Nonnull DataItem data) {
super(data);
}
@Override
protected void checkMessages(ArrayList<AssemblyMessage> messages) {
assertThat(messages, is(empty()));
}
}
public static abstract class BaseTest<TDataItem extends BaseTest.DataItem> {
public static class DataItem {
@Nonnull
private static final M68KTestAssemblyContext EMPTY_ASSEMBLY_CONTEXT = new M68KTestAssemblyContext();
@Nonnull
final String text;
@Nonnull
final Set<AddressingMode> validAddressingModes;
final boolean expectBitFieldSpecification;
@Nonnull
final InstructionSize instructionSize;
@Nonnull
final InstructionSet instructionSet;
@CheckForNull
final SymbolLookup symbolLookup;
@Nonnull
final M68KTestAssemblyContext context;
public DataItem(@Nonnull String text, @Nonnull Set<AddressingMode> validAddressingModes,
boolean expectBitFieldSpecification, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @CheckForNull SymbolLookup symbolLookup,
@CheckForNull M68KTestAssemblyContext context) {
this.text = text;
this.validAddressingModes = validAddressingModes;
this.expectBitFieldSpecification = expectBitFieldSpecification;
this.instructionSize = instructionSize;
this.instructionSet = instructionSet;
this.symbolLookup = symbolLookup;
this.context = context != null ? context : EMPTY_ASSEMBLY_CONTEXT;
}
}
@Nonnull
final TDataItem data;
protected BaseTest(@Nonnull TDataItem data) {
this.data = data;
}
@Test
public void getEffectiveAddress() {
try {
final Tokenizer tokenizer = new Tokenizer();
final EffectiveAddress ea = new EffectiveAddress();
final ArrayList<AssemblyMessage> messages = new ArrayList<>();
tokenizer.setCharSequence(this.data.text);
this.data.context.instructionSet = this.data.instructionSet;
EffectiveAddress.getEffectiveAddress(tokenizer, this.data.symbolLookup, this.data.validAddressingModes,
this.data.expectBitFieldSpecification, this.data.instructionSize, 2, new EvaluationContext(null, 0, null),
this.data.context, new AssemblyMessageCollector(messages), ea);
this.checkMessages(messages);
this.checkOutput(ea);
} catch (AssertionError e) {
throw new AssertionError("text: " + this.data.text + e.getMessage(), e);
}
}
protected abstract void checkMessages(@Nonnull ArrayList<AssemblyMessage> messages);
protected abstract void checkOutput(@Nonnull EffectiveAddress ea);
}
public static abstract class BaseTestWithOutputCheck<TDataItem extends BaseTestWithOutputCheck.DataItem> extends
BaseTest<TDataItem> {
public static class DataItem extends BaseTest.DataItem {
@Nonnull
final short[] words;
public DataItem(@Nonnull String text, @Nonnull Set<AddressingMode> validAddressingModes,
boolean expectBitFieldSpecification, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @CheckForNull SymbolLookup symbolLookup,
@CheckForNull M68KTestAssemblyContext context, short[] words) {
super(text, validAddressingModes, expectBitFieldSpecification, instructionSize, instructionSet, symbolLookup,
context);
this.words = words;
}
}
protected BaseTestWithOutputCheck(@Nonnull TDataItem data) {
super(data);
}
@Override
protected void checkOutput(@Nonnull EffectiveAddress ea) {
assertThat((int) ea.numberOfWords, is(this.data.words.length));
for (int i = 0; i < ea.numberOfWords; i++) {
assertThat(ea.getWord(i), is(this.data.words[i]));
}
}
}
@RunWith(Parameterized.class)
public static class ExtendedSyntaxTest extends BaseSuccessfulTest {
@Nonnull
private static final ArrayList<Object[]> TEST_DATA = new ArrayList<>();
static {
// Address register indirect with displacement
// - MRI syntax
addDataItem("0(A0)", new short[] { 0b101000, 0x0000 });
addDataItem("0(a0)", new short[] { 0b101000, 0x0000 });
addDataItem("0(A7)", new short[] { 0b101111, 0x0000 });
addDataItem("-1(A0)", new short[] { 0b101000, -0x0001 });
addDataItem("-1(A7)", new short[] { 0b101111, -0x0001 });
addDataItem("--1(A0)", new short[] { 0b101000, 0x0001 });
addDataItem("2+2(A0)", new short[] { 0b101000, 0x0004 });
addDataItem("2+2*2(A0)", new short[] { 0b101000, 0x0006 });
addDataItem("1?2:4(A0)", new short[] { 0b101000, 0x0002 });
addDataItem("1?2:4?8:16(A0)", new short[] { 0b101000, 0x0002 });
// - reordered parts
addDataItem("(A0,0)", new short[] { 0b101000, 0x0000 });
// Address register indirect with index (8-bit displacement)
// - MRI syntax
addDataItem("0(A0,D0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,d0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,D0.W)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,D0.w)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,d0.W)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,d0.w)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,D0*1)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("0(A0,D0*2)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000010_00000000 });
addDataItem("0(A0,D0*4)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000100_00000000 });
addDataItem("0(A0,D0*8)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("0(A0,D0*8)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("0(A0,A7.L)", new short[] { 0b110000, (short) 0b11111000_00000000 });
addDataItem("0(A7,D0)", new short[] { 0b110111, 0b00000000_00000000 });
addDataItem("-1(A0,D0)", new short[] { 0b110000, 0b00000000_11111111 });
addDataItem("-1(A7,A7.L)", new short[] { 0b110111, (short) 0b11111000_11111111 });
addDataItem("-1(A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111110_11111111 });
addDataItem("-1(A7,A7.L*8)", InstructionSet.MC68020, new short[] { 0b110111, (short) 0b11111110_11111111 });
// - reordered parts
addDataItem("(D0,A0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(D0.W,A0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(D0.W*8,A0)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("(A0.W,A0)", new short[] { 0b110000, (short) 0b10000000_00000000 });
addDataItem("(0,D0,A0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(D0,0,A0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(D0,A0,0)", new short[] { 0b110000, 0b00000000_00000000 });
// - MRI syntax + reordered parts
addDataItem("0(D0,A0)", new short[] { 0b110000, 0b00000000_00000000 });
// Address register indirect with index (base displacement)
// - MRI syntax
addDataItem("$80(A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$80(A0,D0.W)", InstructionSet.MC68020, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$80(A0,D0.W*1)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$80(A0,D0.W*8)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000111_00100000, 0x0080 });
addDataItem("$80(A0,A7.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b11110001_00100000, 0x0080 });
addDataItem("$80(A7,D0.W)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$7FFF(A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x7FFF });
addDataItem("$8000(A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00110000, 0x0000,
(short) 0x8000 });
addDataItem("$FFFF7FFF(A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("-$81(A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111111_00100000, -0x0081 });
addDataItem("-$8001(A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111111_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("$10000(A0)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_01110000, 0x0001, 0x0000 });
addDataItem("1(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, 0x0001 });
addDataItem("1(D0.W*8)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000111_10100000, 0x0001 });
addDataItem("$7FFF(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, 0x7FFF });
addDataItem("$FFFF8000(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, -0x8000 });
addDataItem("$FFFFFFFF(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, -0x0001 });
addDataItem("-$8000(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_10100000, -0x8000 });
addDataItem("-1(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_10100000, -1 });
addDataItem("-1(A7.L*8)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b11111111_10100000, -1 });
addDataItem("$8000(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10110000, 0x0000, (short) 0x8000 });
addDataItem("$FFFF7FFF(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10110000, (short) 0xFFFF,
0x7FFF });
addDataItem("$FFFF7FFF(A7.L*8)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b11111111_10110000,
(short) 0xFFFF, 0x7FFF });
// - reordered parts
addDataItem("($80,D0.W,A0)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("(D0.W,$80,A0)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("(D0.W,A0,$80)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
// - MRI syntax + reordered parts
addDataItem("$80(D0.W,A0)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
// Memory indirect
// - MRI syntax
addDataItem("1([A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010010, 0x0001 });
addDataItem("$10000([A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010011, 0x0001, 0x0000 });
addDataItem("1([A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010110, 0x0001 });
addDataItem("$10000([A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010111, 0x0001, 0x0000 });
addDataItem("1([1,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("$10000([1,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100011, 0x0001, 0x0001,
0x0000 });
addDataItem("1([1,A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("$10000([1,A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100111, 0x0001, 0x0001,
0x0000 });
addDataItem("1([$10000,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110010, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10000,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([$10000,A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110110, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10000,A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010010, 0x0001 });
addDataItem("$10000([A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010011, 0x0001, 0x0000 });
addDataItem("1([1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("$10000([1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100011, 0x0001, 0x0001,
0x0000 });
addDataItem("1([$10000,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01110010, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10000,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01110011, 0x0001, 0x0000,
0x0001, 0x0000 });
addDataItem("1([D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010010, 0x0001 });
addDataItem("$10000([D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010011, 0x0001, 0x0000 });
addDataItem("1([],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010110, 0x0001 });
addDataItem("$10000([],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010111, 0x0001, 0x0000 });
addDataItem("1([1,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("$10000([1,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100011, 0x0001, 0x0001,
0x0000 });
addDataItem("1([1],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("$10000([1],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100111, 0x0001, 0x0001,
0x0000 });
addDataItem("1([$10000,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110010, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10000,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([$10000],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110110, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10000],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010010, 0x0001 });
addDataItem("$10000([])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010011, 0x0001, 0x0000 });
addDataItem("1([1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11100010, 0x0001, 0x0001 });
addDataItem("$10000([1])", InstructionSet.MC68020,
new short[] { 0b110000, 0b00000001_11100011, 0x0001, 0x0001, 0x0000 });
addDataItem("1([$10000])", InstructionSet.MC68020,
new short[] { 0b110000, 0b00000001_11110010, 0x0001, 0x0000, 0x0001 });
addDataItem("$10000([$10000])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11110011, 0x0001, 0x0000,
0x0001, 0x0000 });
// - reordered parts
addDataItem("([D0.W,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010001 });
addDataItem("(1,[A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010010, 0x0001 });
addDataItem("(D0.W,[A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010101 });
addDataItem("(D0.W,1,[A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010110, 0x0001 });
addDataItem("(1,D0.W,[A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010110, 0x0001 });
addDataItem("([D0.W,1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100001, 0x0001 });
addDataItem("([D0.W,A0,1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100001, 0x0001 });
addDataItem("(1,[1,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("(D0.W,[1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100101, 0x0001 });
addDataItem("(D0.W,1,[1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("(1,D0.W,[1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("(1,[A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010010, 0x0001 });
addDataItem("([A0,1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100001, 0x0001 });
addDataItem("(1,[1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("(1,[D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010010, 0x0001 });
addDataItem("(D0.W,[])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010101 });
addDataItem("(D0.W,[],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010110, 0x0001 });
addDataItem("(1,D0.W,[])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010110, 0x0001 });
addDataItem("([D0.W,1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100001, 0x0001 });
addDataItem("(1,[1,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("(D0.W,[1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100101, 0x0001 });
addDataItem("(A0,[1])", InstructionSet.MC68020, new short[] { 0b110000, (short) 0b10000001_10100101, 0x0001 });
addDataItem("(D0.W,[1],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("(D0.W,1,[1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("(1,[])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010010, 0x0001 });
addDataItem("(1,[1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11100010, 0x0001, 0x0001 });
// - MRI syntax + reordered parts
addDataItem("1([A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010010, 0x0001 });
addDataItem("1(D0.W,[A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010110, 0x0001 });
addDataItem("1(D0.W,[A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010110, 0x0001 });
addDataItem("1([1,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("1(D0.W,[1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("1(D0.W,[1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("1([A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010010, 0x0001 });
addDataItem("1([1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("1([D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010010, 0x0001 });
addDataItem("1(D0.W,[])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010110, 0x0001 });
addDataItem("1([1,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("1(D0.W,[1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("1([])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010010, 0x0001 });
addDataItem("1([1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11100010, 0x0001, 0x0001 });
// Absolute short addressing
// - without parentheses, with explicit size specification
addDataItem("0.W", new short[] { 0b111000, 0x0000 });
addDataItem("0.w", new short[] { 0b111000, 0x0000 });
addDataItem("$FFFFFFFF.W", new short[] { 0b111000, -0x0001 });
addDataItem("-1.W", new short[] { 0b111000, -0x0001 });
addDataItem("2+2.W", new short[] { 0b111000, 0x0004 });
// - with parentheses, without explicit size specification
addDataItem("(0)", new short[] { 0b111000, 0x0000 });
addDataItem("($FFFFFFFF)", new short[] { 0b111000, -0x0001 });
addDataItem("(-1)", new short[] { 0b111000, -0x0001 });
// - without parentheses or explicit size specification
addDataItem("0", new short[] { 0b111000, 0x0000 });
addDataItem("$FFFFFFFF", new short[] { 0b111000, -0x0001 });
addDataItem("-1", new short[] { 0b111000, -0x0001 });
// Absolute long addressing
// - without parentheses, with explicit size specification
addDataItem("0.L", new short[] { 0b111001, 0x0000, 0x0000 });
addDataItem("0.l", new short[] { 0b111001, 0x0000, 0x0000 });
addDataItem("$8000.L", new short[] { 0b111001, 0x0000, (short) 0x8000 });
addDataItem("$FFFF7FFF.L", new short[] { 0b111001, (short) 0xFFFF, 0x7FFF });
addDataItem("$FFFFFFFF.L", new short[] { 0b111001, (short) 0xFFFF, (short) 0xFFFF });
addDataItem("-1.L", new short[] { 0b111001, (short) 0xFFFF, (short) 0xFFFF });
addDataItem("2+2.L", new short[] { 0b111001, 0x0000, 0x0004 });
// - with parentheses, without explicit size specification
addDataItem("($8000)", new short[] { 0b111001, 0x0000, (short) 0x8000 });
addDataItem("($FFFF7FFF)", new short[] { 0b111001, (short) 0xFFFF, 0x7FFF });
// - without parentheses or explicit size specification
addDataItem("$8000", new short[] { 0b111001, 0x0000, (short) 0x8000 });
addDataItem("$FFFF7FFF", new short[] { 0b111001, (short) 0xFFFF, 0x7FFF });
// Program counter indirect with displacement
// - MRI syntax
addDataItem("0(PC)", new short[] { 0b111010, -0x0002 });
addDataItem("1(PC)", new short[] { 0b111010, -0x0001 });
addDataItem("2(PC)", new short[] { 0b111010, 0x0000 });
addDataItem("3(PC)", new short[] { 0b111010, 0x0001 });
addDataItem("$8001(PC)", new short[] { 0b111010, 0x7FFF });
addDataItem("$FFFF8002(PC)", new short[] { 0b111010, -0x8000 });
addDataItem("1(PC)", new short[] { 0b111010, -0x0001 });
addDataItem("-$7FFE(PC)", new short[] { 0b111010, -0x8000 });
addDataItem("-1(PC)", new short[] { 0b111010, -0x0003 });
// - reordered parts
addDataItem("(PC,1)", new short[] { 0b111010, -0x0001 });
// Program counter indirect with index (8-bit displacement)
// - MRI syntax
addDataItem("0(PC,D0)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("0(PC,A7.L)", new short[] { 0b111011, (short) 0b11111000_11111110 });
addDataItem("$81(PC,D0)", new short[] { 0b111011, 0b00000000_01111111 });
addDataItem("$FFFFFF82(PC,D0)", new short[] { 0b111011, 0b00000000_10000000 });
addDataItem("1(PC,D0)", new short[] { 0b111011, 0b00000000_11111111 });
addDataItem("-$7E(PC,D0)", new short[] { 0b111011, 0b00000000_10000000 });
addDataItem("1(PC,D0)", new short[] { 0b111011, 0b00000000_11111111 });
addDataItem("1(PC,A7.L)", new short[] { 0b111011, (short) 0b11111000_11111111 });
addDataItem("1(PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111110_11111111 });
addDataItem("1(PC,A7.L*8)", InstructionSet.MC68020, new short[] { 0b111011, (short) 0b11111110_11111111 });
// - reordered parts
addDataItem("(D0,PC)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(A0,PC)", new short[] { 0b111011, (short) 0b10000000_11111110 });
addDataItem("(D0,PC,0)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(D0,0,PC)", new short[] { 0b111011, 0b00000000_11111110 });
// - MRI syntax + reordered parts
addDataItem("0(D0,PC)", new short[] { 0b111011, 0b00000000_11111110 });
// Program counter indirect with index (base displacement)
// - MRI syntax
addDataItem("$82(PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$82(PC,D0.W)", InstructionSet.MC68020, new short[] { 0b111011, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$82(PC,D0.W*1)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_00100000, 0x0080 });
addDataItem("$82(PC,D0.W*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000111_00100000, 0x0080 });
addDataItem("$82(PC,A7.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11110001_00100000, 0x0080 });
addDataItem("$8001(PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_00100000, 0x7FFF });
addDataItem("$8002(PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_00110000, 0x0000,
(short) 0x8000 });
addDataItem("$FFFF8001(PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("-$7F(PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_00100000, -0x0081 });
addDataItem("-$7FFF(PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("$10002(PC)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_01110000, 0x0001, 0x0000 });
addDataItem("3(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, 0x0001 });
addDataItem("3(ZPC,D0.W*8)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000111_10100000, 0x0001 });
addDataItem("$8001(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, 0x7FFF });
addDataItem("$FFFF8002(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x8000 });
addDataItem("1(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x0001 });
addDataItem("-$7FFE(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_10100000, -0x8000 });
addDataItem("1(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_10100000, -1 });
addDataItem("1(ZPC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_10100000, -1 });
addDataItem("$8002(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10110000, 0x0000,
(short) 0x8000 });
addDataItem("$FFFF8001(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10110000, (short) 0xFFFF,
0x7FFF });
addDataItem("$FFFF8001(ZPC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_10110000,
(short) 0xFFFF, 0x7FFF });
// - reordered parts
addDataItem("($82,D0.W,PC)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00100000, 0x0080 });
addDataItem("(D0.W,PC,$82)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00100000, 0x0080 });
addDataItem("(D0.W,ZPC)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x0002 });
addDataItem("(A0,ZPC)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b10000001_10100000, -0x0002 });
addDataItem("(ZPC,3,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, 0x0001 });
addDataItem("(ZPC,D0.W,3)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, 0x0001 });
// - MRI syntax + reordered parts
addDataItem("$82(D0.W,PC)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00100000, 0x0080 });
addDataItem("3(D0.W,ZPC)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, 0x0001 });
// Program counter memory indirect
// - MRI syntax
addDataItem("1([PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, -0x0002, 0x0001 });
addDataItem("$10000([PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100011, -0x0002, 0x0001,
0x0000 });
addDataItem("1([PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, -0x0002, 0x0001 });
addDataItem("$10000([PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100111, -0x0002, 0x0001,
0x0000 });
addDataItem("1([3,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("$10000([3,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100011, 0x0001, 0x0001,
0x0000 });
addDataItem("1([3,PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("$10000([3,PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100111, 0x0001, 0x0001,
0x0000 });
addDataItem("1([$10002,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110010, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10002,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([$10002,PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110110, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10002,PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, -0x0002, 0x0001 });
addDataItem("$10000([PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100011, -0x0002, 0x0001,
0x0000 });
addDataItem("1([3,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("$10000([3,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100011, 0x0001, 0x0001,
0x0000 });
addDataItem("1([$10002,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01110010, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10002,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01110011, 0x0001, 0x0000,
0x0001, 0x0000 });
addDataItem("1([ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, -0x0002, 0x0001 });
addDataItem("$10000([ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100011, -0x0002, 0x0001,
0x0000 });
addDataItem("1([ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, -0x0002, 0x0001 });
addDataItem("$10000([ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100111, -0x0002, 0x0001,
0x0000 });
addDataItem("1([3,ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("$10000([3,ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100011, 0x0001,
0x0001, 0x0000 });
addDataItem("1([3,ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("$10000([3,ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100111, 0x0001,
0x0001, 0x0000 });
addDataItem("1([$10002,ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110010, 0x0001,
0x0000, 0x0001 });
addDataItem("$10000([$10002,ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([$10002,ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110110, 0x0001,
0x0000, 0x0001 });
addDataItem("$10000([$10002,ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("1([ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, -0x0002, 0x0001 });
addDataItem("$10000([ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100011, -0x0002, 0x0001,
0x0000 });
addDataItem("1([3,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, 0x0001, 0x0001 });
addDataItem("$10000([3,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100011, 0x0001, 0x0001,
0x0000 });
addDataItem("1([$10002,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11110010, 0x0001, 0x0000,
0x0001 });
addDataItem("$10000([$10002,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11110011, 0x0001,
0x0000, 0x0001, 0x0000 });
// - reordered parts
addDataItem("([D0.W,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100001, -0x0002 });
addDataItem("([D0.W,PC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, -0x0002, 0x0001 });
addDataItem("(D0.W,[PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100101, -0x0002 });
addDataItem("([PC,D0.W,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100001, 0x0001 });
addDataItem("([D0.W,PC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100001, 0x0001 });
addDataItem("(1,[3,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("(1,[3,D0.W,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("([PC,3],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100101, 0x0001 });
addDataItem("(D0.W,[PC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100101, 0x0001 });
addDataItem("(D0.W,1,[3,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("(D0.W,[3,PC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("(1,[PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, -0x0002, 0x0001 });
addDataItem("([PC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100001, 0x0001 });
addDataItem("(1,[PC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("([D0.W,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100001, -0x0002 });
addDataItem("(1,[D0.W,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, -0x0002, 0x0001 });
addDataItem("(D0.W,[ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100101, -0x0002 });
addDataItem("(D0.W,[ZPC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, -0x0002, 0x0001 });
addDataItem("([ZPC,3,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100001, 0x0001 });
addDataItem("(1,[3,D0.W,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("(D0.W,[ZPC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100101, 0x0001 });
addDataItem("(1,D0.W,[3,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("(1,[ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, -0x0002, 0x0001 });
addDataItem("([ZPC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100001, 0x0001 });
addDataItem("(1,[ZPC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, 0x0001, 0x0001 });
// - MRI syntax + reordered parts
addDataItem("1([D0.W,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, -0x0002, 0x0001 });
addDataItem("1([3,D0.W,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("1([D0.W,3,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("1(D0.W,[3,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("1(D0.W,[PC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("1([PC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("1([D0.W,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, -0x0002, 0x0001 });
addDataItem("1(D0.W,[ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, -0x0002, 0x0001 });
addDataItem("1([ZPC,D0.W,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("1(D0.W,[ZPC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("1([ZPC,3])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, 0x0001, 0x0001 });
// Immediate data
// - float literal
addDataItem("#0.0", new short[] { 0b111100, 0x0000 });
// Optimizations
// - zero displacement optimization
M68KTestAssemblyContext context = new M68KTestAssemblyContext();
context.optimizeZeroDisplacement = true;
addDataItem("0(A0)", context, new short[] { 0b010000 });
addDataItem("0(a0)", context, new short[] { 0b010000 });
addDataItem("(A0,0)", context, new short[] { 0b010000 });
addDataItem("$7FFF(A0)", context, new short[] { 0b101000, 0x7FFF });
addDataItem("2(PC)", context, new short[] { 0b111010, 0x0000 });
}
@Nonnull
@Parameters
public static List<Object[]> data() {
return TEST_DATA;
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSet instructionSet, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, instructionSet, null, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @CheckForNull M68KTestAssemblyContext context, short[] words) {
TEST_DATA.add(new Object[] { new DataItem(text, AddressingModeCategory.ALL, false, instructionSize, instructionSet,
DummySymbolLookup.DEFAULT, context, words) });
}
private static void addDataItem(@Nonnull String text, @CheckForNull M68KTestAssemblyContext context, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, InstructionSet.MC68000, context, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, InstructionSet.MC68000, null, words);
}
public ExtendedSyntaxTest(@Nonnull DataItem data) {
super(data);
}
}
@RunWith(Parameterized.class)
public static class MessageTest extends BaseTestWithOutputCheck<MessageTest.DataItem> {
public static class DataItem extends BaseTestWithOutputCheck.DataItem {
@Nonnull
final Matcher<AssemblyMessage>[] messageMatchers;
public DataItem(@Nonnull String text, boolean expectBitFieldSpecification, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @CheckForNull SymbolLookup symbolLookup,
@Nonnull Matcher<AssemblyMessage>[] messageMatchers, @Nonnull short[] words) {
super(text, AddressingModeCategory.ALL, expectBitFieldSpecification, instructionSize, instructionSet, symbolLookup,
null, words);
this.messageMatchers = messageMatchers;
}
}
@Nonnull
private static final short[] NO_WORDS = new short[0];
@Nonnull
private static final EquivalentAssemblyMessage[] SYNTAX_ERROR = new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new SyntaxErrorInEffectiveAddressErrorMessage()) };
@Nonnull
private static final ArrayList<Object[]> TEST_DATA = new ArrayList<>();
static {
SymbolLookup symbolLookup;
// Syntax errors
addDataItem("", SYNTAX_ERROR, NO_WORDS);
addDataItem("(", SYNTAX_ERROR, NO_WORDS);
addDataItem("(0", SYNTAX_ERROR, NO_WORDS);
addDataItem("(A0)-", SYNTAX_ERROR, NO_WORDS);
addDataItem("(0,0)", SYNTAX_ERROR, NO_WORDS);
addDataItem("([A0],0,0)", SYNTAX_ERROR, NO_WORDS);
addDataItem("(A0,D0.W)!", SYNTAX_ERROR, new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("([0)", SYNTAX_ERROR, NO_WORDS);
addDataItem("([0,[0]])", SYNTAX_ERROR, NO_WORDS);
addDataItem("(0])", SYNTAX_ERROR, NO_WORDS);
addDataItem("(PC,0,[A0])", SYNTAX_ERROR, NO_WORDS);
addDataItem("2+", SYNTAX_ERROR, NO_WORDS);
addDataItem("(D0)+", SYNTAX_ERROR, NO_WORDS);
addDataItem("(A0)+!", SYNTAX_ERROR, NO_WORDS);
addDataItem("((A0))+", SYNTAX_ERROR, NO_WORDS);
addDataItem("D0{1:1}", SYNTAX_ERROR, NO_WORDS);
addDataItem("D0", true, SYNTAX_ERROR, NO_WORDS);
addDataItem("#",
new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(new ExpressionExpectedErrorMessage()) },
new short[] { 0b111100, 0x0000 });
addDataItem("#0!", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new EndOfExpressionExpectedErrorMessage()) }, new short[] { 0b111100, 0x0000 });
addDataItem("$G",
new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(new InvalidTokenErrorMessage("$G")) }, NO_WORDS);
// Validations against the scale on an index register
addDataItem("(A0,D0.W*3)", InstructionSet.CPU32, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new InvalidScaleValueErrorMessage(3)) }, new short[] { 0b110000, 0b00000000_00000000 });
// Validations against the instruction set
addDataItem("(A0,D0.W*8)", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new ScaleSpecificationNotSupportedErrorMessage()) }, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("($10000,A0)", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new BaseDisplacementOutOfRangeErrorMessage()) }, new short[] { 0b101000, 0b00000000_00000000 });
addDataItem("($100,A0,D0.W)", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new BaseDisplacementOutOfRangeErrorMessage()) }, new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("($10,D0.W)", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new AddressingModeNotSupportedErrorMessage()) }, new short[] { 0b110000, 0b00000001_10100000, 0x0010 });
addDataItem("([A0])", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new AddressingModeNotSupportedErrorMessage()) }, new short[] { 0b110000, 0b00000001_01010001 });
addDataItem("([A0])", InstructionSet.CPU32, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new AddressingModeNotSupportedErrorMessage()) }, new short[] { 0b110000, 0b00000001_01010001 });
// Bound validations
addDataItem("#$100", InstructionSize.BYTE, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new ValueOutOfRangeErrorMessage(0x100)) }, new short[] { 0b111100, 0x0000 });
addDataItem("#-$81", InstructionSize.BYTE, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new ValueOutOfRangeErrorMessage(-0x81)) }, new short[] { 0b111100, 0x007F });
addDataItem("#$10000", InstructionSize.WORD, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new ValueOutOfRangeErrorMessage(0x10000)) }, new short[] { 0b111100, 0x0000 });
addDataItem("#-$8001", InstructionSize.WORD, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new ValueOutOfRangeErrorMessage(-0x8001)) }, new short[] { 0b111100, 0x7FFF });
// String length validation
addDataItem("#'ABCDE'", InstructionSize.LONG, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new StringTooLongErrorMessage("ABCDE")) }, new short[] { 0b111100, 0x4142, 0x4344 });
// Conversion of function to integer
symbolLookup = new SingleSymbolLookup("foo", ONE_FUNCTION);
addDataItem("#foo", symbolLookup, new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new FunctionCannotBeConvertedToIntegerErrorMessage()) }, new short[] { 0b111100, 0x0000 });
// Loss of precision
addDataItem("#0.5", new EquivalentAssemblyMessage[] { new EquivalentAssemblyMessage(
new LossyConversionFromRealToIntegerWarningMessage(0.5)) }, new short[] { 0b111100, 0x0000 });
}
@Nonnull
@Parameters
public static List<Object[]> data() {
return TEST_DATA;
}
private static void addDataItem(@Nonnull String text, boolean expectBitFieldSpecification,
@Nonnull InstructionSize instructionSize, @Nonnull InstructionSet instructionSet,
@CheckForNull SymbolLookup symbolLookup, @Nonnull Matcher<AssemblyMessage>[] messageMatchers, @Nonnull short[] words) {
TEST_DATA.add(new Object[] { new DataItem(text, expectBitFieldSpecification, instructionSize, instructionSet,
symbolLookup, messageMatchers, words) });
}
private static void addDataItem(@Nonnull String text, boolean expectBitFieldSpecification,
@Nonnull Matcher<AssemblyMessage>[] messageMatchers, @Nonnull short[] words) {
addDataItem(text, expectBitFieldSpecification, InstructionSize.DEFAULT, InstructionSet.MC68000, null, messageMatchers,
words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSet instructionSet,
@Nonnull Matcher<AssemblyMessage>[] messageMatchers, @Nonnull short[] words) {
addDataItem(text, false, InstructionSize.DEFAULT, instructionSet, null, messageMatchers, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSize instructionSize,
@Nonnull EquivalentAssemblyMessage[] messageMatchers, @Nonnull short[] words) {
addDataItem(text, false, instructionSize, InstructionSet.MC68000, null, messageMatchers, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull Matcher<AssemblyMessage>[] messageMatchers,
@Nonnull short[] words) {
addDataItem(text, false, InstructionSize.DEFAULT, InstructionSet.MC68000, null, messageMatchers, words);
}
private static void addDataItem(@Nonnull String text, @CheckForNull SymbolLookup symbolLookup,
@Nonnull EquivalentAssemblyMessage[] messageMatchers, @Nonnull short[] words) {
addDataItem(text, false, InstructionSize.DEFAULT, InstructionSet.MC68000, symbolLookup, messageMatchers, words);
}
public MessageTest(@Nonnull DataItem data) {
super(data);
}
@Override
protected void checkMessages(ArrayList<AssemblyMessage> messages) {
assertThat(messages, contains(this.data.messageMatchers));
}
}
@RunWith(Parameterized.class)
public static class RegisterAliasTest extends BaseSuccessfulTest {
@Nonnull
private static final ArrayList<Object[]> TEST_DATA = new ArrayList<>();
static {
M68KTestAssemblyContext context;
context = new M68KTestAssemblyContext();
context.registerAliases.put("foo", GeneralPurposeRegister.D0);
addDataItem("foo", context, new short[] { 0b000000 });
addDataItem("(foo)", InstructionSet.CPU32, context, new short[] { 0b110000, 0b00000001_10010000 });
addDataItem("(foo.W)", InstructionSet.CPU32, context, new short[] { 0b110000, 0b00000001_10010000 });
addDataItem("(foo.w)", InstructionSet.CPU32, context, new short[] { 0b110000, 0b00000001_10010000 });
addDataItem("(foo.L)", InstructionSet.CPU32, context, new short[] { 0b110000, 0b00001001_10010000 });
addDataItem("(foo.L)", InstructionSet.CPU32, context, new short[] { 0b110000, 0b00001001_10010000 });
context = new M68KTestAssemblyContext();
context.registerAliases.put("foo", GeneralPurposeRegister.A0);
addDataItem("foo", context, new short[] { 0b001000 });
addDataItem("(foo)", InstructionSet.CPU32, context, new short[] { 0b010000 });
addDataItem("(foo.W)", InstructionSet.CPU32, context, new short[] { 0b110000, (short) 0b10000001_10010000 });
addDataItem("(foo.w)", InstructionSet.CPU32, context, new short[] { 0b110000, (short) 0b10000001_10010000 });
addDataItem("(foo.L)", InstructionSet.CPU32, context, new short[] { 0b110000, (short) 0b10001001_10010000 });
addDataItem("(foo.L)", InstructionSet.CPU32, context, new short[] { 0b110000, (short) 0b10001001_10010000 });
context = new M68KTestAssemblyContext();
context.registerAliases.put("sx", GeneralPurposeRegister.A6);
addDataItem("sx", context, new short[] { 0b001110 });
}
@Nonnull
@Parameters
public static List<Object[]> data() {
return TEST_DATA;
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSet instructionSet,
@Nonnull M68KTestAssemblyContext context, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, instructionSet, context, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @Nonnull M68KTestAssemblyContext context, @Nonnull short[] words) {
TEST_DATA.add(new Object[] { new DataItem(text, AddressingModeCategory.ALL, false, instructionSize, instructionSet,
DummySymbolLookup.DEFAULT, context, words) });
}
private static void addDataItem(@Nonnull String text, @Nonnull M68KTestAssemblyContext context, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, InstructionSet.MC68000, context, words);
}
public RegisterAliasTest(@Nonnull DataItem data) {
super(data);
}
}
@RunWith(Parameterized.class)
public static class StandardSyntaxTest extends BaseSuccessfulTest {
@Nonnull
private static final ArrayList<Object[]> TEST_DATA = new ArrayList<>();
static {
// Data register direct
addDataItem("D0", new short[] { 0b000000 });
addDataItem("D1", new short[] { 0b000001 });
addDataItem("D2", new short[] { 0b000010 });
addDataItem("D3", new short[] { 0b000011 });
addDataItem("D4", new short[] { 0b000100 });
addDataItem("D5", new short[] { 0b000101 });
addDataItem("D6", new short[] { 0b000110 });
addDataItem("D7", new short[] { 0b000111 });
addDataItem("d0", new short[] { 0b000000 });
// Address register direct
addDataItem("A0", new short[] { 0b001000 });
addDataItem("A1", new short[] { 0b001001 });
addDataItem("A2", new short[] { 0b001010 });
addDataItem("A3", new short[] { 0b001011 });
addDataItem("A4", new short[] { 0b001100 });
addDataItem("A5", new short[] { 0b001101 });
addDataItem("A6", new short[] { 0b001110 });
addDataItem("A7", new short[] { 0b001111 });
addDataItem("a0", new short[] { 0b001000 });
addDataItem("SP", new short[] { 0b001111 });
addDataItem("sp", new short[] { 0b001111 });
// Address register indirect
addDataItem("(A0)", new short[] { 0b010000 });
addDataItem("(A7)", new short[] { 0b010111 });
addDataItem("(A0)", EnumSet.of(AddressingMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT), new short[] { 0b101000,
0x0000 });
addDataItem("(A7)", EnumSet.of(AddressingMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT), new short[] { 0b101111,
0x0000 });
// Address register indirect with postincrement
addDataItem("(A0)+", new short[] { 0b011000 });
addDataItem("(A7)+", new short[] { 0b011111 });
// Address register indirect with predecrement
addDataItem("-(A0)", new short[] { 0b100000 });
addDataItem("-(A7)", new short[] { 0b100111 });
// Address register indirect with displacement
addDataItem("(0,A0)", new short[] { 0b101000, 0x0000 });
addDataItem("(0,A7)", new short[] { 0b101111, 0x0000 });
addDataItem("($7FFF,A0)", new short[] { 0b101000, 0x7FFF });
addDataItem("($FFFF8000,A0)", new short[] { 0b101000, -0x8000 });
addDataItem("($FFFFFFFF,A0)", new short[] { 0b101000, -0x0001 });
addDataItem("(-$8000,A0)", new short[] { 0b101000, -0x8000 });
addDataItem("(-1,A0)", new short[] { 0b101000, -1 });
addDataItem("(-1,A7)", new short[] { 0b101111, -1 });
// Address register indirect with index (8-bit displacement)
addDataItem("(A0,D0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,d0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,D0.W)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,D0.w)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,d0.W)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,d0.w)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,D0.L)", new short[] { 0b110000, 0b00001000_00000000 });
addDataItem("(A0,D0.l)", new short[] { 0b110000, 0b00001000_00000000 });
addDataItem("(A0,d0.L)", new short[] { 0b110000, 0b00001000_00000000 });
addDataItem("(A0,d0.l)", new short[] { 0b110000, 0b00001000_00000000 });
addDataItem("(A0,D0.W*1)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(A0,D0.W*2)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000010_00000000 });
addDataItem("(A0,D0.W*4)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000100_00000000 });
addDataItem("(A0,D0.W*8)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("(A0,D0.W * 8)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("(A0,D0.W*8)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000110_00000000 });
addDataItem("(A0,D1)", new short[] { 0b110000, 0b00010000_00000000 });
addDataItem("(A0,D2)", new short[] { 0b110000, 0b00100000_00000000 });
addDataItem("(A0,D4)", new short[] { 0b110000, 0b01000000_00000000 });
addDataItem("(A0,D6)", new short[] { 0b110000, 0b01100000_00000000 });
addDataItem("(A0,D7)", new short[] { 0b110000, 0b01110000_00000000 });
addDataItem("(A0,A0)", new short[] { 0b110000, (short) 0b10000000_00000000 });
addDataItem("(A0,A0.W)", new short[] { 0b110000, (short) 0b10000000_00000000 });
addDataItem("(A0,A0.w)", new short[] { 0b110000, (short) 0b10000000_00000000 });
addDataItem("(A0,a0.W)", new short[] { 0b110000, (short) 0b10000000_00000000 });
addDataItem("(A0,a0.w)", new short[] { 0b110000, (short) 0b10000000_00000000 });
addDataItem("(A0,A0.L)", new short[] { 0b110000, (short) 0b10001000_00000000 });
addDataItem("(A0,A0.l)", new short[] { 0b110000, (short) 0b10001000_00000000 });
addDataItem("(A0,a0.L)", new short[] { 0b110000, (short) 0b10001000_00000000 });
addDataItem("(A0,a0.l)", new short[] { 0b110000, (short) 0b10001000_00000000 });
addDataItem("(A0,A1)", new short[] { 0b110000, (short) 0b10010000_00000000 });
addDataItem("(A0,A2)", new short[] { 0b110000, (short) 0b10100000_00000000 });
addDataItem("(A0,A4)", new short[] { 0b110000, (short) 0b11000000_00000000 });
addDataItem("(A0,A6)", new short[] { 0b110000, (short) 0b11100000_00000000 });
addDataItem("(A0,A7)", new short[] { 0b110000, (short) 0b11110000_00000000 });
addDataItem("(A7,D0)", new short[] { 0b110111, 0b00000000_00000000 });
addDataItem("(A7,A7.L)", new short[] { 0b110111, (short) 0b11111000_00000000 });
addDataItem("(A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111110_00000000 });
addDataItem("(0,A0,D0)", new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(0,A0,A7.L)", new short[] { 0b110000, (short) 0b11111000_00000000 });
addDataItem("(0,A7,D0)", new short[] { 0b110111, 0b00000000_00000000 });
addDataItem("($7F,A0,D0)", new short[] { 0b110000, 0b00000000_01111111 });
addDataItem("($FFFFFF80,A0,D0)", new short[] { 0b110000, 0b00000000_10000000 });
addDataItem("($FFFFFFFF,A0,D0)", new short[] { 0b110000, 0b00000000_11111111 });
addDataItem("(-$80,A0,D0)", new short[] { 0b110000, 0b00000000_10000000 });
addDataItem("(-1,A0,D0)", new short[] { 0b110000, 0b00000000_11111111 });
addDataItem("(-1,A7,A7.L)", new short[] { 0b110111, (short) 0b11111000_11111111 });
addDataItem("(-1,A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111110_11111111 });
addDataItem("(-1,A7,A7.L*8)", InstructionSet.MC68020, new short[] { 0b110111, (short) 0b11111110_11111111 });
// Address register indirect with index (base displacement)
addDataItem("($80,A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("($80,A0,D0.W)", InstructionSet.MC68020, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("($80,A0,D0.W*1)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x0080 });
addDataItem("($80,A0,D0.W*8)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000111_00100000, 0x0080 });
addDataItem("($80,A0,A7.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b11110001_00100000, 0x0080 });
addDataItem("($80,A7,D0.W)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b00000001_00100000, 0x0080 });
addDataItem("($7FFF,A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00100000, 0x7FFF });
addDataItem("($8000,A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00110000, 0x0000,
(short) 0x8000 });
addDataItem("($FFFF7FFF,A0,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("(-$81,A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111111_00100000, -0x0081 });
addDataItem("(-$8001,A7,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110111, (short) 0b11111111_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("($10000,A0)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_01110000, 0x0001, 0x0000 });
addDataItem("(D0)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10010000 });
addDataItem("(D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10010000 });
addDataItem("(D0.W*8)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000111_10010000 });
addDataItem("(A0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b10000001_10010000 });
addDataItem("(1,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, 0x0001 });
addDataItem("(1,D0.W*8)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000111_10100000, 0x0001 });
addDataItem("($7FFF,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, 0x7FFF });
addDataItem("($FFFF8000,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, -0x8000 });
addDataItem("($FFFFFFFF,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10100000, -0x0001 });
addDataItem("(-$8000,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_10100000, -0x8000 });
addDataItem("(-1,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b00000001_10100000, -1 });
addDataItem("(-1,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b11111111_10100000, -1 });
addDataItem("($8000,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10110000, 0x0000, (short) 0x8000 });
addDataItem("($FFFF7FFF,D0.W)", InstructionSet.CPU32, new short[] { 0b110000, 0b00000001_10110000, (short) 0xFFFF,
0x7FFF });
addDataItem("($FFFF7FFF,A7.L*8)", InstructionSet.CPU32, new short[] { 0b110000, (short) 0b11111111_10110000,
(short) 0xFFFF, 0x7FFF });
// Memory indirect
addDataItem("([A0,D0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010001 });
addDataItem("([A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010001 });
addDataItem("([A0,D0.W],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010010, 0x0001 });
addDataItem("([A0,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010011, 0x0001, 0x0000 });
addDataItem("([A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010101 });
addDataItem("([A0],D0.W,1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010110, 0x0001 });
addDataItem("([A0],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00010111, 0x0001, 0x0000 });
addDataItem("([1,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100001, 0x0001 });
addDataItem("([1,A0,D0.W],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("([1,A0,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100011, 0x0001,
0x0001, 0x0000 });
addDataItem("([1,A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100101, 0x0001 });
addDataItem("([1,A0],D0.W,1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("([1,A0],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00100111, 0x0001,
0x0001, 0x0000 });
addDataItem("([$10000,A0,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110001, 0x0001, 0x0000 });
addDataItem("([$10000,A0,D0.W],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110010, 0x0001,
0x0000, 0x0001 });
addDataItem("([$10000,A0,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([$10000,A0],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110101, 0x0001, 0x0000 });
addDataItem("([$10000,A0],D0.W,1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110110, 0x0001,
0x0000, 0x0001 });
addDataItem("([$10000,A0],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_00110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010001 });
addDataItem("([A0],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010010, 0x0001 });
addDataItem("([A0],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01010011, 0x0001, 0x0000 });
addDataItem("([1,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100001, 0x0001 });
addDataItem("([1,A0],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("([1,A0],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01100011, 0x0001, 0x0001,
0x0000 });
addDataItem("([$10000,A0])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01110001, 0x0001, 0x0000 });
addDataItem("([$10000,A0],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01110010, 0x0001, 0x0000,
0x0001 });
addDataItem("([$10000,A0],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_01110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010001 });
addDataItem("([D0.W],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010010, 0x0001 });
addDataItem("([D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010011, 0x0001, 0x0000 });
addDataItem("([],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010101 });
addDataItem("([],D0.W,1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010110, 0x0001 });
addDataItem("([],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10010111, 0x0001, 0x0000 });
addDataItem("([1,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100001, 0x0001 });
addDataItem("([1,D0.W],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("([1,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100011, 0x0001, 0x0001,
0x0000 });
addDataItem("([1],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100101, 0x0001 });
addDataItem("([1],D0.W,1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("([1],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10100111, 0x0001, 0x0001,
0x0000 });
addDataItem("([$10000,D0.W])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110001, 0x0001, 0x0000 });
addDataItem("([$10000,D0.W],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110010, 0x0001, 0x0000,
0x0001 });
addDataItem("([$10000,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([$10000],D0.W)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110101, 0x0001, 0x0000 });
addDataItem("([$10000],D0.W,1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110110, 0x0001, 0x0000,
0x0001 });
addDataItem("([$10000],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_10110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010001 });
addDataItem("([],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010010, 0x0001 });
addDataItem("([],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11010011, 0x0001, 0x0000 });
addDataItem("([1])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11100001, 0x0001 });
addDataItem("([1],1)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11100010, 0x0001, 0x0001 });
addDataItem("([1],$10000)", InstructionSet.MC68020,
new short[] { 0b110000, 0b00000001_11100011, 0x0001, 0x0001, 0x0000 });
addDataItem("([$10000])", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11110001, 0x0001, 0x0000 });
addDataItem("([$10000],1)", InstructionSet.MC68020,
new short[] { 0b110000, 0b00000001_11110010, 0x0001, 0x0000, 0x0001 });
addDataItem("([$10000],$10000)", InstructionSet.MC68020, new short[] { 0b110000, 0b00000001_11110011, 0x0001, 0x0000,
0x0001, 0x0000 });
// Absolute short addressing
addDataItem("(0).W", new short[] { 0b111000, 0x0000 });
addDataItem("(0).w", new short[] { 0b111000, 0x0000 });
addDataItem("(1).W", new short[] { 0b111000, 0x0001 });
addDataItem("($7FFF).W", new short[] { 0b111000, 0x7FFF });
addDataItem("($FFFF8000).W", new short[] { 0b111000, -0x8000 });
addDataItem("($FFFFFFFF).W", new short[] { 0b111000, -0x0001 });
addDataItem("(-$8000).W", new short[] { 0b111000, -0x8000 });
addDataItem("(-1).W", new short[] { 0b111000, -0x0001 });
// Absolute long addressing
addDataItem("(0).L", new short[] { 0b111001, 0x0000, 0x0000 });
addDataItem("(0).l", new short[] { 0b111001, 0x0000, 0x0000 });
addDataItem("(1).L", new short[] { 0b111001, 0x0000, 0x0001 });
addDataItem("($7FFF).L", new short[] { 0b111001, 0x0000, 0x7FFF });
addDataItem("($8000).L", new short[] { 0b111001, 0x0000, (short) 0x8000 });
addDataItem("($10000).L", new short[] { 0b111001, 0x0001, 0x0000 });
addDataItem("($7FFFFFFF).L", new short[] { 0b111001, 0x7FFF, (short) 0xFFFF });
addDataItem("($80000000).L", new short[] { 0b111001, (short) 0x8000, 0x0000 });
addDataItem("($FFFF0000).L", new short[] { 0b111001, (short) 0xFFFF, 0x0000 });
addDataItem("($FFFF7FFF).L", new short[] { 0b111001, (short) 0xFFFF, 0x7FFF });
addDataItem("($FFFF8000).L", new short[] { 0b111001, (short) 0xFFFF, (short) 0x8000 });
addDataItem("($FFFFFFFF).L", new short[] { 0b111001, (short) 0xFFFF, (short) 0xFFFF });
addDataItem("(-$FFFFFFFF).L", new short[] { 0b111001, 0x0000, 0x0001 });
addDataItem("(-1).L", new short[] { 0b111001, (short) 0xFFFF, (short) 0xFFFF });
// Program counter indirect with displacement
addDataItem("(PC)", new short[] { 0b111010, -0x0002 });
addDataItem("(pc)", new short[] { 0b111010, -0x0002 });
addDataItem("(0,PC)", new short[] { 0b111010, -0x0002 });
addDataItem("(1,PC)", new short[] { 0b111010, -0x0001 });
addDataItem("(2,PC)", new short[] { 0b111010, 0x0000 });
addDataItem("($8001,PC)", new short[] { 0b111010, 0x7FFF });
addDataItem("($FFFF8002,PC)", new short[] { 0b111010, -0x8000 });
addDataItem("($FFFFFFFF,PC)", new short[] { 0b111010, -0x0003 });
addDataItem("(-$7FFE,PC)", new short[] { 0b111010, -0x8000 });
addDataItem("(-1,PC)", new short[] { 0b111010, -0x0003 });
// Program counter indirect with index (8-bit displacement)
addDataItem("(PC,D0)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,d0)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,D0.W)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,D0.w)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,d0.W)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,d0.w)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,D0.L)", new short[] { 0b111011, 0b00001000_11111110 });
addDataItem("(PC,D0.l)", new short[] { 0b111011, 0b00001000_11111110 });
addDataItem("(PC,d0.L)", new short[] { 0b111011, 0b00001000_11111110 });
addDataItem("(PC,d0.l)", new short[] { 0b111011, 0b00001000_11111110 });
addDataItem("(PC,D0.W*1)", new short[] { 0b111011, 0b00000000_11111110 });
addDataItem("(PC,D0.W*2)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000010_11111110 });
addDataItem("(PC,D0.W*4)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000100_11111110 });
addDataItem("(PC,D0.W*8)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000110_11111110 });
addDataItem("(PC,D0.W * 8)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000110_11111110 });
addDataItem("(PC,D0.W*8)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000110_11111110 });
addDataItem("(PC,D7)", new short[] { 0b111011, 0b01110000_11111110 });
addDataItem("(PC,A0)", new short[] { 0b111011, (short) 0b10000000_11111110 });
addDataItem("(PC,A7)", new short[] { 0b111011, (short) 0b11110000_11111110 });
addDataItem("(PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111110_11111110 });
addDataItem("(2,PC,D0)", new short[] { 0b111011, 0b00000000_00000000 });
addDataItem("(2,PC,A7.L)", new short[] { 0b111011, (short) 0b11111000_00000000 });
addDataItem("($81,PC,D0)", new short[] { 0b111011, 0b00000000_01111111 });
addDataItem("($FFFFFF82,PC,D0)", new short[] { 0b111011, 0b00000000_10000000 });
addDataItem("(1,PC,D0)", new short[] { 0b111011, 0b00000000_11111111 });
addDataItem("(-$7E,PC,D0)", new short[] { 0b111011, 0b00000000_10000000 });
addDataItem("(1,PC,D0)", new short[] { 0b111011, 0b00000000_11111111 });
addDataItem("(1,PC,A7.L)", new short[] { 0b111011, (short) 0b11111000_11111111 });
addDataItem("(1,PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111110_11111111 });
addDataItem("(1,PC,A7.L*8)", InstructionSet.MC68020, new short[] { 0b111011, (short) 0b11111110_11111111 });
// Program counter indirect with index (base displacement)
addDataItem("($82,PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00100000, 0x0080 });
addDataItem("($82,PC,D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100000, 0x0080 });
addDataItem("($82,PC,D0.W*1)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00100000, 0x0080 });
addDataItem("($82,PC,D0.W*8)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000111_00100000, 0x0080 });
addDataItem("($82,PC,A7.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11110001_00100000, 0x0080 });
addDataItem("($8001,PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00100000, 0x7FFF });
addDataItem("($8002,PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00110000, 0x0000,
(short) 0x8000 });
addDataItem("($FFFF8001,PC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_00110000, (short) 0xFFFF,
0x7FFF });
addDataItem("(-$7F,PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_00100000, -0x0081 });
addDataItem("(-$7FFF,PC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_00110000,
(short) 0xFFFF, 0x7FFF });
addDataItem("($10002,PC)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b00000001_01110000, 0x0001, 0x0000 });
addDataItem("(ZPC)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_11100000, -0x0002 });
addDataItem("(zpc)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_11100000, -0x0002 });
addDataItem("(ZPC,D0)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x0002 });
addDataItem("(ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x0002 });
addDataItem("(ZPC,D0.W*8)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000111_10100000, -0x0002 });
addDataItem("(ZPC,A0)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b10000001_10100000, -0x0002 });
addDataItem("(ZPC,A0.W)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b10000001_10100000, -0x0002 });
addDataItem("(2,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10010000 });
addDataItem("(2,ZPC,D0.W*8)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000111_10010000 });
addDataItem("($8001,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, 0x7FFF });
addDataItem("($FFFF8002,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x8000 });
addDataItem("(1,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x0001 });
addDataItem("(-$7FFE,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10100000, -0x8000 });
addDataItem("(1,ZPC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_10100000, -1 });
addDataItem("($8002,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10110000, 0x0000,
(short) 0x8000 });
addDataItem("($FFFF8001,ZPC,D0.W)", InstructionSet.CPU32, new short[] { 0b111011, 0b00000001_10110000, (short) 0xFFFF,
0x7FFF });
addDataItem("($FFFF8001,ZPC,A7.L*8)", InstructionSet.CPU32, new short[] { 0b111011, (short) 0b11111111_10110000,
(short) 0xFFFF, 0x7FFF });
// Program counter memory indirect
addDataItem("([PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100001, -0x0002 });
addDataItem("([PC,D0.W],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, -0x0002, 0x0001 });
addDataItem("([PC,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100011, -0x0002, 0x0001,
0x0000 });
addDataItem("([PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100101, -0x0002 });
addDataItem("([PC],D0.W,1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, -0x0002, 0x0001 });
addDataItem("([PC],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100111, -0x0002, 0x0001,
0x0000 });
addDataItem("([3,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100001, 0x0001 });
addDataItem("([3,PC,D0.W],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100010, 0x0001, 0x0001 });
addDataItem("([3,PC,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100011, 0x0001,
0x0001, 0x0000 });
addDataItem("([3,PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100101, 0x0001 });
addDataItem("([3,PC],D0.W,1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100110, 0x0001, 0x0001 });
addDataItem("([3,PC],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00100111, 0x0001,
0x0001, 0x0000 });
addDataItem("([$10002,PC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110001, 0x0001, 0x0000 });
addDataItem("([$10002,PC,D0.W],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110010, 0x0001,
0x0000, 0x0001 });
addDataItem("([$10002,PC,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([$10002,PC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110101, 0x0001, 0x0000 });
addDataItem("([$10002,PC],D0.W,1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110110, 0x0001,
0x0000, 0x0001 });
addDataItem("([$10002,PC],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_00110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100001, -0x0002 });
addDataItem("([PC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, -0x0002, 0x0001 });
addDataItem("([PC],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100011, -0x0002, 0x0001,
0x0000 });
addDataItem("([3,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100001, 0x0001 });
addDataItem("([3,PC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100010, 0x0001, 0x0001 });
addDataItem("([3,PC],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01100011, 0x0001, 0x0001,
0x0000 });
addDataItem("([$10002,PC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01110001, 0x0001, 0x0000 });
addDataItem("([$10002,PC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01110010, 0x0001, 0x0000,
0x0001 });
addDataItem("([$10002,PC],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_01110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100001, -0x0002 });
addDataItem("([ZPC,D0.W],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, -0x0002, 0x0001 });
addDataItem("([ZPC,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100011, -0x0002,
0x0001, 0x0000 });
addDataItem("([ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100101, -0x0002 });
addDataItem("([ZPC],D0.W,1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, -0x0002, 0x0001 });
addDataItem("([ZPC],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100111, -0x0002,
0x0001, 0x0000 });
addDataItem("([3,ZPC,D0.W])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100001, 0x0001 });
addDataItem("([3,ZPC,D0.W],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100010, 0x0001, 0x0001 });
addDataItem("([3,ZPC,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100011, 0x0001,
0x0001, 0x0000 });
addDataItem("([3,ZPC],D0.W)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100101, 0x0001 });
addDataItem("([3,ZPC],D0.W,1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100110, 0x0001, 0x0001 });
addDataItem("([3,ZPC],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10100111, 0x0001,
0x0001, 0x0000 });
addDataItem("([$10002,ZPC,D0.W])", InstructionSet.MC68020,
new short[] { 0b111011, 0b00000001_10110001, 0x0001, 0x0000 });
addDataItem("([$10002,ZPC,D0.W],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110010, 0x0001,
0x0000, 0x0001 });
addDataItem("([$10002,ZPC,D0.W],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110011, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([$10002,ZPC],D0.W)", InstructionSet.MC68020,
new short[] { 0b111011, 0b00000001_10110101, 0x0001, 0x0000 });
addDataItem("([$10002,ZPC],D0.W,1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110110, 0x0001,
0x0000, 0x0001 });
addDataItem("([$10002,ZPC],D0.W,$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_10110111, 0x0001,
0x0000, 0x0001, 0x0000 });
addDataItem("([ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100001, -0x0002 });
addDataItem("([ZPC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, -0x0002, 0x0001 });
addDataItem("([ZPC],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100011, -0x0002, 0x0001,
0x0000 });
addDataItem("([3,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100001, 0x0001 });
addDataItem("([3,ZPC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100010, 0x0001, 0x0001 });
addDataItem("([3,ZPC],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11100011, 0x0001, 0x0001,
0x0000 });
addDataItem("([$10002,ZPC])", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11110001, 0x0001, 0x0000 });
addDataItem("([$10002,ZPC],1)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11110010, 0x0001, 0x0000,
0x0001 });
addDataItem("([$10002,ZPC],$10000)", InstructionSet.MC68020, new short[] { 0b111011, 0b00000001_11110011, 0x0001,
0x0000, 0x0001, 0x0000 });
// Immediate
// - byte instruction size
addDataItem("#0", InstructionSize.BYTE, new short[] { 0b111100, 0x0000 });
addDataItem("#1", InstructionSize.BYTE, new short[] { 0b111100, 0x0001 });
addDataItem("#$7F", InstructionSize.BYTE, new short[] { 0b111100, 0x007F });
addDataItem("#$80", InstructionSize.BYTE, new short[] { 0b111100, 0x0080 });
addDataItem("#$FF", InstructionSize.BYTE, new short[] { 0b111100, 0x00FF });
addDataItem("#$FFFFFF80", InstructionSize.BYTE, new short[] { 0b111100, 0x0080 });
addDataItem("#$FFFFFFFF", InstructionSize.BYTE, new short[] { 0b111100, 0x00FF });
addDataItem("#-$80", InstructionSize.BYTE, new short[] { 0b111100, 0x0080 });
addDataItem("#-1", InstructionSize.BYTE, new short[] { 0b111100, 0x00FF });
addDataItem("#'A'", InstructionSize.BYTE, new short[] { 0b111100, 0x0041 });
// - word instruction size
addDataItem("#0", InstructionSize.WORD, new short[] { 0b111100, 0x0000 });
addDataItem("#1", InstructionSize.WORD, new short[] { 0b111100, 0x0001 });
addDataItem("#$7FFF", InstructionSize.WORD, new short[] { 0b111100, 0x7FFF });
addDataItem("#$8000", InstructionSize.WORD, new short[] { 0b111100, (short) 0x8000 });
addDataItem("#$FFFF", InstructionSize.WORD, new short[] { 0b111100, (short) 0xFFFF });
addDataItem("#$FFFF8000", InstructionSize.WORD, new short[] { 0b111100, (short) 0x8000 });
addDataItem("#$FFFFFFFF", InstructionSize.WORD, new short[] { 0b111100, (short) 0xFFFF });
addDataItem("#-$8000", InstructionSize.WORD, new short[] { 0b111100, (short) 0x8000 });
addDataItem("#-1", InstructionSize.WORD, new short[] { 0b111100, (short) 0xFFFF });
addDataItem("#'A'", InstructionSize.WORD, new short[] { 0b111100, 0x0041 });
addDataItem("#'AB'", InstructionSize.WORD, new short[] { 0b111100, 0x4142 });
// - long instruction size
addDataItem("#0", InstructionSize.LONG, new short[] { 0b111100, 0x0000, 0x0000 });
addDataItem("#1", InstructionSize.LONG, new short[] { 0b111100, 0x0000, 0x0001 });
addDataItem("#$7FFFFFFF", InstructionSize.LONG, new short[] { 0b111100, 0x7FFF, (short) 0xFFFF });
addDataItem("#$80000000", InstructionSize.LONG, new short[] { 0b111100, (short) 0x8000, 0x0000 });
addDataItem("#$FFFFFFFF", InstructionSize.LONG, new short[] { 0b111100, (short) 0xFFFF, (short) 0xFFFF });
addDataItem("#-$80000000", InstructionSize.LONG, new short[] { 0b111100, (short) 0x8000, 0x0000 });
addDataItem("#-1", InstructionSize.LONG, new short[] { 0b111100, (short) 0xFFFF, (short) 0xFFFF });
addDataItem("#'ABC'", InstructionSize.LONG, new short[] { 0b111100, 0x0041, 0x4243 });
addDataItem("#'ABCD'", InstructionSize.LONG, new short[] { 0b111100, 0x4142, 0x4344 });
// Optimizations
M68KTestAssemblyContext context;
// - zero displacement optimization
context = new M68KTestAssemblyContext();
context.optimizeZeroDisplacement = true;
addDataItem("(0,A0)", context, new short[] { 0b010000 });
addDataItem("(0,A0)", EnumSet.of(AddressingMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT), context, new short[] {
0b101000, 0x0000 });
addDataItem("($7FFF,A0)", context, new short[] { 0b101000, 0x7FFF });
addDataItem("(2,PC)", context, new short[] { 0b111010, 0x0000 });
// - optimizeUnsizedAbsoluteAddressingToPcRelative
context = new M68KTestAssemblyContext();
context.optimizeUnsizedAbsoluteAddressingToPcRelative = true;
context.programCounter = 0x40000;
addDataItem("$38000", context, new short[] { 0b111001, 0x0003, (short) 0x8000 });
addDataItem("$38002", context, new short[] { 0b111010, -0x8000 });
addDataItem("$40000", context, new short[] { 0b111010, -0x0002 });
addDataItem("$40000", AddressingModeCategory.ALTERABLE, context, new short[] { 0b111001, 0x0004, 0x0000 });
addDataItem("$40002", context, new short[] { 0b111010, 0x0000 });
addDataItem("$48001", context, new short[] { 0b111010, 0x7FFF });
addDataItem("$48002", context, new short[] { 0b111001, 0x0004, (short) 0x8002 });
// With bit field specification
addDataItem("D0{1:1}", true, new short[] { 0b000000 });
}
@Nonnull
@Parameters
public static List<Object[]> data() {
return TEST_DATA;
}
private static void addDataItem(@Nonnull String text, boolean expectBitFieldSpecification, @Nonnull short[] words) {
addDataItem(text, AddressingModeCategory.ALL, expectBitFieldSpecification, InstructionSize.DEFAULT,
InstructionSet.MC68000, null, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSet instructionSet, @Nonnull short[] words) {
addDataItem(text, AddressingModeCategory.ALL, false, InstructionSize.DEFAULT, instructionSet, null, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSize instructionSize, @Nonnull short[] words) {
addDataItem(text, AddressingModeCategory.ALL, false, instructionSize, InstructionSet.MC68000, null, words);
}
private static void addDataItem(@Nonnull String text, @CheckForNull M68KTestAssemblyContext context, @Nonnull short[] words) {
addDataItem(text, AddressingModeCategory.ALL, false, InstructionSize.DEFAULT, InstructionSet.MC68000, context, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull Set<AddressingMode> validAddressingModes,
boolean expectBitFieldSpecification, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @CheckForNull M68KTestAssemblyContext context, @Nonnull short[] words) {
TEST_DATA.add(new Object[] { new DataItem(text, validAddressingModes, expectBitFieldSpecification, instructionSize,
instructionSet, DummySymbolLookup.DEFAULT, context, words) });
}
private static void addDataItem(@Nonnull String text, @Nonnull Set<AddressingMode> validAddressingModes,
@CheckForNull M68KTestAssemblyContext context, @Nonnull short[] words) {
addDataItem(text, validAddressingModes, false, InstructionSize.DEFAULT, InstructionSet.MC68000, context, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull Set<AddressingMode> validAddressingModes,
@Nonnull short[] words) {
addDataItem(text, validAddressingModes, false, InstructionSize.DEFAULT, InstructionSet.MC68000, null, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull short[] words) {
addDataItem(text, AddressingModeCategory.ALL, false, InstructionSize.DEFAULT, InstructionSet.MC68000, null, words);
}
public StandardSyntaxTest(@Nonnull DataItem data) {
super(data);
}
}
@RunWith(Parameterized.class)
public static class SymbolTest extends BaseSuccessfulTest {
@Nonnull
private static final ArrayList<Object[]> TEST_DATA = new ArrayList<>();
static {
SymbolLookup symbolLookup;
symbolLookup = new SingleSymbolLookup("foo", ONE);
addDataItem("(foo).W", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("(foo).w", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("(foo).L", symbolLookup, new short[] { 0b111001, 0x0000, 0x0001 });
addDataItem("(foo).L", symbolLookup, new short[] { 0b111001, 0x0000, 0x0001 });
addDataItem("(foo)", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("foo.W", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("foo.w", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("foo.L", symbolLookup, new short[] { 0b111001, 0x0000, 0x0001 });
addDataItem("foo.l", symbolLookup, new short[] { 0b111001, 0x0000, 0x0001 });
addDataItem("foo", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("#foo", symbolLookup, new short[] { 0b111100, 0x0001 });
addDataItem("~foo", symbolLookup, new short[] { 0b111000, ~0x0001 });
addDataItem("-(foo)", symbolLookup, new short[] { 0b111000, -0x0001 });
addDataItem("(foo*1)", symbolLookup, new short[] { 0b111000, 0x0001 });
symbolLookup = new SingleSymbolLookup("foo", UNDEFINED);
addDataItem("foo", symbolLookup, new short[] { 0b111000, 0x0000 });
addDataItem("#foo", symbolLookup, new short[] { 0b111100, 0x0000 });
addDataItem("(A0,D0.W*foo)", InstructionSet.CPU32, symbolLookup, new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("(foo,A0,D0.W)", symbolLookup, new short[] { 0b110000, 0b00000000_00000000 });
addDataItem("([A0],foo)", InstructionSet.MC68020, symbolLookup, new short[] { 0b110000, 0b00000001_01010001 });
symbolLookup = new SingleSymbolLookup("D0", ONE);
addDataItem("#D0", symbolLookup, new short[] { 0b111100, 0x0001 });
addDataItem("(D0+1)", symbolLookup, new short[] { 0b111000, 0x0002 });
addDataItem("(D0,D0)", InstructionSet.CPU32, symbolLookup, new short[] { 0b110000, 0b00000001_10100000, 0x0001 });
symbolLookup = new SingleSymbolLookup("D.", ONE);
addDataItem("D.", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("#D.", symbolLookup, new short[] { 0b111100, 0x0001 });
symbolLookup = new SingleSymbolLookup("D8", ONE);
addDataItem("D8", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("#D8", symbolLookup, new short[] { 0b111100, 0x0001 });
symbolLookup = new SingleSymbolLookup("PS", ONE);
addDataItem("(PS)", symbolLookup, new short[] { 0b111000, 0x0001 });
symbolLookup = new SingleSymbolLookup("ZPS", ONE);
addDataItem("(ZPS)", symbolLookup, new short[] { 0b111000, 0x0001 });
symbolLookup = new SingleSymbolLookup("ZZZ", ONE);
addDataItem("(ZZZ)", symbolLookup, new short[] { 0b111000, 0x0001 });
symbolLookup = new SingleSymbolLookup("PC", ONE);
addDataItem("(PC,PC)", symbolLookup, new short[] { 0b111010, -0x0001 });
addDataItem("(PC,[A0])", InstructionSet.MC68020, symbolLookup, new short[] { 0b110000, 0b00000001_01010010, 0x0001 });
symbolLookup = new SingleSymbolLookup("foo.0", ONE);
addDataItem("foo . 0", symbolLookup, new short[] { 0b111000, 0x0001 });
symbolLookup = new SingleSymbolLookup("foo.bar", ONE);
addDataItem("foo . bar", symbolLookup, new short[] { 0b111000, 0x0001 });
symbolLookup = new SingleSymbolLookup("foo.z", ONE);
addDataItem("foo . z", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("(A0,foo.z)", symbolLookup, new short[] { 0b101000, 0x0001 });
symbolLookup = new SingleSymbolLookup("foo.w", ONE);
addDataItem("(A0,foo.w)", symbolLookup, new short[] { 0b101000, 0x0001 });
symbolLookup = new SingleSymbolLookup("foo", ONE_FUNCTION);
addDataItem("foo()", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("foo(0)", symbolLookup, new short[] { 0b111000, 0x0001 });
addDataItem("foo(0, 0)", symbolLookup, new short[] { 0b111000, 0x0001 });
}
@Nonnull
@Parameters
public static List<Object[]> data() {
return TEST_DATA;
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSet instructionSet,
@CheckForNull SymbolLookup symbolLookup, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, instructionSet, symbolLookup, words);
}
private static void addDataItem(@Nonnull String text, @Nonnull InstructionSize instructionSize,
@Nonnull InstructionSet instructionSet, @CheckForNull SymbolLookup symbolLookup, @Nonnull short[] words) {
TEST_DATA.add(new Object[] { new DataItem(text, AddressingModeCategory.ALL, false, instructionSize, instructionSet,
symbolLookup, null, words) });
}
private static void addDataItem(@Nonnull String text, @CheckForNull SymbolLookup symbolLookup, @Nonnull short[] words) {
addDataItem(text, InstructionSize.DEFAULT, InstructionSet.MC68000, symbolLookup, words);
}
public SymbolTest(@Nonnull DataItem data) {
super(data);
}
}
@RunWith(Parameterized.class)
public static class ValidateAddressingModeTest extends BaseTest<ValidateAddressingModeTest.DataItem> {
public static class DataItem extends BaseTest.DataItem {
final boolean expectedValid;
DataItem(@Nonnull String text, @Nonnull Set<AddressingMode> validAddressingModes, boolean expectedValid) {
super(text, validAddressingModes, false, InstructionSize.DEFAULT, InstructionSet.MC68020, null, null);
this.expectedValid = expectedValid;
}
}
private static final int CLASS_CONSTANT_MODIFIERS = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
@Nonnull
private static final EquivalentAssemblyMessage ADDRESSING_MODE_NOT_ALLOWED_HERE = new EquivalentAssemblyMessage(
new AddressingModeNotAllowedHereErrorMessage());
@Nonnull
private static final ArrayList<Set<AddressingMode>> CATEGORIES = loadCategories();
@Nonnull
private static final ArrayList<Object[]> TEST_DATA = new ArrayList<>();
static {
addDataItem("D0", AddressingMode.DATA_REGISTER_DIRECT);
addDataItem("A0", AddressingMode.ADDRESS_REGISTER_DIRECT);
addDataItem("(A0)", AddressingMode.ADDRESS_REGISTER_INDIRECT);
addDataItem("(A0)+", AddressingMode.ADDRESS_REGISTER_INDIRECT_WITH_POSTINCREMENT);
addDataItem("-(A0)", AddressingMode.ADDRESS_REGISTER_INDIRECT_WITH_PREDECREMENT);
addDataItem("(2,A0)", AddressingMode.ADDRESS_REGISTER_INDIRECT_WITH_DISPLACEMENT);
addDataItem("(A0,D0)", AddressingMode.ADDRESS_REGISTER_INDIRECT_INDEXED);
addDataItem("(0).W", AddressingMode.ABSOLUTE);
addDataItem("(2,PC)", AddressingMode.PROGRAM_COUNTER_INDIRECT_WITH_DISPLACEMENT);
addDataItem("(PC,D0.W)", AddressingMode.PROGRAM_COUNTER_INDIRECT_INDEXED);
addDataItem("#0", AddressingMode.IMMEDIATE_DATA);
}
@Nonnull
@Parameters
public static List<Object[]> data() {
return TEST_DATA;
}
private static void addDataItem(@Nonnull String text, @Nonnull AddressingMode addressingMode) {
for (Set<AddressingMode> category : CATEGORIES) {
TEST_DATA.add(new Object[] { new DataItem(text, category, category.contains(addressingMode)) });
}
}
@Nonnull
@SuppressWarnings("unchecked")
private static ArrayList<Set<AddressingMode>> loadCategories() {
try {
ArrayList<Set<AddressingMode>> categories = new ArrayList<>();
final Field[] categoryFields = AddressingModeCategory.class.getDeclaredFields();
for (Field categoryField : categoryFields) {
if ((categoryField.getModifiers() & CLASS_CONSTANT_MODIFIERS) == CLASS_CONSTANT_MODIFIERS) {
final Object object = categoryField.get(null);
if (object instanceof Set) {
categories.add((Set<AddressingMode>) object);
}
}
}
return categories;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public ValidateAddressingModeTest(@Nonnull DataItem data) {
super(data);
}
@Override
protected void checkMessages(ArrayList<AssemblyMessage> messages) {
if (this.data.expectedValid) {
assertThat(messages, is(empty()));
} else {
assertThat(messages, contains(ADDRESSING_MODE_NOT_ALLOWED_HERE));
}
}
@Override
protected void checkOutput(EffectiveAddress ea) {
}
}
@Nonnull
static final UnsignedIntValue ONE_VALUE = new UnsignedIntValue(1);
@Nonnull
static final ValueExpression ONE_EXPRESSION = new ValueExpression(ONE_VALUE);
@Nonnull
static final Symbol UNDEFINED = new StaticSymbol(null);
@Nonnull
static final Symbol ONE = new StaticSymbol(ONE_VALUE);
@Nonnull
static final Symbol ONE_FUNCTION = new StaticSymbol(new FunctionValue(new Function() {
@Override
public Expression call(Expression[] arguments, EvaluationContext evaluationContext) {
return ONE_EXPRESSION;
}
}));
}