|
| 1 | +// This is to test the scenario where different HwMode attributes coexist. |
| 2 | +// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-REG |
| 3 | +// RUN: llvm-tblgen -gen-subtarget -I %p/../../include %s -o - 2>&1 | FileCheck %s --check-prefix=CHECK-SUBTARGET |
| 4 | + |
| 5 | + |
| 6 | +include "llvm/Target/Target.td" |
| 7 | + |
| 8 | +def TestTargetInstrInfo : InstrInfo; |
| 9 | + |
| 10 | +def TestTarget : Target { |
| 11 | + let InstructionSet = TestTargetInstrInfo; |
| 12 | +} |
| 13 | + |
| 14 | +def TestMode : HwMode<"+feat", []>; |
| 15 | +def TestMode1 : HwMode<"+feat1", []>; |
| 16 | +def TestMode2 : HwMode<"+feat2", []>; |
| 17 | + |
| 18 | +class MyReg<string n> |
| 19 | + : Register<n> { |
| 20 | + let Namespace = "Test"; |
| 21 | +} |
| 22 | + |
| 23 | +class MyClass<int size, list<ValueType> types, dag registers> |
| 24 | + : RegisterClass<"Test", types, size, registers> { |
| 25 | + let Size = size; |
| 26 | +} |
| 27 | + |
| 28 | +def X0 : MyReg<"x0">; |
| 29 | +def X1 : MyReg<"x1">; |
| 30 | +def X2 : MyReg<"x2">; |
| 31 | +def X3 : MyReg<"x3">; |
| 32 | +def X4 : MyReg<"x4">; |
| 33 | +def X5 : MyReg<"x5">; |
| 34 | +def X6 : MyReg<"x6">; |
| 35 | +def X7 : MyReg<"x7">; |
| 36 | +def X8 : MyReg<"x8">; |
| 37 | +def X9 : MyReg<"x9">; |
| 38 | +def X10 : MyReg<"x10">; |
| 39 | +def X11 : MyReg<"x11">; |
| 40 | +def X12 : MyReg<"x12">; |
| 41 | +def X13 : MyReg<"x13">; |
| 42 | +def X14 : MyReg<"x14">; |
| 43 | +def X15 : MyReg<"x15">; |
| 44 | + |
| 45 | +def ValueModeVT : ValueTypeByHwMode<[DefaultMode, TestMode, TestMode1], |
| 46 | + [i32, i64, f32]>; |
| 47 | + |
| 48 | +let RegInfos = RegInfoByHwMode<[DefaultMode, TestMode], |
| 49 | + [RegInfo<32,32,32>, RegInfo<64,64,64>]> in |
| 50 | +def XRegs : MyClass<32, [ValueModeVT], (sequence "X%u", 0, 15)>; |
| 51 | + |
| 52 | +def sub_even : SubRegIndex<32> { |
| 53 | + let SubRegRanges = SubRegRangeByHwMode<[DefaultMode, TestMode], |
| 54 | + [SubRegRange<32>, SubRegRange<64>]>; |
| 55 | +} |
| 56 | +def sub_odd : SubRegIndex<32, 32> { |
| 57 | + let SubRegRanges = SubRegRangeByHwMode<[DefaultMode, TestMode], |
| 58 | + [SubRegRange<32, 32>, SubRegRange<64, 64>]>; |
| 59 | +} |
| 60 | + |
| 61 | +def XPairs : RegisterTuples<[sub_even, sub_odd], |
| 62 | + [(decimate (rotl XRegs, 0), 2), |
| 63 | + (decimate (rotl XRegs, 1), 2)]>; |
| 64 | + |
| 65 | +let RegInfos = RegInfoByHwMode<[DefaultMode, TestMode], |
| 66 | + [RegInfo<64,64,32>, RegInfo<128,128,64>]> in |
| 67 | +def XPairsClass : MyClass<64, [untyped], (add XPairs)>; |
| 68 | + |
| 69 | +// Modes who are not controlling Register related features will be manipulated |
| 70 | +// the same as DefaultMode. |
| 71 | +// CHECK-REG-LABEL: RegisterClass XRegs: |
| 72 | +// CHECK-REG: SpillSize: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 } |
| 73 | +// CHECK-REG: SpillAlignment: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 } |
| 74 | +// CHECK-REG: Regs: X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 |
| 75 | + |
| 76 | +// CHECK-REG-LABEL: RegisterClass XPairsClass: |
| 77 | +// CHECK-REG: SpillSize: { Default:64 TestMode:128 TestMode1:64 TestMode2:64 } |
| 78 | +// CHECK-REG: SpillAlignment: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 } |
| 79 | +// CHECK-REG: CoveredBySubRegs: 1 |
| 80 | +// CHECK-REG: Regs: X0_X1 X2_X3 X4_X5 X6_X7 X8_X9 X10_X11 X12_X13 X14_X15 |
| 81 | + |
| 82 | +// CHECK-REG-LABEL: SubRegIndex sub_even: |
| 83 | +// CHECK-REG: Offset: { Default:0 TestMode:0 TestMode1:0 TestMode2:0 } |
| 84 | +// CHECK-REG: Size: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 } |
| 85 | +// CHECK-REG-LABEL: SubRegIndex sub_odd: |
| 86 | +// CHECK-REG: Offset: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 } |
| 87 | +// CHECK-REG: Size: { Default:32 TestMode:64 TestMode1:32 TestMode2:32 } |
| 88 | + |
| 89 | +//============================================================================// |
| 90 | +//--------------------- Encoding/Decoding parts ------------------------------// |
| 91 | +//============================================================================// |
| 92 | +def fooTypeEncDefault : InstructionEncoding { |
| 93 | + let Size = 8; |
| 94 | + field bits<64> SoftFail = 0; |
| 95 | + bits<64> Inst; |
| 96 | + bits<8> factor; |
| 97 | + let Inst{7...0} = factor; |
| 98 | + let Inst{3...2} = 0b10; |
| 99 | + let Inst{1...0} = 0b00; |
| 100 | +} |
| 101 | + |
| 102 | +def fooTypeEncA : InstructionEncoding { |
| 103 | + let Size = 4; |
| 104 | + field bits<32> SoftFail = 0; |
| 105 | + bits<32> Inst; |
| 106 | + bits<8> factor; |
| 107 | + let Inst{7...0} = factor; |
| 108 | + let Inst{3...2} = 0b11; |
| 109 | + let Inst{1...0} = 0b00; |
| 110 | +} |
| 111 | + |
| 112 | + |
| 113 | +def foo : Instruction { |
| 114 | + bits<32> Inst; |
| 115 | + let OutOperandList = (outs); |
| 116 | + let InOperandList = (ins i32imm:$factor); |
| 117 | + let EncodingInfos = EncodingByHwMode< |
| 118 | + [TestMode2, DefaultMode], [fooTypeEncA, fooTypeEncDefault] |
| 119 | + >; |
| 120 | + let AsmString = "foo $factor"; |
| 121 | +} |
| 122 | + |
| 123 | +// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenSubtargetInfo::getHwModeSet() const { |
| 124 | +// CHECK-SUBTARGET: unsigned Modes = 0; |
| 125 | +// CHECK-SUBTARGET: if (checkFeatures("+feat")) Modes |= (1 << 0); |
| 126 | +// CHECK-SUBTARGET: if (checkFeatures("+feat1")) Modes |= (1 << 1); |
| 127 | +// CHECK-SUBTARGET: if (checkFeatures("+feat2")) Modes |= (1 << 2); |
| 128 | +// CHECK-SUBTARGET: return Modes; |
| 129 | +// CHECK-SUBTARGET: } |
| 130 | +// CHECK-SUBTARGET-LABEL: unsigned TestTargetGenSubtargetInfo::getHwMode(enum HwModeType type) const { |
| 131 | +// CHECK-SUBTARGET: unsigned Modes = getHwModeSet(); |
| 132 | +// CHECK-SUBTARGET: if (!Modes) |
| 133 | +// CHECK-SUBTARGET: return Modes; |
| 134 | +// CHECK-SUBTARGET: switch (type) { |
| 135 | +// CHECK-SUBTARGET: case HwMode_Default: |
| 136 | +// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1; |
| 137 | +// CHECK-SUBTARGET: case HwMode_ValueType: |
| 138 | +// CHECK-SUBTARGET: Modes &= 3; |
| 139 | +// CHECK-SUBTARGET: if (!Modes) |
| 140 | +// CHECK-SUBTARGET: return Modes; |
| 141 | +// CHECK-SUBTARGET: if (!llvm::has_single_bit<unsigned>(Modes)) |
| 142 | +// CHECK-SUBTARGET: llvm_unreachable("Two or more HwModes for ValueType were found!"); |
| 143 | +// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1; |
| 144 | +// CHECK-SUBTARGET: case HwMode_RegInfo: |
| 145 | +// CHECK-SUBTARGET: Modes &= 1; |
| 146 | +// CHECK-SUBTARGET: if (!Modes) |
| 147 | +// CHECK-SUBTARGET: return Modes; |
| 148 | +// CHECK-SUBTARGET: if (!llvm::has_single_bit<unsigned>(Modes)) |
| 149 | +// CHECK-SUBTARGET: llvm_unreachable("Two or more HwModes for RegInfo were found!"); |
| 150 | +// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1; |
| 151 | +// CHECK-SUBTARGET: case HwMode_EncodingInfo: |
| 152 | +// CHECK-SUBTARGET: Modes &= 4; |
| 153 | +// CHECK-SUBTARGET: if (!Modes) |
| 154 | +// CHECK-SUBTARGET: return Modes; |
| 155 | +// CHECK-SUBTARGET: if (!llvm::has_single_bit<unsigned>(Modes)) |
| 156 | +// CHECK-SUBTARGET: llvm_unreachable("Two or more HwModes for EncodingInfo were found!"); |
| 157 | +// CHECK-SUBTARGET: return llvm::countr_zero(Modes) + 1; |
| 158 | +// CHECK-SUBTARGET: } |
| 159 | +// CHECK-SUBTARGET: llvm_unreachable("unexpected HwModeType"); |
| 160 | +// CHECK-SUBTARGET: return 0; // should not get here |
| 161 | +// CHECK-SUBTARGET: } |
| 162 | + |
0 commit comments