diff --git a/llvm/lib/Target/M68k/CMakeLists.txt b/llvm/lib/Target/M68k/CMakeLists.txt --- a/llvm/lib/Target/M68k/CMakeLists.txt +++ b/llvm/lib/Target/M68k/CMakeLists.txt @@ -14,6 +14,7 @@ tablegen(LLVM M68kGenCallingConv.inc -gen-callingconv) tablegen(LLVM M68kGenAsmWriter.inc -gen-asm-writer) tablegen(LLVM M68kGenAsmMatcher.inc -gen-asm-matcher) +tablegen(LLVM M68kGenDisassemblerTable.inc -gen-disassembler) add_public_tablegen_target(M68kCommonTableGen) diff --git a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp --- a/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp +++ b/llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp @@ -20,584 +20,118 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCDecoderOps.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; #define DEBUG_TYPE "m68k-disassembler" typedef MCDisassembler::DecodeStatus DecodeStatus; +const unsigned MaxInstrWord = 11; -namespace { -constexpr unsigned MaxInstructionWords = 11; - -class M68kInstructionBuffer { - typedef SmallVector BufferType; - BufferType Buffer; - -public: - M68kInstructionBuffer() {} - - template - M68kInstructionBuffer(TIt Start, TIt End) : Buffer(Start, End) {} - - unsigned size() const { return Buffer.size(); } - - BufferType::const_iterator begin() const { return Buffer.begin(); } - BufferType::const_iterator end() const { return Buffer.end(); } - - uint16_t operator[](unsigned Index) const { - assert((Index < Buffer.size()) && "tried to read out of bounds word"); - return Buffer[Index]; - } - - void truncate(unsigned NewLength) { - assert((NewLength <= Buffer.size()) && - "instruction buffer too short to truncate"); - Buffer.resize(NewLength); - } - - void dump() const; - - static M68kInstructionBuffer fill(ArrayRef Bytes); +static const unsigned RegisterDecode[] = { + M68k::D0, M68k::D1, M68k::D2, M68k::D3, M68k::D4, M68k::D5, + M68k::D6, M68k::D7, M68k::A0, M68k::A1, M68k::A2, M68k::A3, + M68k::A4, M68k::A5, M68k::A6, M68k::SP, }; -class M68kInstructionReader { - M68kInstructionBuffer Buffer; - unsigned NumRead; - -public: - M68kInstructionReader(M68kInstructionBuffer Buf) : Buffer(Buf), NumRead(0) {} +static DecodeStatus DecodeRegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, const void *Decoder) { + if (RegNo >= 16) + return DecodeStatus::Fail; + Inst.addOperand(MCOperand::createReg(RegisterDecode[RegNo])); + return DecodeStatus::Success; +} - unsigned size() const { return (Buffer.size() * 16) - NumRead; } +static DecodeStatus DecodeDR32RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo, Address, Decoder); +} - uint64_t readBits(unsigned NumBits); -}; +static DecodeStatus DecodeDR16RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo, Address, Decoder); +} -struct M68kInstructionLookup { - unsigned OpCode; - M68kInstructionBuffer Mask; - M68kInstructionBuffer Value; +static DecodeStatus DecodeDR8RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo, Address, Decoder); +} - unsigned size() const { return Mask.size(); } +static DecodeStatus DecodeAR32RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder); +} - // Check whether this instruction could possibly match the given bytes. - bool matches(const M68kInstructionBuffer &Test) const; - void dump() const; -}; +static DecodeStatus DecodeAR16RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo | 8ULL, Address, Decoder); +} -class M68kInstructionLookupBuilder { - std::array Mask; - std::array Value; - unsigned NumWritten; +static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo, Address, Decoder); +} -public: - M68kInstructionLookupBuilder() : NumWritten(0) { - Mask.fill(0); - Value.fill(0); - } +static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo, + uint64_t Address, + const void *Decoder) { + return DecodeRegisterClass(Inst, RegNo, Address, Decoder); +} - unsigned numWords() const { - assert(!(NumWritten & 0xf) && "instructions must be whole words"); - return NumWritten >> 4; - } +static DecodeStatus DecodeCCRCRegisterClass(MCInst &Inst, APInt &Insn, + uint64_t Address, + const void *Decoder) { + llvm_unreachable("unimplemented"); +} - bool isValid() const; - M68kInstructionLookup build(unsigned OpCode); - void addBits(unsigned N, uint64_t Bits); - void skipBits(unsigned N); -}; +#include "M68kGenDisassemblerTable.inc" /// A disassembler class for M68k. class M68kDisassembler : public MCDisassembler { MCInstrInfo *MCII; - std::vector Lookups; public: M68kDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, MCInstrInfo *MCII) - : MCDisassembler(STI, Ctx), MCII(MCII) { - buildBeadTable(); - } + : MCDisassembler(STI, Ctx), MCII(MCII) {} virtual ~M68kDisassembler() {} - void buildBeadTable(); DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef Bytes, uint64_t Address, raw_ostream &CStream) const override; - void decodeReg(MCInst &Instr, unsigned int Bead, - M68kInstructionReader &Reader, unsigned &Scratch) const; - void decodeImm(MCInst &Instr, unsigned int Bead, - M68kInstructionReader &Reader, unsigned &Scratch) const; - unsigned int getRegOperandIndex(MCInst &Instr, unsigned int Bead) const; - unsigned int getImmOperandIndex(MCInst &Instr, unsigned int Bead) const; }; -} // namespace - -static unsigned RegisterDecode[] = { - M68k::A0, M68k::A1, M68k::A2, M68k::A3, M68k::A4, M68k::A5, - M68k::A6, M68k::SP, M68k::D0, M68k::D1, M68k::D2, M68k::D3, - M68k::D4, M68k::D5, M68k::D6, M68k::D7, -}; - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD -void M68kInstructionBuffer::dump() const { - for (auto Word : Buffer) { - for (unsigned B = 0; B < 16; ++B) { - uint16_t Bit = (1 << (16 - B - 1)); - unsigned IsClear = !(Word & Bit); - - if (B == 8) - dbgs() << " "; - - char Ch = IsClear ? '0' : '1'; - dbgs() << Ch; - } - - dbgs() << " "; - } - - dbgs() << "\n"; -} -#endif - -M68kInstructionBuffer M68kInstructionBuffer::fill(ArrayRef Bytes) { - SmallVector Buffer; - Buffer.resize(std::min(Bytes.size() / 2, Buffer.max_size())); - - for (unsigned I = 0, E = Buffer.size(); I < E; ++I) { - unsigned Offset = I * 2; - uint64_t Hi = Bytes[Offset]; - uint64_t Lo = Bytes[Offset + 1]; - uint64_t Word = (Hi << 8) | Lo; - Buffer[I] = Word; - - LLVM_DEBUG( - errs() << format("Read word %x (%d)\n", (unsigned)Word, Buffer.size())); - } - - return M68kInstructionBuffer(Buffer.begin(), Buffer.end()); -} - -uint64_t M68kInstructionReader::readBits(unsigned NumBits) { - assert((size() >= NumBits) && "not enough bits to read"); - - // We have to read the bits in 16-bit chunks because we read them as - // 16-bit words but they're actually written in big-endian. If a read - // crosses a word boundary we have to be careful. - - uint64_t Value = 0; - unsigned BitsRead = 0; - - while (BitsRead < NumBits) { - unsigned AvailableThisWord = 16 - (NumRead & 0xf); - unsigned ToRead = std::min(NumBits, AvailableThisWord); - - unsigned WordIndex = NumRead >> 4; - uint64_t ThisWord = Buffer[WordIndex] >> (NumRead & 0xf); - uint64_t Mask = (1 << ToRead) - 1; - Value |= (ThisWord & Mask) << BitsRead; - NumRead += ToRead; - BitsRead += ToRead; - } - return Value; -} - -bool M68kInstructionLookup::matches(const M68kInstructionBuffer &Test) const { - if (Test.size() < Value.size()) - return false; - - for (unsigned I = 0, E = Value.size(); I < E; ++I) { - uint16_t Have = Test[I]; - uint16_t Need = Value[I]; - uint16_t WordMask = Mask[I]; - - if ((Have & WordMask) != Need) - return false; - } - - return true; -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD -void M68kInstructionLookup::dump() const { - dbgs() << "M68kInstructionLookup " << OpCode << " "; - - for (unsigned I = 0, E = Mask.size(); I < E; ++I) { - uint16_t WordMask = Mask[I]; - uint16_t WordValue = Value[I]; - - for (unsigned B = 0; B < 16; ++B) { - uint16_t Bit = (1 << (15 - B)); - unsigned IsMasked = !(WordMask & Bit); - unsigned IsClear = !(WordValue & Bit); - - if (B == 8) - dbgs() << " "; - - char Ch = IsMasked ? '?' : (IsClear ? '0' : '1'); - dbgs() << Ch; - } - - dbgs() << " "; - } - - dbgs() << "\n"; -} -#endif - -bool M68kInstructionLookupBuilder::isValid() const { - for (unsigned I = 0, E = numWords(); I < E; ++I) - if (Mask[I]) - return true; - - return false; -} - -M68kInstructionLookup M68kInstructionLookupBuilder::build(unsigned OpCode) { - unsigned NumWords = numWords(); - M68kInstructionBuffer MaskBuffer(Mask.begin(), Mask.begin() + NumWords); - M68kInstructionBuffer ValueBuffer(Value.begin(), Value.begin() + NumWords); - M68kInstructionLookup Ret; - Ret.OpCode = OpCode; - Ret.Mask = MaskBuffer; - Ret.Value = ValueBuffer; - return Ret; -} - -void M68kInstructionLookupBuilder::addBits(unsigned N, uint64_t Bits) { - while (N > 0) { - unsigned WordIndex = NumWritten >> 4; - unsigned WordOffset = NumWritten & 0xf; - unsigned AvailableThisWord = 16 - WordOffset; - unsigned ToWrite = std::min(AvailableThisWord, N); - - uint16_t WordMask = (1 << ToWrite) - 1; - uint16_t BitsToWrite = Bits & WordMask; - - Value[WordIndex] |= (BitsToWrite << WordOffset); - Mask[WordIndex] |= (WordMask << WordOffset); - - Bits >>= ToWrite; - N -= ToWrite; - NumWritten += ToWrite; - } -} - -void M68kInstructionLookupBuilder::skipBits(unsigned N) { NumWritten += N; } - -// This is a bit of a hack: we can't generate this table at table-gen time -// because some of the definitions are in our platform. -void M68kDisassembler::buildBeadTable() { - const unsigned NumInstr = M68k::INSTRUCTION_LIST_END; - Lookups.reserve(NumInstr); - - for (unsigned I = 0; I < NumInstr; ++I) { - M68kInstructionLookupBuilder Builder; - - for (const uint8_t *PartPtr = M68k::getMCInstrBeads(I); *PartPtr; - ++PartPtr) { - uint8_t Bead = *PartPtr; - unsigned Ext = Bead >> 4; - unsigned Op = Bead & 0xf; - - switch (Op) { - case M68kBeads::Ctrl: - // Term will have already been skipped by the loop. - assert((Ext == M68kBeads::Ignore) && "unexpected command bead"); - break; - - case M68kBeads::Bits1: - Builder.addBits(1, Ext); - break; - - case M68kBeads::Bits2: - Builder.addBits(2, Ext); - break; - - case M68kBeads::Bits3: - Builder.addBits(3, Ext); - break; - - case M68kBeads::Bits4: - Builder.addBits(4, Ext); - break; - - case M68kBeads::DAReg: - case M68kBeads::DA: - case M68kBeads::DReg: - case M68kBeads::Reg: - if (Op != M68kBeads::DA) - Builder.skipBits(3); - - if (Op != M68kBeads::Reg && Op != M68kBeads::DReg) - Builder.skipBits(1); - - break; - - case M68kBeads::Disp8: - Builder.skipBits(8); - break; - - case M68kBeads::Imm8: - case M68kBeads::Imm16: - Builder.skipBits(16); - break; - - case M68kBeads::Imm32: - Builder.skipBits(32); - break; - - case M68kBeads::Imm3: - Builder.skipBits(3); - break; - - default: - llvm_unreachable("unhandled bead type"); - } - } - - // Ignore instructions which are unmatchable (usually pseudo instructions). - if (!Builder.isValid()) - continue; - - Lookups.push_back(Builder.build(I)); - } -} - -unsigned M68kDisassembler::getRegOperandIndex(MCInst &Instr, - unsigned Bead) const { - unsigned Ext = Bead >> 4; - - const MCInstrDesc &Desc = MCII->get(Instr.getOpcode()); - auto MIOpIdx = M68k::getLogicalOperandIdx(Instr.getOpcode(), Ext & 7); - - if (M68kII::hasMultiMIOperands(Instr.getOpcode(), Ext & 7)) { - bool IsPCRel = Desc.OpInfo[MIOpIdx].OperandType == MCOI::OPERAND_PCREL; - if (IsPCRel) - MIOpIdx += M68k::PCRelIndex; - else if (Ext & 8) - MIOpIdx += M68k::MemIndex; - else - MIOpIdx += M68k::MemBase; - } - - return MIOpIdx; -} - -unsigned M68kDisassembler::getImmOperandIndex(MCInst &Instr, - unsigned Bead) const { - unsigned Ext = Bead >> 4; - - const MCInstrDesc &Desc = MCII->get(Instr.getOpcode()); - auto MIOpIdx = M68k::getLogicalOperandIdx(Instr.getOpcode(), Ext & 7); - - if (M68kII::hasMultiMIOperands(Instr.getOpcode(), Ext & 7)) { - bool IsPCRel = Desc.OpInfo[MIOpIdx].OperandType == MCOI::OPERAND_PCREL; - if (IsPCRel) - MIOpIdx += M68k::PCRelDisp; - else if (Ext & 8) - MIOpIdx += M68k::MemOuter; - else - MIOpIdx += M68k::MemDisp; - } - - return MIOpIdx; -} - -void M68kDisassembler::decodeReg(MCInst &Instr, unsigned Bead, - M68kInstructionReader &Reader, - unsigned &Scratch) const { - unsigned Op = Bead & 0xf; - LLVM_DEBUG(errs() << format("decodeReg %x\n", Bead)); - - if (Op != M68kBeads::DA) - Scratch = (Scratch & ~7) | Reader.readBits(3); - - if (Op != M68kBeads::Reg) { - bool DA = (Op != M68kBeads::DReg) && Reader.readBits(1); - if (!DA) - Scratch |= 8; - else - Scratch &= ~8; - } -} - -void M68kDisassembler::decodeImm(MCInst &Instr, unsigned Bead, - M68kInstructionReader &Reader, - unsigned &Scratch) const { - unsigned Op = Bead & 0xf; - LLVM_DEBUG(errs() << format("decodeImm %x\n", Bead)); - - unsigned NumToRead; - switch (Op) { - case M68kBeads::Disp8: - NumToRead = 8; - break; - case M68kBeads::Imm8: - case M68kBeads::Imm16: - NumToRead = 16; - break; - case M68kBeads::Imm32: - NumToRead = 32; - break; - case M68kBeads::Imm3: - NumToRead = 3; - break; - default: - llvm_unreachable("invalid imm"); - } - - Scratch = (NumToRead < 32) ? (Scratch << NumToRead) : 0; - Scratch |= Reader.readBits(NumToRead); -} DecodeStatus M68kDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef Bytes, uint64_t Address, raw_ostream &CStream) const { - // Read and shift the input (fetch as much as we can for now). - auto Buffer = M68kInstructionBuffer::fill(Bytes); - if (Buffer.size() == 0) - return Fail; - - // Check through our lookup table. - bool Found = false; - for (unsigned I = 0, E = Lookups.size(); I < E; ++I) { - const M68kInstructionLookup &Lookup = Lookups[I]; - if (!Lookup.matches(Buffer)) - continue; - - Found = true; - Size = Lookup.size() * 2; - Buffer.truncate(Lookup.size()); - Instr.setOpcode(Lookup.OpCode); - LLVM_DEBUG(errs() << "decoding instruction " << MCII->getName(Lookup.OpCode) - << "\n"); - break; - } - - if (!Found) - return Fail; - - M68kInstructionReader Reader(Buffer); - const MCInstrDesc &Desc = MCII->get(Instr.getOpcode()); - unsigned NumOperands = Desc.NumOperands; - - // Now use the beads to decode the operands. - enum class OperandType { - Invalid, - Reg, - Imm, - }; - - SmallVector OpType(NumOperands, OperandType::Invalid); - SmallVector Scratch(NumOperands, 0); - for (const uint8_t *PartPtr = M68k::getMCInstrBeads(Instr.getOpcode()); - *PartPtr; ++PartPtr) { - uint8_t Bead = *PartPtr; - unsigned Ext = Bead >> 4; - unsigned Op = Bead & 0xf; - unsigned MIOpIdx; - - switch (Op) { - case M68kBeads::Ctrl: - // Term will have already been skipped by the loop. - assert((Ext == M68kBeads::Ignore) && "unexpected command bead"); - break; - - // These bits are constant - if we're here we've already matched them. - case M68kBeads::Bits1: - Reader.readBits(1); - break; - case M68kBeads::Bits2: - Reader.readBits(2); - break; - case M68kBeads::Bits3: - Reader.readBits(3); - break; - case M68kBeads::Bits4: - Reader.readBits(4); - break; - - case M68kBeads::DAReg: - case M68kBeads::DA: - case M68kBeads::DReg: - case M68kBeads::Reg: - MIOpIdx = getRegOperandIndex(Instr, Bead); - assert(((OpType[MIOpIdx] == OperandType::Invalid) || - (OpType[MIOpIdx] == OperandType::Reg)) && - "operands cannot change type"); - OpType[MIOpIdx] = OperandType::Reg; - decodeReg(Instr, Bead, Reader, Scratch[MIOpIdx]); - break; - - case M68kBeads::Disp8: - case M68kBeads::Imm8: - case M68kBeads::Imm16: - case M68kBeads::Imm32: - case M68kBeads::Imm3: - MIOpIdx = getImmOperandIndex(Instr, Bead); - assert(((OpType[MIOpIdx] == OperandType::Invalid) || - (OpType[MIOpIdx] == OperandType::Imm)) && - "operands cannot change type"); - OpType[MIOpIdx] = OperandType::Imm; - decodeImm(Instr, Bead, Reader, Scratch[MIOpIdx]); - break; - - default: - llvm_unreachable("unhandled bead type"); - } - } - - // Copy constrained operands. - for (unsigned DstMIOpIdx = 0; DstMIOpIdx < NumOperands; ++DstMIOpIdx) { - int TiedTo = Desc.getOperandConstraint(DstMIOpIdx, MCOI::TIED_TO); - if (TiedTo < 0) - continue; - - unsigned SrcMIOpIdx = TiedTo; - - unsigned OpCount = 0; - for (unsigned I = 0;; ++I) { - unsigned Offset = M68k::getLogicalOperandIdx(Instr.getOpcode(), I); - assert(Offset <= SrcMIOpIdx && "missing logical operand"); - if (Offset == SrcMIOpIdx) { - OpCount = M68k::getLogicalOperandSize(Instr.getOpcode(), I); - break; - } + DecodeStatus Result; + auto MakeUp = [&](APInt &Insn, unsigned InstrBits) { + unsigned Idx = Insn.getBitWidth() >> 3; + unsigned RoundUp = alignTo(InstrBits, Align(16)); + Insn = Insn.zextOrSelf(RoundUp); + RoundUp = RoundUp >> 3; + for (; Idx < RoundUp; Idx += 2) { + Insn.insertBits(support::endian::read16be(&Bytes[Idx]), Idx * 8, 16); } - assert(OpCount != 0 && "operand count not found"); - - for (unsigned I = 0; I < OpCount; ++I) { - assert(OpType[DstMIOpIdx + I] == OperandType::Invalid && - "tried to stomp over operand whilst applying constraints"); - OpType[DstMIOpIdx + I] = OpType[SrcMIOpIdx + I]; - Scratch[DstMIOpIdx + I] = Scratch[SrcMIOpIdx + I]; - } - } - - // Create the operands from our scratch space. - for (unsigned O = 0; O < NumOperands; ++O) { - switch (OpType[O]) { - case OperandType::Invalid: - assert(false && "operand not parsed"); - - case OperandType::Imm: - Instr.addOperand(MCOperand::createImm(Scratch[O])); - break; - - case OperandType::Reg: - Instr.addOperand(MCOperand::createReg(RegisterDecode[Scratch[O]])); - break; - } - } - - assert((Reader.size() == 0) && "wrong number of bits consumed"); - return Success; + }; + APInt Insn(16, support::endian::read16be(Bytes.data())); + Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI, + MakeUp); + if (Result == DecodeStatus::Success) + Size = InstrLenTable[Instr.getOpcode()] >> 3; + return Result; } static MCDisassembler *createM68kDisassembler(const Target &T, diff --git a/llvm/test/MC/Disassembler/M68k/arithmetic.txt b/llvm/test/MC/Disassembler/M68k/arithmetic.txt --- a/llvm/test/MC/Disassembler/M68k/arithmetic.txt +++ b/llvm/test/MC/Disassembler/M68k/arithmetic.txt @@ -1,13 +1,131 @@ +# FIXME: The first two tests are disabled due to decoding conflict +# RUN: llvm-mc -disassemble -triple m68k %s | not FileCheck -check-prefix=CHECK-CONFLICT %s # RUN: llvm-mc -disassemble -triple m68k %s | FileCheck %s -# Disable this particular test until migration to the new code emitter is -# finished. -# XFAIL: * -# CHECK: adda.l %a0, %a1 +# CHECK-CONFLICT: adda.l %a0, %a1 0xd3 0xc8 -# CHECK: sub.w %d3, %d1 +# CHECK-CONFLICT: sub.w %d3, %d1 0x92 0x43 + +# CHECK: add.w (56,%a4,%d3), %d2 +0xd4 0x74 0x38 0x38 + +# CHECK: add.w #35172, %d1 +0xd2 0x7c 0x89 0x64 + +# CHECK: add.w (%a5), %d3 +0xd6 0x55 + +# CHECK: add.w (102,%pc,%a4), %d7 +0xde 0x7b 0xc8 0x66 + +# CHECK: add.w (30600,%a4), %d5 +0xda 0x6c 0x77 0x88 + +# CHECK: add.w (5190,%pc), %d1 +0xd2 0x7a 0x14 0x46 + +# CHECK: add.w %d2, (20,%a6,%d5) +0xd5 0x76 0x58 0x14 + +# CHECK: add.w #5205, (49,%a3,%d7) +0x06 0x73 0x14 0x55 0x78 0x31 + +# CHECK: add.w %d2, (%a6) +0xd5 0x56 + +# CHECK: add.w #5378, (%a6) +0x06 0x56 0x15, 0x02 + +# CHECK: add.w %d2, (5380,%a2) +0xd5 0x6a 0x15 0x04 + +# CHECK: adda.l (18,%a4,%d1), %a3 +0xd7 0xf4 0x18 0x12 + +# CHECK: adda.l #50402580, %a1 +0xd3 0xfc 0x03 0x01 0x15 0x14 + +# CHECK: adda.l (%a5), %a1 +0xd3 0xd5 + +# CHECK: adda.l (0,%pc,%sp), %sp +0xdf 0xfb 0xf8 0x00 + +# CHECK: adda.l (5401,%pc), %a5 +0xdb 0xfa 0x15 0x19 + +# CHECK: adda.l %a5, %a4 +0xd9 0xcd + +# CHECK: add.l (4660,%sp), %d5 +0xda 0xaf 0x12 0x34 + +# CHECK: cmpi.w #769, $3012022 +0x0c 0x79 0x03 0x01 0x20 0x22 0x03 0x01 + +# CHECK: cmpi.w #5416, %d7 +0x0c 0x47 0x15 0x28 + +# CHECK: cmp.w (69,%a2,%a1), %d3 +0xb6 0x72 0x98 0x45 + +# CHECK: cmpi.l #50402614, (51,%a5,%d7) +0x0c 0xb5 0x03 0x01 0x15 0x36 0x78 0x33 + +# CHECK: cmpi.l #50403411, $1 +0x0c 0xb9 0x03 0x01 0x18 0x53 0x00 0x01 0x00 0x00 + +# CHECK: cmpi.b #64, $15400301 +0x0c 0x39 0x00 0x40 0x03 0x01 0x15 0x40 + +# CHECK: cmp.b %d5, %d7 +0xbe 0x05 + # CHECK: cmp.w %d1, %d0 0xb0 0x41 + # CHECK: neg.w %d0 0x44 0x40 + +# CHECK: negx.l %a2 +0x40 0x8a + +# CHECK: or.w (18,%a4,%a0), %d3 +0x86 0x74 0x88 0x12 + +# CHECK: or.w #4149, %d2 +0x84 0x7c 0x10 0x35 + +# CHECK: or.l (%a3), %d4 +0x88 0x93 + +# CHECK: or.l (55,%pc,%a1), %d6 +0x8c 0xbb 0x98 0x37 + +# CHECK: or.l (38967,%a3), %d6 +0x8c 0xab 0x98 0x37 + +# CHECK: or.l %d6, (48,%a4,%a2) +0x8d 0xb4 0xa8 0x30 + +# CHECK: or.b %a2, %d7 +0x8e 0x0a + +# CHECK: or.b (4163,%a1), %d0 +0x80 0x29 0x10 0x43 + +# CHECK: or.b #16, (3,%a3,%d4) +0x00 0x33 0x00 0x10 0x48 0x03 + +# CHECK: sub.w %d5, (16,%a3,%a2) +0x9b 0x73 0xa8 0x10 + +# CHECK: suba.l (85,%a4,%a2), %a0 +0x91 0xf4 0xa8 0x55 + +# CHECK: suba.l %d4, %a1 +0x93 0xc4 + +# CHECK: sub.l #16843009, %d3 +0x96 0xbc 0x01 0x01 0x01 0x01 \ No newline at end of file diff --git a/llvm/test/MC/Disassembler/M68k/bits.txt b/llvm/test/MC/Disassembler/M68k/bits.txt --- a/llvm/test/MC/Disassembler/M68k/bits.txt +++ b/llvm/test/MC/Disassembler/M68k/bits.txt @@ -1,7 +1,22 @@ # RUN: llvm-mc -disassemble -triple m68k %s | FileCheck %s -# Disable this particular test until migration to the new code emitter is -# finished. -# XFAIL: * -# CHECK: btst #0, %d3 -0x08 0x03 0x00 0x00 +# CHECK: btst %d3, %a0 +0x07 0x08 + +# CHECK: btst %d5, -(%a2) +0x0b 0x22 + +# CHECK: btst #20, -(%a4) +0x08 0x24 0x00 0x14 + +# CHECK: btst %d5, (79,%sp,%a0) +0x0b 0x37 0x88 0x4f + +# CHECK: btst %d4, (%a2)+ +0x09 0x1a + +# CHECK: btst %d6, (8217,%pc) +0x0d 0x3a 0x20 0x19 + +# CHECK: btst #20, %d3 +0x08 0x03 0x00 0x14 diff --git a/llvm/test/MC/Disassembler/M68k/control.txt b/llvm/test/MC/Disassembler/M68k/control.txt --- a/llvm/test/MC/Disassembler/M68k/control.txt +++ b/llvm/test/MC/Disassembler/M68k/control.txt @@ -1,5 +1,4 @@ # RUN: llvm-mc -disassemble -triple m68k %s | FileCheck %s -# XFAIL: * # CHECK: bra $0 0x60 0x00 0x00 0x00 diff --git a/llvm/test/MC/Disassembler/M68k/data.txt b/llvm/test/MC/Disassembler/M68k/data.txt --- a/llvm/test/MC/Disassembler/M68k/data.txt +++ b/llvm/test/MC/Disassembler/M68k/data.txt @@ -1,7 +1,4 @@ # RUN: llvm-mc -disassemble -triple m68k %s | FileCheck %s -# Disable this particular test until migration to the new code emitter is -# finished. -# XFAIL: * # CHECK: move.l %a1, %a0 0x20 0x49 diff --git a/llvm/test/MC/Disassembler/M68k/shift-rotate.txt b/llvm/test/MC/Disassembler/M68k/shift-rotate.txt --- a/llvm/test/MC/Disassembler/M68k/shift-rotate.txt +++ b/llvm/test/MC/Disassembler/M68k/shift-rotate.txt @@ -1,7 +1,4 @@ # RUN: llvm-mc -disassemble -triple m68k %s | FileCheck %s -# Disable this particular test until migration to the new code emitter is -# finished. -# XFAIL: * # CHECK: lsl.l #5, %d1 0xeb 0x89 diff --git a/llvm/test/MC/M68k/Control/call-pc-rel.s b/llvm/test/MC/M68k/Control/call-pc-rel.s --- a/llvm/test/MC/M68k/Control/call-pc-rel.s +++ b/llvm/test/MC/M68k/Control/call-pc-rel.s @@ -1,8 +1,6 @@ ; RUN: llvm-mc -triple=m68k -show-encoding %s | FileCheck %s -; TODO: We negates the second test since it needs disassembler support -; Revert it back when we have that. ; RUN: llvm-mc -triple=m68k -filetype=obj < %s | \ -; RUN: llvm-objdump -d - | not FileCheck --check-prefix=CHECK-OBJ %s +; RUN: llvm-objdump -d - | FileCheck --check-prefix=CHECK-OBJ %s ; CHECK-LABEL: BACKWARD: BACKWARD: diff --git a/llvm/test/MC/M68k/Relaxations/branch.s b/llvm/test/MC/M68k/Relaxations/branch.s --- a/llvm/test/MC/M68k/Relaxations/branch.s +++ b/llvm/test/MC/M68k/Relaxations/branch.s @@ -1,6 +1,5 @@ ; RUN: llvm-mc -triple=m68k -motorola-integers -filetype=obj < %s \ ; RUN: | llvm-objdump -d - | FileCheck %s -; XFAIL: * ; CHECK-LABEL: : TIGHT: