Index: lib/Target/Sparc/Sparc.td =================================================================== --- lib/Target/Sparc/Sparc.td +++ lib/Target/Sparc/Sparc.td @@ -60,6 +60,15 @@ def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", "Use software emulation for floating point">; +def UseG5 : SubtargetFeature<"useg5", "UseG5", "true", + "Allow use of register %g5">; + +def UseG6 : SubtargetFeature<"useg6", "UseG6", "true", + "Allow use of register %g6">; + +def UseG7 : SubtargetFeature<"useg7", "UseG7", "true", + "Allow use of register %g7">; + //==== Features added predmoninantly for LEON subtarget support include "LeonFeatures.td" Index: lib/Target/Sparc/SparcRegisterInfo.cpp =================================================================== --- lib/Target/Sparc/SparcRegisterInfo.cpp +++ lib/Target/Sparc/SparcRegisterInfo.cpp @@ -56,36 +56,26 @@ BitVector Reserved(getNumRegs()); const SparcSubtarget &Subtarget = MF.getSubtarget(); // FIXME: G1 reserved for now for large imm generation by frame code. - Reserved.set(SP::G1); + markSuperRegs(Reserved, SP::G1); // G1-G4 can be used in applications. if (ReserveAppRegisters) { - Reserved.set(SP::G2); - Reserved.set(SP::G3); - Reserved.set(SP::G4); + markSuperRegs(Reserved, SP::G2); + markSuperRegs(Reserved, SP::G3); + markSuperRegs(Reserved, SP::G4); } // G5 is not reserved in 64 bit mode. - if (!Subtarget.is64Bit()) - Reserved.set(SP::G5); - - Reserved.set(SP::O6); - Reserved.set(SP::I6); - Reserved.set(SP::I7); - Reserved.set(SP::G0); - Reserved.set(SP::G6); - Reserved.set(SP::G7); - - // Also reserve the register pair aliases covering the above - // registers, with the same conditions. - Reserved.set(SP::G0_G1); - if (ReserveAppRegisters) - Reserved.set(SP::G2_G3); - if (ReserveAppRegisters || !Subtarget.is64Bit()) - Reserved.set(SP::G4_G5); - - Reserved.set(SP::O6_O7); - Reserved.set(SP::I6_I7); - Reserved.set(SP::G6_G7); + if (!Subtarget.is64Bit() && !Subtarget.useG5()) + markSuperRegs(Reserved, SP::G5); + + markSuperRegs(Reserved, SP::O6); + markSuperRegs(Reserved, SP::I6); + markSuperRegs(Reserved, SP::I7); + markSuperRegs(Reserved, SP::G0); + if (!Subtarget.useG6()) + markSuperRegs(Reserved, SP::G6); + if (!Subtarget.useG7()) + markSuperRegs(Reserved, SP::G7); // Unaliased double registers are not available in non-V9 targets. if (!Subtarget.isV9()) { Index: lib/Target/Sparc/SparcSubtarget.h =================================================================== --- lib/Target/Sparc/SparcSubtarget.h +++ lib/Target/Sparc/SparcSubtarget.h @@ -43,6 +43,9 @@ bool UseSoftFloat; bool HasNoFSMULD; bool HasNoFMULS; + bool UseG5; + bool UseG6; + bool UseG7; // LEON features bool HasUmacSmac; @@ -88,6 +91,9 @@ bool useSoftFloat() const { return UseSoftFloat; } bool hasNoFSMULD() const { return HasNoFSMULD; } bool hasNoFMULS() const { return HasNoFMULS; } + bool useG5() const { return UseG5; } + bool useG6() const { return UseG6; } + bool useG7() const { return UseG7; } // Leon options bool hasUmacSmac() const { return HasUmacSmac; } Index: lib/Target/Sparc/SparcSubtarget.cpp =================================================================== --- lib/Target/Sparc/SparcSubtarget.cpp +++ lib/Target/Sparc/SparcSubtarget.cpp @@ -40,6 +40,9 @@ UseSoftFloat = false; HasNoFSMULD = false; HasNoFMULS = false; + UseG5 = false; + UseG6 = false; + UseG7 = false; // Leon features HasLeonCasa = false; Index: test/CodeGen/SPARC/reserved-regs.ll =================================================================== --- test/CodeGen/SPARC/reserved-regs.ll +++ test/CodeGen/SPARC/reserved-regs.ll @@ -1,4 +1,7 @@ ; RUN: llc -march=sparc -verify-machineinstrs < %s | FileCheck %s +; RUN: llc -march=sparc -verify-machineinstrs -mattr=useg5 < %s | FileCheck %s -check-prefix=USEG5 +; RUN: llc -march=sparc -verify-machineinstrs -mattr=useg6 < %s | FileCheck %s -check-prefix=USEG6 +; RUN: llc -march=sparc -verify-machineinstrs -mattr=useg7 < %s | FileCheck %s -check-prefix=USEG7 @g = common global [32 x i32] zeroinitializer, align 16 @h = common global [16 x i64] zeroinitializer, align 16 @@ -15,6 +18,9 @@ ; CHECK-NOT: %o6 ; CHECK-NOT: %i6 ; CHECK-NOT: %i7 +; USEG5: %g5 +; USEG6: %g6 +; USEG7: %g7 ; CHECK: ret define void @use_all_i32_regs() { entry: @@ -98,6 +104,9 @@ ; CHECK-NOT: %o7 ; CHECK-NOT: %i6 ; CHECK-NOT: %i7 +; USEG5: %g5 +; USEG6: %g6 +; USEG7: %g7 ; CHECK: ret define void @use_all_i64_regs() { entry: