+// Segment registers for use by MOV instructions (and others) that have a
+// segment register as one operand. Always contain a 16-bit segment
+// descriptor.
+def SEGMENT_REG : RegisterClass<"X86", [i16], 16, [CS, DS, SS, ES, FS, GS]>;
+
+// Debug registers.
+def DEBUG_REG : RegisterClass<"X86", [i32], 32,
+ [DR0, DR1, DR2, DR3, DR4, DR5, DR6, DR7]>;
+
+// Control registers.
+def CONTROL_REG : RegisterClass<"X86", [i64], 64,
+ [CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7, CR8,
+ CR9, CR10, CR11, CR12, CR13, CR14, CR15]>;
+
+// GR8_ABCD_L, GR8_ABCD_H, GR16_ABCD, GR32_ABCD, GR64_ABCD - Subclasses of
+// GR8, GR16, GR32, and GR64 which contain just the "a" "b", "c", and "d"
+// registers. On x86-32, GR16_ABCD and GR32_ABCD are classes for registers
+// that support 8-bit subreg operations. On x86-64, GR16_ABCD, GR32_ABCD,
+// and GR64_ABCD are classes for registers that support 8-bit h-register
+// operations.
+def GR8_ABCD_L : RegisterClass<"X86", [i8], 8, [AL, CL, DL, BL]>;
+def GR8_ABCD_H : RegisterClass<"X86", [i8], 8, [AH, CH, DH, BH]>;
+def GR16_ABCD : RegisterClass<"X86", [i16], 16, [AX, CX, DX, BX]> {
+ let SubRegClasses = [(GR8_ABCD_L sub_8bit), (GR8_ABCD_H sub_8bit_hi)];
+}
+def GR32_ABCD : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX, EBX]> {
+ let SubRegClasses = [(GR8_ABCD_L sub_8bit),
+ (GR8_ABCD_H sub_8bit_hi),
+ (GR16_ABCD sub_16bit)];
+}
+def GR64_ABCD : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RBX]> {
+ let SubRegClasses = [(GR8_ABCD_L sub_8bit),
+ (GR8_ABCD_H sub_8bit_hi),
+ (GR16_ABCD sub_16bit),
+ (GR32_ABCD sub_32bit)];
+}
+def GR32_TC : RegisterClass<"X86", [i32], 32, [EAX, ECX, EDX]> {
+ let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)];
+}
+def GR64_TC : RegisterClass<"X86", [i64], 64, [RAX, RCX, RDX, RSI, RDI,
+ R8, R9, R11]> {
+ let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi),
+ (GR16 sub_16bit),
+ (GR32_TC sub_32bit)];
+}
+
+// GR8_NOREX - GR8 registers which do not require a REX prefix.
+def GR8_NOREX : RegisterClass<"X86", [i8], 8,
+ [AL, CL, DL, AH, CH, DH, BL, BH]> {
+ let MethodProtos = [{
+ iterator allocation_order_begin(const MachineFunction &MF) const;
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ // In 64-bit mode, it's not safe to blindly allocate H registers.
+ static const unsigned X86_GR8_NOREX_AO_64[] = {
+ X86::AL, X86::CL, X86::DL, X86::BL
+ };
+
+ GR8_NOREXClass::iterator
+ GR8_NOREXClass::allocation_order_begin(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
+ if (Subtarget.is64Bit())
+ return X86_GR8_NOREX_AO_64;
+ else
+ return begin();
+ }
+
+ GR8_NOREXClass::iterator
+ GR8_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
+ if (Subtarget.is64Bit())
+ return array_endof(X86_GR8_NOREX_AO_64);
+ else
+ return end();
+ }
+ }];
+}
+// GR16_NOREX - GR16 registers which do not require a REX prefix.
+def GR16_NOREX : RegisterClass<"X86", [i16], 16,
+ [AX, CX, DX, SI, DI, BX, BP, SP]> {
+ let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi)];
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ GR16_NOREXClass::iterator
+ GR16_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
+ // Does the function dedicate RBP / EBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ // If so, don't allocate SP or BP.
+ return end() - 2;
+ else
+ // If not, just don't allocate SP.
+ return end() - 1;
+ }
+ }];
+}
+// GR32_NOREX - GR32 registers which do not require a REX prefix.
+def GR32_NOREX : RegisterClass<"X86", [i32], 32,
+ [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP]> {
+ let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
+ (GR16_NOREX sub_16bit)];
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ GR32_NOREXClass::iterator
+ GR32_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
+ // Does the function dedicate RBP / EBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ // If so, don't allocate ESP or EBP.
+ return end() - 2;
+ else
+ // If not, just don't allocate ESP.
+ return end() - 1;
+ }
+ }];
+}
+// GR64_NOREX - GR64 registers which do not require a REX prefix.
+def GR64_NOREX : RegisterClass<"X86", [i64], 64,
+ [RAX, RCX, RDX, RSI, RDI, RBX, RBP, RSP, RIP]> {
+ let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
+ (GR16_NOREX sub_16bit),
+ (GR32_NOREX sub_32bit)];
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ GR64_NOREXClass::iterator
+ GR64_NOREXClass::allocation_order_end(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
+ // Does the function dedicate RBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ // If so, don't allocate RIP, RSP or RBP.
+ return end() - 3;
+ else
+ // If not, just don't allocate RIP or RSP.
+ return end() - 2;
+ }
+ }];
+}
+
+// GR32_NOSP - GR32 registers except ESP.
+def GR32_NOSP : RegisterClass<"X86", [i32], 32,
+ [EAX, ECX, EDX, ESI, EDI, EBX, EBP,
+ R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> {
+ let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)];
+ let MethodProtos = [{
+ iterator allocation_order_begin(const MachineFunction &MF) const;
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ static const unsigned X86_GR32_NOSP_AO_64[] = {
+ X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI,
+ X86::R8D, X86::R9D, X86::R10D, X86::R11D,
+ X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP
+ };
+
+ GR32_NOSPClass::iterator
+ GR32_NOSPClass::allocation_order_begin(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
+ if (Subtarget.is64Bit())
+ return X86_GR32_NOSP_AO_64;
+ else
+ return begin();
+ }
+
+ GR32_NOSPClass::iterator
+ GR32_NOSPClass::allocation_order_end(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
+ const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
+ if (Subtarget.is64Bit()) {
+ // Does the function dedicate RBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ // If so, don't allocate EBP.
+ return array_endof(X86_GR32_NOSP_AO_64) - 1;
+ else
+ // If not, any reg in this class is ok.
+ return array_endof(X86_GR32_NOSP_AO_64);
+ } else {
+ // Does the function dedicate EBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ // If so, don't allocate EBP.
+ return begin() + 6;
+ else
+ // If not, any reg in this class is ok.
+ return begin() + 7;
+ }
+ }
+ }];
+}
+
+// GR64_NOSP - GR64 registers except RSP (and RIP).
+def GR64_NOSP : RegisterClass<"X86", [i64], 64,
+ [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
+ RBX, R14, R15, R12, R13, RBP]> {
+ let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi),
+ (GR16 sub_16bit),
+ (GR32_NOSP sub_32bit)];
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ GR64_NOSPClass::iterator
+ GR64_NOSPClass::allocation_order_end(const MachineFunction &MF) const {
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>();
+ const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
+ if (!Subtarget.is64Bit())
+ return begin(); // None of these are allocatable in 32-bit.
+ // Does the function dedicate RBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ return end()-1; // If so, don't allocate RBP
+ else
+ return end(); // If not, any reg in this class is ok.
+ }
+ }];
+}
+
+// GR64_NOREX_NOSP - GR64_NOREX registers except RSP.
+def GR64_NOREX_NOSP : RegisterClass<"X86", [i64], 64,
+ [RAX, RCX, RDX, RSI, RDI, RBX, RBP]> {
+ let SubRegClasses = [(GR8_NOREX sub_8bit, sub_8bit_hi),
+ (GR16_NOREX sub_16bit),
+ (GR32_NOREX sub_32bit)];
+ let MethodProtos = [{
+ iterator allocation_order_end(const MachineFunction &MF) const;
+ }];
+ let MethodBodies = [{
+ GR64_NOREX_NOSPClass::iterator
+ GR64_NOREX_NOSPClass::allocation_order_end(const MachineFunction &MF) const
+ {
+ const TargetMachine &TM = MF.getTarget();
+ const TargetFrameInfo *TFI = TM.getFrameInfo();
+ const X86MachineFunctionInfo *MFI = MF.getInfo<X86MachineFunctionInfo>();
+ // Does the function dedicate RBP to being a frame ptr?
+ if (TFI->hasFP(MF) || MFI->getReserveFP())
+ // If so, don't allocate RBP.
+ return end() - 1;
+ else
+ // If not, any reg in this class is ok.
+ return end();
+ }
+ }];
+}
+
+// A class to support the 'A' assembler constraint: EAX then EDX.
+def GR32_AD : RegisterClass<"X86", [i32], 32, [EAX, EDX]> {
+ let SubRegClasses = [(GR8_ABCD_L sub_8bit),
+ (GR8_ABCD_H sub_8bit_hi),
+ (GR16_ABCD sub_16bit)];
+}
+