1// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s 2 3include "llvm/Target/Target.td" 4 5def ArchInstrInfo : InstrInfo { } 6 7def Arch : Target { 8 let InstructionSet = ArchInstrInfo; 9} 10 11def Reg : Register<"reg">; 12 13def RegClass : RegisterClass<"foo", [i64], 0, (add Reg)>; 14 15def GR64 : RegisterOperand<RegClass>; 16 17class MyMemOperand<dag sub_ops> : Operand<iPTR> { 18 let MIOperandInfo = sub_ops; 19 dag Base; 20 dag Extension; 21} 22 23def MemOp16: MyMemOperand<(ops GR64:$reg, i16imm:$offset)>; 24 25def MemOp32: MyMemOperand<(ops GR64:$reg, i32imm:$offset)>; 26 27class MyVarInst<MyMemOperand memory_op> : Instruction { 28 dag Inst; 29 30 let OutOperandList = (outs GR64:$dst); 31 let InOperandList = (ins memory_op:$src); 32} 33 34def FOO16 : MyVarInst<MemOp16> { 35 let Inst = (ascend 36 (descend (operand "$dst", 3), 0b01000, (operand "$src.reg", 3)), 37 (slice "$src.offset", 15, 0, (decoder "myCustomDecoder")) 38 ); 39} 40def FOO32 : MyVarInst<MemOp32> { 41 let Inst = (ascend 42 (descend (operand "$dst", 3), 0b01001, 43 (operand "$src.reg", 3, (decoder "myCustomDecoder"))), 44 (slice "$src.offset", 31, 16), 45 (slice "$src.offset", 15, 0) 46 ); 47} 48 49// CHECK: MCD::OPC_ExtractField, 3, 5, // Inst{7-3} ... 50// CHECK-NEXT: MCD::OPC_FilterValue, 8, 4, 0, 0, // Skip to: 12 51// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 0, // Opcode: FOO16 52// CHECK-NEXT: MCD::OPC_FilterValue, 9, 4, 0, 0, // Skip to: 21 53// CHECK-NEXT: MCD::OPC_Decode, {{[0-9]+}}, {{[0-9]+}}, 1, // Opcode: FOO32 54// CHECK-NEXT: MCD::OPC_Fail, 55 56// Instruction length table 57// CHECK: 27, 58// CHECK-NEXT: 43, 59// CHECK-NEXT: }; 60 61// CHECK: case 0: 62// CHECK-NEXT: tmp = fieldFromInstruction(insn, 8, 3); 63// CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; } 64// CHECK-NEXT: tmp = fieldFromInstruction(insn, 0, 3); 65// CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; } 66// CHECK-NEXT: tmp = fieldFromInstruction(insn, 11, 16); 67// CHECK-NEXT: if (!Check(S, myCustomDecoder(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; } 68// CHECK-NEXT: return S; 69// CHECK-NEXT: case 1: 70// CHECK-NEXT: tmp = fieldFromInstruction(insn, 8, 3); 71// CHECK-NEXT: if (!Check(S, DecodeRegClassRegisterClass(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; } 72// CHECK-NEXT: tmp = fieldFromInstruction(insn, 0, 3); 73// CHECK-NEXT: if (!Check(S, myCustomDecoder(MI, tmp, Address, Decoder))) { return MCDisassembler::Fail; } 74// CHECK-NEXT: tmp = 0x0; 75// CHECK-NEXT: insertBits(tmp, fieldFromInstruction(insn, 11, 16), 16, 16); 76// CHECK-NEXT: insertBits(tmp, fieldFromInstruction(insn, 27, 16), 0, 16); 77// CHECK-NEXT: MI.addOperand(MCOperand::createImm(tmp)); 78// CHECK-NEXT: return S; 79 80// CHECK-LABEL: case MCD::OPC_ExtractField: { 81// CHECK: makeUp(insn, Start + Len); 82 83// CHECK-LABEL: case MCD::OPC_CheckField: { 84// CHECK: makeUp(insn, Start + Len); 85 86// CHECK-LABEL: case MCD::OPC_Decode: { 87// CHECK: Len = InstrLenTable[Opc]; 88// CHECK-NEXT: makeUp(insn, Len); 89