forked from OSchip/llvm-project
93 lines
3.0 KiB
TableGen
93 lines
3.0 KiB
TableGen
|
// RUN: llvm-tblgen -gen-register-info -I %p/../../include %s 2>&1 | FileCheck %s
|
||
|
//
|
||
|
// CHECK-NOT: warning: SubRegIndex Test::subreg_h64 and Test::subreg_h32 compose ambiguously as Test::subreg_hh32 or Test::subreg_h32
|
||
|
// CHECK: warning: SubRegIndex Test::subreg_l64 and Test::subreg_l32 compose ambiguously as Test::subreg_ll32 or Test::subreg_l32
|
||
|
|
||
|
include "llvm/Target/Target.td"
|
||
|
|
||
|
def TestInstrInfo : InstrInfo {
|
||
|
}
|
||
|
|
||
|
def Test : Target {
|
||
|
let InstructionSet = TestInstrInfo;
|
||
|
}
|
||
|
|
||
|
let Namespace = "Test" in {
|
||
|
def subreg_l32 : SubRegIndex<32, 0>;
|
||
|
def subreg_h32 : SubRegIndex<32, 32>;
|
||
|
def subreg_h64 : SubRegIndex<64, 64>;
|
||
|
def subreg_l64 : SubRegIndex<64, 0>;
|
||
|
def subreg_hh32 : ComposedSubRegIndex<subreg_h64, subreg_h32>;
|
||
|
def subreg_ll32 : ComposedSubRegIndex<subreg_l64, subreg_l32>;
|
||
|
}
|
||
|
|
||
|
class TestReg<string n, list<Register> s> : RegisterWithSubRegs<n, s> {
|
||
|
let Namespace = "Test";
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------
|
||
|
// A situation that previously caused the warning about ambiguous
|
||
|
// composition.
|
||
|
//
|
||
|
// The actual subregister actions are:
|
||
|
// subreg_h64: { F0Q->F0D V0Q->F0D }
|
||
|
// subreg_h32: { F0D->F0S F0Q->F2S V0Q->F0S }
|
||
|
// composition: { F0Q->F0S V0Q->F0S } (this is the same as subreg_hh32)
|
||
|
//
|
||
|
// For the register V0Q, subreg_hh32(V0Q) = subreg_h32(V0Q) = F0S, which
|
||
|
// would be enough to trigger the warning about ambiguous composition.
|
||
|
// However, for F0Q, subreg_hh32(F0Q) = F0S, while subreg_h32(F0Q) = F2S,
|
||
|
// which shows that there two subregister indices are different.
|
||
|
// Make sure that the warning is not emitted in this case.
|
||
|
|
||
|
class FPR32<string n> : TestReg<n, []> {
|
||
|
}
|
||
|
|
||
|
class FPR64<string n, FPR32 high> : TestReg<n, [high]> {
|
||
|
let SubRegIndices = [subreg_h32];
|
||
|
}
|
||
|
|
||
|
class FPR128<string n, FPR64 high, FPR32 low> : TestReg<n, [high, low]> {
|
||
|
let SubRegIndices = [subreg_h64, subreg_h32];
|
||
|
}
|
||
|
|
||
|
class VPR128<string n, FPR64 high> : TestReg<n, [high]> {
|
||
|
let SubRegIndices = [subreg_h64];
|
||
|
}
|
||
|
|
||
|
def F0S : FPR32<"f0s">;
|
||
|
def F1S : FPR32<"f1s">;
|
||
|
def F2S : FPR32<"f2s">;
|
||
|
|
||
|
def F0D : FPR64<"f0d", F0S>;
|
||
|
def F0Q : FPR128<"f0q", F0D, F2S>;
|
||
|
def V0Q : VPR128<"v0q", F0D>;
|
||
|
|
||
|
def FP32 : RegisterClass<"FP32", [f32], 32, (add F0S)>;
|
||
|
def FP64 : RegisterClass<"FP64", [f64], 64, (add F0D)>;
|
||
|
def FP128 : RegisterClass<"FP128", [v2f64], 128, (add F0Q)>;
|
||
|
def VP128 : RegisterClass<"VP128", [v2f64], 128, (add V0Q)>;
|
||
|
|
||
|
// --------------------------------------------------------------------
|
||
|
// A situation where the warning is legitimate.
|
||
|
// Make sure that the warning is still displayed.
|
||
|
|
||
|
class GPR32<string n> : TestReg<n, []> {
|
||
|
}
|
||
|
|
||
|
class GPR64<string n, GPR32 low> : TestReg<n, [low]> {
|
||
|
let SubRegIndices = [subreg_l32];
|
||
|
}
|
||
|
|
||
|
class GPR128<string n, GPR64 low> : TestReg<n, [low]> {
|
||
|
let SubRegIndices = [subreg_l64];
|
||
|
}
|
||
|
|
||
|
def G0S : GPR32<"g0s">;
|
||
|
def G0D : GPR64<"g0d", G0S>;
|
||
|
def G0Q : GPR128<"g0q", G0D>;
|
||
|
|
||
|
def GP32 : RegisterClass<"GP32", [i32], 32, (add G0S)>;
|
||
|
def GP64 : RegisterClass<"GP64", [i64], 64, (add G0D)>;
|
||
|
def GP128 : RegisterClass<"GP128", [v2i64], 128, (add G0Q)>;
|