diff options
Diffstat (limited to 'contrib/llvm/lib/Target/X86/X86RegisterInfo.td')
-rw-r--r-- | contrib/llvm/lib/Target/X86/X86RegisterInfo.td | 63 |
1 files changed, 47 insertions, 16 deletions
diff --git a/contrib/llvm/lib/Target/X86/X86RegisterInfo.td b/contrib/llvm/lib/Target/X86/X86RegisterInfo.td index 56f0d9352d30..373f9b4c65f2 100644 --- a/contrib/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/contrib/llvm/lib/Target/X86/X86RegisterInfo.td @@ -226,14 +226,14 @@ let SubRegIndices = [sub_ymm] in { } // Mask Registers, used by AVX-512 instructions. -def K0 : X86Reg<"k0", 0>, DwarfRegNum<[118, -2, -2]>; -def K1 : X86Reg<"k1", 1>, DwarfRegNum<[119, -2, -2]>; -def K2 : X86Reg<"k2", 2>, DwarfRegNum<[120, -2, -2]>; -def K3 : X86Reg<"k3", 3>, DwarfRegNum<[121, -2, -2]>; -def K4 : X86Reg<"k4", 4>, DwarfRegNum<[122, -2, -2]>; -def K5 : X86Reg<"k5", 5>, DwarfRegNum<[123, -2, -2]>; -def K6 : X86Reg<"k6", 6>, DwarfRegNum<[124, -2, -2]>; -def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, -2, -2]>; +def K0 : X86Reg<"k0", 0>, DwarfRegNum<[118, 93, 93]>; +def K1 : X86Reg<"k1", 1>, DwarfRegNum<[119, 94, 94]>; +def K2 : X86Reg<"k2", 2>, DwarfRegNum<[120, 95, 95]>; +def K3 : X86Reg<"k3", 3>, DwarfRegNum<[121, 96, 96]>; +def K4 : X86Reg<"k4", 4>, DwarfRegNum<[122, 97, 97]>; +def K5 : X86Reg<"k5", 5>, DwarfRegNum<[123, 98, 98]>; +def K6 : X86Reg<"k6", 6>, DwarfRegNum<[124, 99, 99]>; +def K7 : X86Reg<"k7", 7>, DwarfRegNum<[125, 100, 100]>; // Floating point stack registers. These don't map one-to-one to the FP // pseudo registers, but we still mark them as aliasing FP registers. That @@ -415,6 +415,26 @@ def GR32_NOREX_NOSP : RegisterClass<"X86", [i32], 32, def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64, (and GR64_NOREX, GR64_NOSP)>; +// Register classes used for ABIs that use 32-bit address accesses, +// while using the whole x84_64 ISA. + +// In such cases, it is fine to use RIP as we are sure the 32 high +// bits are not set. We do not need variants for NOSP as RIP is not +// allowed there. +// RIP is not spilled anywhere for now, so stick to 32-bit alignment +// to save on memory space. +// FIXME: We could allow all 64bit registers, but we would need +// something to check that the 32 high bits are not set, +// which we do not have right now. +def LOW32_ADDR_ACCESS : RegisterClass<"X86", [i32], 32, (add GR32, RIP)>; + +// When RBP is used as a base pointer in a 32-bit addresses environement, +// this is also safe to use the full register to access addresses. +// Since RBP will never be spilled, stick to a 32 alignment to save +// on memory consumption. +def LOW32_ADDR_ACCESS_RBP : RegisterClass<"X86", [i32], 32, + (add LOW32_ADDR_ACCESS, RBP)>; + // A class to support the 'A' assembler constraint: EAX then EDX. def GR32_AD : RegisterClass<"X86", [i32], 32, (add EAX, EDX)>; @@ -451,6 +471,17 @@ def VR128 : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], def VR256 : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], 256, (sequence "YMM%u", 0, 15)>; +// Special classes that help the assembly parser choose some alternate +// instructions to favor 2-byte VEX encodings. +def VR128L : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], + 128, (sequence "XMM%u", 0, 7)>; +def VR128H : RegisterClass<"X86", [v4f32, v2f64, v16i8, v8i16, v4i32, v2i64], + 128, (sequence "XMM%u", 8, 15)>; +def VR256L : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], + 256, (sequence "YMM%u", 0, 7)>; +def VR256H : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], + 256, (sequence "YMM%u", 8, 15)>; + // Status flags registers. def CCR : RegisterClass<"X86", [i32], 32, (add EFLAGS)> { let CopyCost = -1; // Don't allow copying of status registers. @@ -477,18 +508,18 @@ def VR256X : RegisterClass<"X86", [v8f32, v4f64, v32i8, v16i16, v8i32, v4i64], 256, (sequence "YMM%u", 0, 31)>; // Mask registers -def VK1 : RegisterClass<"X86", [i1], 8, (sequence "K%u", 0, 7)> {let Size = 8;} -def VK2 : RegisterClass<"X86", [v2i1], 8, (add VK1)> {let Size = 8;} -def VK4 : RegisterClass<"X86", [v4i1], 8, (add VK2)> {let Size = 8;} -def VK8 : RegisterClass<"X86", [v8i1], 8, (add VK4)> {let Size = 8;} +def VK1 : RegisterClass<"X86", [i1], 16, (sequence "K%u", 0, 7)> {let Size = 16;} +def VK2 : RegisterClass<"X86", [v2i1], 16, (add VK1)> {let Size = 16;} +def VK4 : RegisterClass<"X86", [v4i1], 16, (add VK2)> {let Size = 16;} +def VK8 : RegisterClass<"X86", [v8i1], 16, (add VK4)> {let Size = 16;} def VK16 : RegisterClass<"X86", [v16i1], 16, (add VK8)> {let Size = 16;} def VK32 : RegisterClass<"X86", [v32i1], 32, (add VK16)> {let Size = 32;} def VK64 : RegisterClass<"X86", [v64i1], 64, (add VK32)> {let Size = 64;} -def VK1WM : RegisterClass<"X86", [i1], 8, (sub VK1, K0)> {let Size = 8;} -def VK2WM : RegisterClass<"X86", [v2i1], 8, (sub VK2, K0)> {let Size = 8;} -def VK4WM : RegisterClass<"X86", [v4i1], 8, (sub VK4, K0)> {let Size = 8;} -def VK8WM : RegisterClass<"X86", [v8i1], 8, (sub VK8, K0)> {let Size = 8;} +def VK1WM : RegisterClass<"X86", [i1], 16, (sub VK1, K0)> {let Size = 16;} +def VK2WM : RegisterClass<"X86", [v2i1], 16, (sub VK2, K0)> {let Size = 16;} +def VK4WM : RegisterClass<"X86", [v4i1], 16, (sub VK4, K0)> {let Size = 16;} +def VK8WM : RegisterClass<"X86", [v8i1], 16, (sub VK8, K0)> {let Size = 16;} def VK16WM : RegisterClass<"X86", [v16i1], 16, (add VK8WM)> {let Size = 16;} def VK32WM : RegisterClass<"X86", [v32i1], 32, (add VK16WM)> {let Size = 32;} def VK64WM : RegisterClass<"X86", [v64i1], 64, (add VK32WM)> {let Size = 64;} |