diff --git a/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp b/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp index 8e2fa8fee38..225c06f9aee 100644 --- a/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp +++ b/lib/Target/ARM64/Disassembler/ARM64Disassembler.cpp @@ -854,6 +854,14 @@ static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst, switch (Inst.getOpcode()) { default: return Fail; + case ARM64::ADDWrs: + case ARM64::ADDSWrs: + case ARM64::SUBWrs: + case ARM64::SUBSWrs: + // if shift == '11' then ReservedValue() + if (shiftHi == 0x3) + return Fail; + // Deliberate fallthrough case ARM64::ANDWrs: case ARM64::ANDSWrs: case ARM64::BICWrs: @@ -861,16 +869,23 @@ static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst, case ARM64::ORRWrs: case ARM64::ORNWrs: case ARM64::EORWrs: - case ARM64::EONWrs: - case ARM64::ADDWrs: - case ARM64::ADDSWrs: - case ARM64::SUBWrs: - case ARM64::SUBSWrs: { + case ARM64::EONWrs: { + // if sf == '0' and imm6<5> == '1' then ReservedValue() + if (shiftLo >> 5 == 1) + return Fail; DecodeGPR32RegisterClass(Inst, Rd, Addr, Decoder); DecodeGPR32RegisterClass(Inst, Rn, Addr, Decoder); DecodeGPR32RegisterClass(Inst, Rm, Addr, Decoder); break; } + case ARM64::ADDXrs: + case ARM64::ADDSXrs: + case ARM64::SUBXrs: + case ARM64::SUBSXrs: + // if shift == '11' then ReservedValue() + if (shiftHi == 0x3) + return Fail; + // Deliberate fallthrough case ARM64::ANDXrs: case ARM64::ANDSXrs: case ARM64::BICXrs: @@ -879,10 +894,6 @@ static DecodeStatus DecodeThreeAddrSRegInstruction(llvm::MCInst &Inst, case ARM64::ORNXrs: case ARM64::EORXrs: case ARM64::EONXrs: - case ARM64::ADDXrs: - case ARM64::ADDSXrs: - case ARM64::SUBXrs: - case ARM64::SUBSXrs: DecodeGPR64RegisterClass(Inst, Rd, Addr, Decoder); DecodeGPR64RegisterClass(Inst, Rn, Addr, Decoder); DecodeGPR64RegisterClass(Inst, Rm, Addr, Decoder); diff --git a/test/MC/Disassembler/ARM64/arithmetic.txt b/test/MC/Disassembler/ARM64/arithmetic.txt index 3981219ff3b..2d8fd263b8b 100644 --- a/test/MC/Disassembler/ARM64/arithmetic.txt +++ b/test/MC/Disassembler/ARM64/arithmetic.txt @@ -85,72 +85,72 @@ 0xac 0x01 0x0e 0x8b 0xac 0x31 0x0e 0x0b 0xac 0x31 0x0e 0x8b -0xac 0xa9 0x4e 0x0b -0xac 0xa9 0x4e 0x8b -0xac 0x9d 0x8e 0x0b +0xac 0x29 0x4e 0x0b +0xac 0x29 0x4e 0x8b +0xac 0x1d 0x8e 0x0b 0xac 0x9d 0x8e 0x8b # CHECK: add w12, w13, w14 # CHECK: add x12, x13, x14 # CHECK: add w12, w13, w14, lsl #12 # CHECK: add x12, x13, x14, lsl #12 -# CHECK: add w12, w13, w14, lsr #42 -# CHECK: add x12, x13, x14, lsr #42 -# CHECK: add w12, w13, w14, asr #39 +# CHECK: add w12, w13, w14, lsr #10 +# CHECK: add x12, x13, x14, lsr #10 +# CHECK: add w12, w13, w14, asr #7 # CHECK: add x12, x13, x14, asr #39 0xac 0x01 0x0e 0x4b 0xac 0x01 0x0e 0xcb 0xac 0x31 0x0e 0x4b 0xac 0x31 0x0e 0xcb -0xac 0xa9 0x4e 0x4b -0xac 0xa9 0x4e 0xcb -0xac 0x9d 0x8e 0x4b +0xac 0x29 0x4e 0x4b +0xac 0x29 0x4e 0xcb +0xac 0x1d 0x8e 0x4b 0xac 0x9d 0x8e 0xcb # CHECK: sub w12, w13, w14 # CHECK: sub x12, x13, x14 # CHECK: sub w12, w13, w14, lsl #12 # CHECK: sub x12, x13, x14, lsl #12 -# CHECK: sub w12, w13, w14, lsr #42 -# CHECK: sub x12, x13, x14, lsr #42 -# CHECK: sub w12, w13, w14, asr #39 +# CHECK: sub w12, w13, w14, lsr #10 +# CHECK: sub x12, x13, x14, lsr #10 +# CHECK: sub w12, w13, w14, asr #7 # CHECK: sub x12, x13, x14, asr #39 0xac 0x01 0x0e 0x2b 0xac 0x01 0x0e 0xab 0xac 0x31 0x0e 0x2b 0xac 0x31 0x0e 0xab -0xac 0xa9 0x4e 0x2b -0xac 0xa9 0x4e 0xab -0xac 0x9d 0x8e 0x2b +0xac 0x29 0x4e 0x2b +0xac 0x29 0x4e 0xab +0xac 0x1d 0x8e 0x2b 0xac 0x9d 0x8e 0xab # CHECK: adds w12, w13, w14 # CHECK: adds x12, x13, x14 # CHECK: adds w12, w13, w14, lsl #12 # CHECK: adds x12, x13, x14, lsl #12 -# CHECK: adds w12, w13, w14, lsr #42 -# CHECK: adds x12, x13, x14, lsr #42 -# CHECK: adds w12, w13, w14, asr #39 +# CHECK: adds w12, w13, w14, lsr #10 +# CHECK: adds x12, x13, x14, lsr #10 +# CHECK: adds w12, w13, w14, asr #7 # CHECK: adds x12, x13, x14, asr #39 0xac 0x01 0x0e 0x6b 0xac 0x01 0x0e 0xeb 0xac 0x31 0x0e 0x6b 0xac 0x31 0x0e 0xeb -0xac 0xa9 0x4e 0x6b -0xac 0xa9 0x4e 0xeb -0xac 0x9d 0x8e 0x6b +0xac 0x29 0x4e 0x6b +0xac 0x29 0x4e 0xeb +0xac 0x1d 0x8e 0x6b 0xac 0x9d 0x8e 0xeb # CHECK: subs w12, w13, w14 # CHECK: subs x12, x13, x14 # CHECK: subs w12, w13, w14, lsl #12 # CHECK: subs x12, x13, x14, lsl #12 -# CHECK: subs w12, w13, w14, lsr #42 -# CHECK: subs x12, x13, x14, lsr #42 -# CHECK: subs w12, w13, w14, asr #39 +# CHECK: subs w12, w13, w14, lsr #10 +# CHECK: subs x12, x13, x14, lsr #10 +# CHECK: subs w12, w13, w14, asr #7 # CHECK: subs x12, x13, x14, asr #39 #==---------------------------------------------------------------------------== diff --git a/test/MC/Disassembler/ARM64/basic-a64-undefined.txt b/test/MC/Disassembler/ARM64/basic-a64-undefined.txt index 24be5c24dc5..88e43468ec5 100644 --- a/test/MC/Disassembler/ARM64/basic-a64-undefined.txt +++ b/test/MC/Disassembler/ARM64/basic-a64-undefined.txt @@ -13,4 +13,9 @@ # MOVK with sf == 0 and hw<1> == 1 is unallocated. # RUN: echo "0x00 0x00 0xc0 0x72" | llvm-mc -triple=arm64 -disassemble 2>&1 | FileCheck %s +# ADD/SUB (shifted register) are reserved if shift == '11' or sf == '0' and imm6<5> == '1'. +# RUN: echo "0x00 0x00 0xc0 0xeb" | llvm-mc -triple=arm64 -disassemble 2>&1 | FileCheck %s +# RUN: echo "0x00 0x80 0x80 0x6b" | llvm-mc -triple=arm64 -disassemble 2>&1 | FileCheck %s + + # CHECK: invalid instruction encoding