Index: lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- lib/Target/AArch64/AArch64InstrFormats.td +++ lib/Target/AArch64/AArch64InstrFormats.td @@ -4082,6 +4082,27 @@ let Inst{1-0} = ll; } +//--- +// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm. +//-- +def uimm16 : Operand, ImmLeaf{ + let ParserMatchClass = Imm0_65535Operand; + let PrintMethod = "printImm"; + let DecoderMethod = "DecodeUImm16"; +} + +let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in { +class UDFType opc, string asm> + : I<(outs), (ins uimm16:$imm), + asm, "\t$imm", "", []>, + Sched<[]> { + bits<16> imm; + let Inst{31-16} = opc; + let Inst{15-0} = imm; +} +} let Predicates = [HasFPARMv8] in { //--- Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -1594,6 +1594,8 @@ def : InstAlias<"dcps2", (DCPS2 0)>; def : InstAlias<"dcps3", (DCPS3 0)>; +def UDF : UDFType<0, "udf">; + //===----------------------------------------------------------------------===// // Load instructions. //===----------------------------------------------------------------------===// Index: lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp =================================================================== --- lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -225,6 +225,9 @@ uint64_t address, const void* Decoder); +static DecodeStatus DecodeUImm16(MCInst &Inst, uint32_t insn, uint64_t Address, + const void *Decoder); + static bool Check(DecodeStatus &Out, DecodeStatus In) { switch (In) { case MCDisassembler::Success: @@ -1023,6 +1026,21 @@ return Success; } +static DecodeStatus DecodeUImm16(MCInst &Inst, uint32_t insn, uint64_t Addr, + const void *Decoder) { + switch (Inst.getOpcode()) { + case AArch64::UDF: { + unsigned imm = fieldFromInstruction(insn, 0, 15); + Inst.addOperand(MCOperand::createImm(imm)); + return Success; + } + default: + assert(false && Inst.getOpcode() && "Don't know how to treat this opcode"); + break; + } + return Success; +} + static DecodeStatus DecodeUnsignedLdStInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr, const void *Decoder) { Index: test/MC/AArch64/udf-erros.s =================================================================== --- /dev/null +++ test/MC/AArch64/udf-erros.s @@ -0,0 +1,10 @@ +# RUN: not llvm-mc -assemble -show-encoding -triple=aarch64- %s 2>&1 | FileCheck %s + +udf 65536 +# CHECK:{{.*}} immediate must be an integer in range [0, 65535]. + +udf -1 +# CHECK:{{.*}} immediate must be an integer in range [0, 65535]. + +udf -768 +# CHECK:{{.*}} immediate must be an integer in range [0, 65535]. Index: test/MC/AArch64/udf.s =================================================================== --- /dev/null +++ test/MC/AArch64/udf.s @@ -0,0 +1,21 @@ +# RUN: llvm-mc -assemble -show-encoding -triple=aarch64- %s | FileCheck %s +.text +# CHECK: .text + +udf 0 +# CHECK-NEXT: udf #0 // encoding: [0x00,0x00,0x00,0x00] + +udf 1 +# CHECK-NEXT: udf #1 // encoding: [0x01,0x00,0x00,0x00] + +udf 16 +# CHECK-NEXT: udf #16 // encoding: [0x10,0x00,0x00,0x00] + +udf 32 +# CHECK-NEXT: udf #32 // encoding: [0x20,0x00,0x00,0x00] + +udf 48 +# CHECK-NEXT: udf #48 // encoding: [0x30,0x00,0x00,0x00] + +udf 65535 +# CHECK-NEXT: udf #65535 // encoding: [0xff,0xff,0x00,0x00] Index: test/MC/Disassembler/AArch64/udf.txt =================================================================== --- /dev/null +++ test/MC/Disassembler/AArch64/udf.txt @@ -0,0 +1,38 @@ +# RUN: llvm-mc -arch aarch64 -disassemble -o - %s | FileCheck %s + +# RUN: llvm-mc -arch aarch64 -disassemble -o - %s | \ +# RUN: llvm-mc -assemble -filetype=obj -arch aarch64 -o - | \ +# RUN: llvm-objdump -r -d --triple=arm64- - | \ +# RUN: FileCheck %s -check-prefix=OBJ + +# CHECK: .text +# OBJ: Disassembly of section .text: +# OBJ-NEXT: $x.0: + +[0x00,0x00,0x00,0x00] +# CHECK-NEXT: udf #0 +# OBJ-NEXT: 0: 00 00 00 00 udf #0 + +[0x01,0x00,0x00,0x00] +# CHECK-NEXT: udf #1 +# OBJ-NEXT: 4: 01 00 00 00 udf #1 + +[0x10,0x00,0x00,0x00] +# CHECK-NEXT: udf #16 +# OBJ-NEXT: 8: 10 00 00 00 udf #16 + +[0x20,0x00,0x00,0x00] +# CHECK-NEXT: udf #32 +# OBJ-NEXT: c: 20 00 00 00 udf #32 + +[0x30,0x00,0x00,0x00] +# CHECK-NEXT: udf #48 +# OBJ-NEXT: 10: 30 00 00 00 udf #48 + +[0xff,0xff,0x00,0x00] +# CHECK-NEXT: udf #32767 +# OBJ-NEXT: 14: ff 7f 00 00 udf #32767 + +[0x00,0xfd,0x00,0x00] +# CHECK-NEXT: udf #32000 +# OBJ-NEXT: 18: 00 7d 00 00 udf #32000