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 @@ -127,6 +127,10 @@ } }; APInt Insn(16, support::endian::read16be(Bytes.data())); + // 2 bytes of data are consumed, so set Size to 2 + // If we don't do this, disassembler may generate result even + // the encoding is invalid. We need to let it fail correctly. + Size = 2; Result = decodeInstruction(DecoderTable80, Instr, Insn, Address, this, STI, MakeUp); if (Result == DecodeStatus::Success) diff --git a/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/llvm/lib/Target/M68k/M68kInstrArithmetic.td --- a/llvm/lib/Target/M68k/M68kInstrArithmetic.td +++ b/llvm/lib/Target/M68k/M68kInstrArithmetic.td @@ -73,8 +73,10 @@ let Inst = (descend CMD, (operand "$dst", 3), !cast("MxOpMode"#DST_TYPE.Size#"_"#DST_TYPE.RLet#"_EA").Value, - (descend /*MODE without last bit*/0b00, - /*REGISTER prefixed with D/A bit*/(operand "$opd", 4)) + !cond( + !eq(SRC_TYPE.RLet, "r") : (descend 0b00, (operand "$opd", 4)), + !eq(SRC_TYPE.RLet, "d") : (descend 0b000, (operand "$opd", 3)) + ) ); } 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,10 +1,8 @@ -# 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 -# CHECK-CONFLICT: adda.l %a0, %a1 +# CHECK: adda.l %a0, %a1 0xd3 0xc8 -# CHECK-CONFLICT: sub.w %d3, %d1 +# CHECK: sub.w %d3, %d1 0x92 0x43 # CHECK: add.w (56,%a4,%d3), %d2 @@ -109,8 +107,8 @@ # CHECK: or.l %d6, (48,%a4,%a2) 0x8d 0xb4 0xa8 0x30 -# CHECK: or.b %a2, %d7 -0x8e 0x0a +# CHECK: or.b %d2, %d7 +0x8e 0x02 # CHECK: or.b (4163,%a1), %d0 0x80 0x29 0x10 0x43 @@ -128,4 +126,91 @@ 0x93 0xc4 # CHECK: sub.l #16843009, %d3 -0x96 0xbc 0x01 0x01 0x01 0x01 \ No newline at end of file +0x96 0xbc 0x01 0x01 0x01 0x01 + +# CHECK: add.w %d0, %d4 +0xd8 0x40 + +# CHECK: add.w %a2, %d3 +0xd6 0x4a + +# CHECK: add.l %d1, %d2 +0xd4 0x81 + +# CHECK: add.l %a0, %d1 +0xd2 0x88 + +# CHECK: sub.w %a5, %d1 +0x92 0x4d + +# CHECK: sub.w %d2, %d4 +0x98 0x42 + +# CHECK: sub.l %d2, %d5 +0x9a 0x82 + +# CHECK: sub.l %a2, %d5 +0x9a 0x8a + +# CHECK: subx.w %d2, %d4 +0x99 0x42 + +# CHECK: subx.l %d5, %d3 +0x97 0x85 + +# CHECK: suba.l %d4, %a0 +0x91 0xc4 + +# CHECK: suba.l #12576, %a2 +0x95 0xfc 0x00 0x00 0x31 0x20 + +# CHECK: suba.l (%sp), %a0 +0x91 0xd7 + +# CHECK: and.b (256,%a2), %d0 +0xc0 0x2a 0x01 0x00 + +# CHECK: and.w %d0, %d7 +0xce 0x40 + +# CHECK: and.w %a1, %d3 +0xc6 0x49 + +# CHECK: and.w (32,%a0,%d1), %d1 +0xc2 0x70 0x18 0x20 + +# CHECK: and.w (288,%a2), %d4 +0xc8 0x6a 0x01 0x20 + +# CHECK: and.l %d1, (49,%a0,%sp) +0xc3 0xb0 0xf8 0x31 + +# CHECK: and.l #100, (1,%a1,%d4) +0x02 0xb1 0x00 0x00 0x00 0x64 0x48 0x01 + +# CHECK: and.l %d0, %d1 +0xc2 0x80 + +# CHECK: and.l %a1, %d2 +0xc4 0x89 + +# CHECK: or.b #7, (%a1) +0x00 0x11 0x00 0x07 + +# CHECK: or.w %d2, %d5 +0x8a 0x42 + +# CHECK: or.w %a0, %d2 +0x84 0x48 + +# CHECK: or.w #0, (0,%a2,%a0) +0x00 0x72 0x00 0x00 0x88 0x00 + +# CHECK: or.l (15,%pc,%a1), %d0 +0x80 0xbb 0x98 0x0f + +# CHECK: or.l %a0, %d0 +0x80 0x88 + +# CHECK: or.l %d1, %d6 +0x8c 0x81