package org.reasm.m68k.assembly.internal; import java.io.IOException; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; import org.reasm.m68k.messages.DataForMoveqOutOfRangeErrorMessage; import org.reasm.m68k.messages.DataForMoveqWillBeSignExtendedWarningMessage; /** * The <code>MOVEQ</code> instruction. * * @author Francis Gagné */ @Immutable class MoveqInstruction extends TwoFixedEaInstruction { @Nonnull static final MoveqInstruction MOVEQ = new MoveqInstruction(); static void encode(@Nonnull M68KAssemblyContext context, int immediateData, int dataRegister) throws IOException { context.appendWord((short) (0b01110000_00000000 | dataRegister << 9 | immediateData & 0xFF)); } private MoveqInstruction() { super(AddressingModeCategory.IMMEDIATE_DATA, AddressingModeCategory.DATA_REGISTER_DIRECT); } @Override void assemble(M68KAssemblyContext context, InstructionSize size, EffectiveAddress ea0, EffectiveAddress ea1) throws IOException { if (ea0.isImmediateData() && ea1.isDataRegisterDirect()) { final int immediateData = ea0.word1 << 16 | ea0.word2; if (immediateData < -0x80 || immediateData > 0x7F) { if ((immediateData & 0xFFFFFF00) == 0) { context.addTentativeMessage(new DataForMoveqWillBeSignExtendedWarningMessage()); } else { context.addTentativeMessage(new DataForMoveqOutOfRangeErrorMessage()); } } encode(context, immediateData, ea1.getRegister()); } else { encode(context, 0, 0); } } @Override InstructionSize getInstructionSize(M68KAssemblyContext context) { final InstructionSize size = context.parseIntegerInstructionSize(); if (size != InstructionSize.DEFAULT && size != InstructionSize.LONG) { context.addInvalidSizeAttributeErrorMessage(); } return InstructionSize.LONG; } }