1// RUN: llvm-tblgen -gen-emitter -I %p/../../include %s | \ 2// RUN: FileCheck %s --check-prefix=ENCODER 3// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | \ 4// RUN: FileCheck %s --check-prefix=DECODER 5// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O1 -I \ 6// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS-O1 7// RUN: llvm-tblgen -gen-disassembler --suppress-per-hwmode-duplicates=O2 -I \ 8// RUN: %p/../../include %s | FileCheck %s --check-prefix=DECODER-SUPPRESS-O2 9 10include "llvm/Target/Target.td" 11 12def archInstrInfo : InstrInfo { } 13 14def arch : Target { 15 let InstructionSet = archInstrInfo; 16} 17 18def Myi32 : Operand<i32> { 19 let DecoderMethod = "DecodeMyi32"; 20} 21 22def HasA : Predicate<"Subtarget->hasA()">; 23def HasB : Predicate<"Subtarget->hasB()">; 24 25def ModeA : HwMode<"+a", [HasA]>; // Mode 1 26def ModeB : HwMode<"+b", [HasB]>; // Mode 2 27def ModeC : HwMode<"+c", []>; // Mode 3 28 29 30def fooTypeEncDefault : InstructionEncoding { 31 let Size = 8; 32 field bits<64> SoftFail = 0; 33 bits<64> Inst; 34 bits<8> factor; 35 let Inst{7...0} = factor; 36 let Inst{3...2} = 0b10; 37 let Inst{1...0} = 0b00; 38} 39 40def fooTypeEncA : InstructionEncoding { 41 let Size = 4; 42 field bits<32> SoftFail = 0; 43 bits<32> Inst; 44 bits<8> factor; 45 let Inst{7...0} = factor; 46 let Inst{3...2} = 0b11; 47 let Inst{1...0} = 0b00; 48} 49 50def fooTypeEncB : InstructionEncoding { 51 let Size = 4; 52 field bits<32> SoftFail = 0; 53 bits<32> Inst; 54 bits<8> factor; 55 let Inst{15...8} = factor; 56 let Inst{1...0} = 0b11; 57} 58 59def fooTypeEncC : InstructionEncoding { 60 let Size = 4; 61 field bits<32> SoftFail = 0; 62 bits<32> Inst; 63 bits<8> factor; 64 let Inst{31...24} = factor; 65 let Inst{23...21} = 0b110; 66 let Inst{1...0} = 0b11; 67} 68 69// Test for DefaultMode as a selector. 70def foo : Instruction { 71 let OutOperandList = (outs); 72 let InOperandList = (ins i32imm:$factor); 73 let EncodingInfos = EncodingByHwMode< 74 [ModeC, ModeA, ModeB, DefaultMode], 75 [fooTypeEncC, fooTypeEncA, fooTypeEncB, fooTypeEncDefault]>; 76 let AsmString = "foo $factor"; 77} 78 79def bar: Instruction { 80 let OutOperandList = (outs); 81 let InOperandList = (ins i32imm:$factor); 82 let Size = 4; 83 bits<32> Inst; 84 bits<32> SoftFail; 85 bits<8> factor; 86 let Inst{31...24} = factor; 87 let Inst{1...0} = 0b10; 88 let AsmString = "bar $factor"; 89} 90 91def baz : Instruction { 92 let OutOperandList = (outs); 93 let InOperandList = (ins i32imm:$factor); 94 bits<32> Inst; 95 let EncodingInfos = EncodingByHwMode< 96 [ModeB], [fooTypeEncA] 97 >; 98 let AsmString = "foo $factor"; 99} 100 101def unrelated: Instruction { 102 let OutOperandList = (outs); 103 let DecoderNamespace = "Alt"; 104 let InOperandList = (ins i32imm:$factor); 105 let Size = 4; 106 bits<32> Inst; 107 bits<32> SoftFail; 108 bits<8> factor; 109 let Inst{31...24} = factor; 110 let Inst{1...0} = 0b10; 111 let AsmString = "unrelated $factor"; 112} 113 114 115// Under default settings, using 'HwMode' to dictate instruction encodings results in 116// significant duplication of DecoderTables. The four tables ‘DecoderTableAlt32’, 117// ‘DecoderTableAlt_ModeA32’, ‘DecoderTableAlt_ModeB32’ and 'DecoderTable_ModeC32' are 118// exact duplicates and could effectively be merged into one. 119// DECODER-LABEL: DecoderTable32[] = 120// DECODER-DAG: Opcode: bar 121// DECODER-LABEL: DecoderTable64[] = 122// DECODER-DAG: Opcode: fooTypeEncDefault:foo 123// DECODER-LABEL: DecoderTableAlt32[] = 124// DECODER-DAG: Opcode: unrelated 125// DECODER-LABEL: DecoderTableAlt_ModeA32[] = 126// DECODER-DAG: Opcode: unrelated 127// DECODER-LABEL: DecoderTableAlt_ModeB32[] = 128// DECODER-DAG: Opcode: unrelated 129// DECODER-LABEL: DecoderTableAlt_ModeC32[] = 130// DECODER-DAG: Opcode: unrelated 131// DECODER-LABEL: DecoderTable_ModeA32[] = 132// DECODER-DAG: Opcode: fooTypeEncA:foo 133// DECODER-DAG: Opcode: bar 134// DECODER-LABEL: DecoderTable_ModeB32[] = 135// DECODER-DAG: Opcode: fooTypeEncB:foo 136// DECODER-DAG: Opcode: fooTypeEncA:baz 137// DECODER-DAG: Opcode: bar 138// DECODER-LABEL: DecoderTable_ModeC32[] = 139// DECODER-DAG: Opcode: fooTypeEncC:foo 140// DECODER-DAG: Opcode: bar 141 142// Under the 'O1' optimization level, unnecessary duplicate tables will be eliminated, 143// reducing the four ‘Alt’ tables down to just one. 144// DECODER-SUPPRESS-O1-LABEL: DecoderTable32[] = 145// DECODER-SUPPRESS-O1-DAG: Opcode: bar 146// DECODER-SUPPRESS-O1-LABEL: DecoderTable64[] = 147// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncDefault:foo 148// DECODER-SUPPRESS-O1-LABEL: DecoderTableAlt32[] = 149// DECODER-SUPPRESS-O1-DAG: Opcode: unrelated 150// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeA32[] = 151// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:foo 152// DECODER-SUPPRESS-O1-DAG: Opcode: bar 153// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeB32[] = 154// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncB:foo 155// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncA:baz 156// DECODER-SUPPRESS-O1-DAG: Opcode: bar 157// DECODER-SUPPRESS-O1-LABEL: DecoderTable_ModeC32[] = 158// DECODER-SUPPRESS-O1-DAG: Opcode: fooTypeEncC:foo 159// DECODER-SUPPRESS-O1-DAG: Opcode: bar 160 161// Under the 'O2' optimization condition, instructions possessing the 'EncodingByHwMode' 162// attribute will be extracted from their original DecoderNamespace and placed into their 163// respective HwMode tables. Meanwhile, other instructions that do not have the 'EncodingByHwMode' 164// attribute but are within the same DecoderNamespace will be stored in the 'Default' table. This 165// approach will significantly reduce instruction redundancy, but it necessitates users to thoroughly 166// consider the interplay between HwMode and DecoderNamespace for their instructions. 167// DECODER-SUPPRESS-O2-LABEL: DecoderTable32[] = 168// DECODER-SUPPRESS-O2-DAG: Opcode: bar 169// DECODER-SUPPRESS-O2-LABEL: DecoderTable64[] = 170// DECODER-SUPPRESS-O2-NOT: Opcode: bar 171// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncDefault:foo 172// DECODER-SUPPRESS-O2-LABEL: DecoderTableAlt32[] = 173// DECODER-SUPPRESS-O2-DAG: Opcode: unrelated 174// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeA32[] = 175// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:foo 176// DECODER-SUPPRESS-O2-NOT: Opcode: bar 177// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeB32[] = 178// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncB:foo 179// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncA:baz 180// DECODER-SUPPRESS-O2-NOT: Opcode: bar 181// DECODER-SUPPRESS-O2-LABEL: DecoderTable_ModeC32[] = 182// DECODER-SUPPRESS-O2-DAG: Opcode: fooTypeEncC:foo 183// DECODER-SUPPRESS-O2-NOT: Opcode: bar 184 185// For 'bar' and 'unrelated', we didn't assign any HwModes for them, 186// they should keep the same in the following four tables. 187// For 'foo' we assigned four HwModes( includes 'DefaultMode' ), 188// it's encodings should be different in the following four tables. 189// For 'baz' we only assigned ModeB for it, so it will be presented 190// as '0' in the tables of ModeA, ModeC and Default Mode. 191// ENCODER-LABEL: static const uint64_t InstBits[] = { 192// ENCODER: UINT64_C(2), // bar 193// ENCODER: UINT64_C(0), // baz 194// ENCODER: UINT64_C(8), // foo 195// ENCODER: UINT64_C(2), // unrelated 196// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = { 197// ENCODER: UINT64_C(2), // bar 198// ENCODER: UINT64_C(0), // baz 199// ENCODER: UINT64_C(12), // foo 200// ENCODER: UINT64_C(2), // unrelated 201// ENCODER-LABEL: static const uint64_t InstBits_ModeB[] = { 202// ENCODER: UINT64_C(2), // bar 203// ENCODER: UINT64_C(12), // baz 204// ENCODER: UINT64_C(3), // foo 205// ENCODER: UINT64_C(2), // unrelated 206// ENCODER-LABEL: static const uint64_t InstBits_ModeC[] = { 207// ENCODER: UINT64_C(2), // bar 208// ENCODER: UINT64_C(0), // baz 209// ENCODER: UINT64_C(12582915), // foo 210// ENCODER: UINT64_C(2), // unrelated 211 212// ENCODER-LABEL: case ::bar: 213// ENCODER-LABEL: case ::unrelated: 214// ENCODER-NOT: getHwMode 215// ENCODER-LABEL: case ::foo: { 216// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo); 217// ENCODER: switch (HwMode) { 218// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break; 219// ENCODER: case 0: InstBitsByHw = InstBits; break; 220// ENCODER: case 1: InstBitsByHw = InstBits_ModeA; break; 221// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break; 222// ENCODER: case 3: InstBitsByHw = InstBits_ModeC; break; 223// ENCODER: }; 224// ENCODER: Value = InstBitsByHw[opcode]; 225// ENCODER: switch (HwMode) { 226// ENCODER: default: llvm_unreachable("Unhandled HwMode"); 227// ENCODER: case 0: { 228// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI); 229// ENCODER: op &= UINT64_C(240); 230// ENCODER: Value |= op; 231// ENCODER: break; 232// ENCODER: } 233// ENCODER: case 1: { 234// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI); 235// ENCODER: op &= UINT64_C(240); 236// ENCODER: Value |= op; 237// ENCODER: break; 238// ENCODER: } 239// ENCODER: case 2: { 240// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI); 241// ENCODER: op &= UINT64_C(255); 242// ENCODER: op <<= 8; 243// ENCODER: Value |= op; 244// ENCODER: break; 245// ENCODER: } 246// ENCODER: case 3: { 247// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI); 248// ENCODER: op &= UINT64_C(255); 249// ENCODER: op <<= 24; 250// ENCODER: Value |= op; 251// ENCODER: break; 252// ENCODER: } 253// ENCODER-LABEL: case ::baz: { 254// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo); 255// ENCODER: switch (HwMode) { 256// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break; 257// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break; 258// ENCODER: }; 259// ENCODER: Value = InstBitsByHw[opcode]; 260// ENCODER: switch (HwMode) { 261// ENCODER: default: llvm_unreachable("Unhandled HwMode"); 262// ENCODER: case 2: { 263// ENCODER: op = getMachineOpValue(MI, MI.getOperand(0), Fixups, STI); 264// ENCODER: op &= UINT64_C(240); 265// ENCODER: Value |= op; 266// ENCODER: break; 267// ENCODER: } 268