|
| 1 | +// This testcase is to test the correctness of HwMode encoding under the 'APInt' Mode. |
| 2 | +// RUN: llvm-tblgen -gen-emitter -I %p/../../include %s | \ |
| 3 | +// RUN: FileCheck %s --check-prefix=ENCODER |
| 4 | + |
| 5 | +include "llvm/Target/Target.td" |
| 6 | + |
| 7 | +def archInstrInfo : InstrInfo { } |
| 8 | + |
| 9 | +def arch : Target { |
| 10 | + let InstructionSet = archInstrInfo; |
| 11 | +} |
| 12 | + |
| 13 | +def Myi32 : Operand<i32> { |
| 14 | + let DecoderMethod = "DecodeMyi32"; |
| 15 | +} |
| 16 | + |
| 17 | +def HasA : Predicate<"Subtarget->hasA()">; |
| 18 | +def HasB : Predicate<"Subtarget->hasB()">; |
| 19 | + |
| 20 | +def ModeA : HwMode<"+a", [HasA]>; // Mode 1 |
| 21 | +def ModeB : HwMode<"+b", [HasB]>; // Mode 2 |
| 22 | +def ModeC : HwMode<"+c", []>; // Mode 3 |
| 23 | + |
| 24 | + |
| 25 | +def fooTypeEncDefault : InstructionEncoding { |
| 26 | + let Size = 16; |
| 27 | + field bits<128> SoftFail = 0; |
| 28 | + bits<128> Inst; |
| 29 | + bits<8> factor; |
| 30 | + let Inst{127...120} = factor; |
| 31 | + let Inst{3...2} = 0b10; |
| 32 | + let Inst{1...0} = 0b00; |
| 33 | +} |
| 34 | + |
| 35 | +def fooTypeEncA : InstructionEncoding { |
| 36 | + let Size = 16; |
| 37 | + field bits<128> SoftFail = 0; |
| 38 | + bits<128> Inst; |
| 39 | + bits<8> factor; |
| 40 | + let Inst{119...112} = factor; |
| 41 | + let Inst{3...2} = 0b11; |
| 42 | + let Inst{1...0} = 0b00; |
| 43 | +} |
| 44 | + |
| 45 | +def fooTypeEncB : InstructionEncoding { |
| 46 | + let Size = 16; |
| 47 | + field bits<128> SoftFail = 0; |
| 48 | + bits<128> Inst; |
| 49 | + bits<8> factor; |
| 50 | + let Inst{119...112} = factor; |
| 51 | + let Inst{111...110} = 0b11; |
| 52 | +} |
| 53 | + |
| 54 | +def fooTypeEncC : InstructionEncoding { |
| 55 | + let Size = 16; |
| 56 | + field bits<128> SoftFail = 0; |
| 57 | + bits<128> Inst; |
| 58 | + bits<8> factor; |
| 59 | + let Inst{31...24} = factor; |
| 60 | + let Inst{23...21} = 0b110; |
| 61 | + let Inst{1...0} = 0b11; |
| 62 | +} |
| 63 | + |
| 64 | +// Test for DefaultMode as a selector. |
| 65 | +def foo : Instruction { |
| 66 | + bits<128> Inst; |
| 67 | + let OutOperandList = (outs); |
| 68 | + let InOperandList = (ins i32imm:$factor); |
| 69 | + let EncodingInfos = EncodingByHwMode< |
| 70 | + [ModeC, ModeA, ModeB, DefaultMode], |
| 71 | + [fooTypeEncC, fooTypeEncA, fooTypeEncB, fooTypeEncDefault]>; |
| 72 | + let AsmString = "foo $factor"; |
| 73 | +} |
| 74 | + |
| 75 | +def bar: Instruction { |
| 76 | + let OutOperandList = (outs); |
| 77 | + let InOperandList = (ins i32imm:$factor); |
| 78 | + let Size = 4; |
| 79 | + bits<32> Inst; |
| 80 | + bits<32> SoftFail; |
| 81 | + bits<8> factor; |
| 82 | + let Inst{31...24} = factor; |
| 83 | + let Inst{1...0} = 0b10; |
| 84 | + let AsmString = "bar $factor"; |
| 85 | +} |
| 86 | + |
| 87 | +def baz : Instruction { |
| 88 | + let OutOperandList = (outs); |
| 89 | + let InOperandList = (ins i32imm:$factor); |
| 90 | + bits<32> Inst; |
| 91 | + let EncodingInfos = EncodingByHwMode< |
| 92 | + [ModeB], [fooTypeEncA] |
| 93 | + >; |
| 94 | + let AsmString = "foo $factor"; |
| 95 | +} |
| 96 | + |
| 97 | +def unrelated: Instruction { |
| 98 | + let OutOperandList = (outs); |
| 99 | + let DecoderNamespace = "Alt"; |
| 100 | + let InOperandList = (ins i32imm:$factor); |
| 101 | + let Size = 4; |
| 102 | + bits<32> Inst; |
| 103 | + bits<32> SoftFail; |
| 104 | + bits<8> factor; |
| 105 | + let Inst{31...24} = factor; |
| 106 | + let Inst{1...0} = 0b10; |
| 107 | + let AsmString = "unrelated $factor"; |
| 108 | +} |
| 109 | + |
| 110 | +// For 'bar' and 'unrelated', we didn't assign any HwModes for them, |
| 111 | +// they should keep the same in the following four tables. |
| 112 | +// For 'foo' we assigned four HwModes( includes 'DefaultMode' ), |
| 113 | +// it's encodings should be different in the following four tables. |
| 114 | +// For 'baz' we only assigned ModeB for it, so it will be presented |
| 115 | +// as '0' in the tables of ModeA, ModeC and Default Mode. |
| 116 | +// ENCODER-LABEL: static const uint64_t InstBits[] = { |
| 117 | +// ENCODER: UINT64_C(2), UINT64_C(0), // bar |
| 118 | +// ENCODER: UINT64_C(0), UINT64_C(0), // baz |
| 119 | +// ENCODER: UINT64_C(8), UINT64_C(0), // foo |
| 120 | +// ENCODER: UINT64_C(2), UINT64_C(0), // unrelated |
| 121 | +// ENCODER-LABEL: static const uint64_t InstBits_ModeA[] = { |
| 122 | +// ENCODER: UINT64_C(2), UINT64_C(0), // bar |
| 123 | +// ENCODER: UINT64_C(0), UINT64_C(0), // baz |
| 124 | +// ENCODER: UINT64_C(12), UINT64_C(0), // foo |
| 125 | +// ENCODER: UINT64_C(2), UINT64_C(0), // unrelated |
| 126 | +// ENCODER-LABEL: static const uint64_t InstBits_ModeB[] = { |
| 127 | +// ENCODER: UINT64_C(2), UINT64_C(0), // bar |
| 128 | +// ENCODER: UINT64_C(12), UINT64_C(0), // baz |
| 129 | +// ENCODER: UINT64_C(0), UINT64_C(211106232532992), // foo |
| 130 | +// ENCODER: UINT64_C(2), UINT64_C(0), // unrelated |
| 131 | +// ENCODER-LABEL: static const uint64_t InstBits_ModeC[] = { |
| 132 | +// ENCODER: UINT64_C(2), UINT64_C(0), // bar |
| 133 | +// ENCODER: UINT64_C(0), UINT64_C(0), // baz |
| 134 | +// ENCODER: UINT64_C(12582915), UINT64_C(0), // foo |
| 135 | +// ENCODER: UINT64_C(2), UINT64_C(0), // unrelated |
| 136 | + |
| 137 | + |
| 138 | +// ENCODER: const uint64_t *InstBitsByHw; |
| 139 | +// ENCODER: const unsigned opcode = MI.getOpcode(); |
| 140 | +// ENCODER: if (Scratch.getBitWidth() != 128) |
| 141 | +// ENCODER: Scratch = Scratch.zext(128); |
| 142 | +// ENCODER: Inst = APInt(128, ArrayRef(InstBits + opcode * 2, 2)); |
| 143 | +// ENCODER: APInt &Value = Inst; |
| 144 | +// ENCODER: APInt &op = Scratch; |
| 145 | +// ENCODER: switch (opcode) { |
| 146 | +// ENCODER-LABEL: case ::bar: |
| 147 | +// ENCODER-LABEL: case ::unrelated: |
| 148 | +// ENCODER-NOT: getHwMode |
| 149 | +// ENCODER-LABEL: case ::foo: { |
| 150 | +// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo); |
| 151 | +// ENCODER: switch (HwMode) { |
| 152 | +// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break; |
| 153 | +// ENCODER: case 0: InstBitsByHw = InstBits; break; |
| 154 | +// ENCODER: case 1: InstBitsByHw = InstBits_ModeA; break; |
| 155 | +// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break; |
| 156 | +// ENCODER: case 3: InstBitsByHw = InstBits_ModeC; break; |
| 157 | +// ENCODER: }; |
| 158 | +// ENCODER: Inst = APInt(128, ArrayRef(InstBitsByHw + opcode * 2, 2)); |
| 159 | +// ENCODER: Value = Inst; |
| 160 | +// ENCODER: switch (HwMode) { |
| 161 | +// ENCODER: default: llvm_unreachable("Unhandled HwMode"); |
| 162 | +// ENCODER: case 0: { |
| 163 | +// ENCODER: op.clearAllBits(); |
| 164 | +// ENCODER: getMachineOpValue(MI, MI.getOperand(0), op, Fixups, STI); |
| 165 | +// ENCODER: Value.insertBits(op.extractBitsAsZExtValue(8, 0), 120, 8); |
| 166 | +// ENCODER: break; |
| 167 | +// ENCODER: } |
| 168 | +// ENCODER: case 1: { |
| 169 | +// ENCODER: op.clearAllBits(); |
| 170 | +// ENCODER: getMachineOpValue(MI, MI.getOperand(0), op, Fixups, STI); |
| 171 | +// ENCODER: Value.insertBits(op.extractBitsAsZExtValue(8, 0), 112, 8); |
| 172 | +// ENCODER: break; |
| 173 | +// ENCODER: } |
| 174 | +// ENCODER: case 2: { |
| 175 | +// ENCODER: op.clearAllBits(); |
| 176 | +// ENCODER: getMachineOpValue(MI, MI.getOperand(0), op, Fixups, STI); |
| 177 | +// ENCODER: Value.insertBits(op.extractBitsAsZExtValue(8, 0), 112, 8); |
| 178 | +// ENCODER: break; |
| 179 | +// ENCODER: } |
| 180 | +// ENCODER: case 3: { |
| 181 | +// ENCODER: op.clearAllBits(); |
| 182 | +// ENCODER: getMachineOpValue(MI, MI.getOperand(0), op, Fixups, STI); |
| 183 | +// ENCODER: Value.insertBits(op.extractBitsAsZExtValue(8, 0), 24, 8); |
| 184 | +// ENCODER: break; |
| 185 | +// ENCODER: } |
| 186 | +// ENCODER-LABEL: case ::baz: { |
| 187 | +// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo); |
| 188 | +// ENCODER: switch (HwMode) { |
| 189 | +// ENCODER: default: llvm_unreachable("Unknown hardware mode!"); break; |
| 190 | +// ENCODER: case 2: InstBitsByHw = InstBits_ModeB; break; |
| 191 | +// ENCODER: }; |
| 192 | +// ENCODER: Inst = APInt(128, ArrayRef(InstBitsByHw + opcode * 2, 2)); |
| 193 | +// ENCODER: Value = Inst; |
| 194 | +// ENCODER: switch (HwMode) { |
| 195 | +// ENCODER: default: llvm_unreachable("Unhandled HwMode"); |
| 196 | +// ENCODER: case 2: { |
| 197 | +// ENCODER: getMachineOpValue(MI, MI.getOperand(0), op, Fixups, STI); |
| 198 | +// ENCODER: Value.insertBits(op.extractBitsAsZExtValue(8, 0), 112, 8); |
| 199 | +// ENCODER: break; |
| 200 | +// ENCODER: } |
| 201 | + |
| 202 | +// ENCODER-LABEL: uint32_t archMCCodeEmitter::getOperandBitOffset |
| 203 | +// ENCODER: switch (MI.getOpcode()) { |
| 204 | +// ENCODER-LABEL: case ::bar: |
| 205 | +// ENCODER-LABEL: case ::unrelated: { |
| 206 | +// ENCODER-NOT: getHwMode |
| 207 | +// ENCODER-LABEL: case ::foo: { |
| 208 | +// ENCODER: unsigned HwMode = STI.getHwMode(MCSubtargetInfo::HwMode_EncodingInfo); |
| 209 | +// ENCODER: switch (HwMode) { |
| 210 | +// ENCODER: default: llvm_unreachable("Unhandled HwMode"); |
| 211 | +// ENCODER: case 0: { |
| 212 | +// ENCODER: switch (OpNum) { |
| 213 | +// ENCODER: case 0: |
| 214 | +// ENCODER: return 120; |
| 215 | +// ENCODER: } |
| 216 | +// ENCODER: break; |
| 217 | +// ENCODER: } |
| 218 | +// ENCODER: case 1: { |
| 219 | +// ENCODER: switch (OpNum) { |
| 220 | +// ENCODER: case 0: |
| 221 | +// ENCODER: return 112; |
| 222 | +// ENCODER: } |
| 223 | +// ENCODER: break; |
| 224 | +// ENCODER: } |
| 225 | +// ENCODER: case 2: { |
| 226 | +// ENCODER: switch (OpNum) { |
| 227 | +// ENCODER: case 0: |
| 228 | +// ENCODER: return 112; |
| 229 | +// ENCODER: } |
| 230 | +// ENCODER: break; |
| 231 | +// ENCODER: } |
| 232 | +// ENCODER: case 3: { |
| 233 | +// ENCODER: switch (OpNum) { |
| 234 | +// ENCODER: case 0: |
| 235 | +// ENCODER: return 24; |
| 236 | +// ENCODER: } |
| 237 | +// ENCODER: break; |
| 238 | +// ENCODER: } |
| 239 | +// ENCODER: } |
| 240 | +// ENCODER: break; |
| 241 | +// ENCODER: } |
0 commit comments