[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -82,6 +88,13 @@ class SparcSubtarget : public SparcGenSubtargetInfo { return is64Bit() ? 2047 : 0; } + bool isRegisterReserved(MCPhysReg PhysReg) const { +if (PhysReg >= SP::G0 && PhysReg <= SP::O7) + return ReserveRegister[PhysReg - SP::G0]; s-barannikov wrote: I wouldn't bother "compacting" a BitVector. This would also allow reserving other registers in the future and not depend on exact values of enum members. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
https://github.com/s-barannikov approved this pull request. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
koachan wrote: Ping? https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -98,9 +96,34 @@ BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction ) const { for (unsigned n = 0; n < 31; n++) Reserved.set(SP::ASR1 + n); + for (size_t i = 0; i < SP::IntRegsRegClass.getNumRegs() / 4; ++i) { +// Mark both single register and register pairs. +if (MF.getSubtarget().isGRegisterReserved(i)) { + Reserved.set(SP::G0 + i); + Reserved.set(SP::G0_G1 + i / 2); +} +if (MF.getSubtarget().isORegisterReserved(i)) { + Reserved.set(SP::O0 + i); + Reserved.set(SP::O0_O1 + i / 2); +} +if (MF.getSubtarget().isLRegisterReserved(i)) { + Reserved.set(SP::L0 + i); + Reserved.set(SP::L0_L1 + i / 2); +} +if (MF.getSubtarget().isIRegisterReserved(i)) { + Reserved.set(SP::I0 + i); + Reserved.set(SP::I0_I1 + i / 2); +} + } + return Reserved; koachan wrote: checkAllSuperRegsMarked returns a bool though, no? We want a BitVector here... https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -29,6 +29,12 @@ namespace llvm { class StringRef; class SparcSubtarget : public SparcGenSubtargetInfo { + // Reserve*Register[i] - *#i is not available as a general purpose register. + BitVector ReserveGRegister; koachan wrote: It should be possible, however my concern is that [the flags](https://github.com/llvm/llvm-project/pull/74927/files#diff-cf43b5b875187dc9a8dc30d7cd08b1595d63286ef469df03d7f89c92fa294fb5R68-R81) need to be defined in terms of register names, and tablegen seems to not like doing arithmetic inside the `"Reserve*Register["#i#"]"` parts? https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -29,6 +29,12 @@ namespace llvm { class StringRef; class SparcSubtarget : public SparcGenSubtargetInfo { + // Reserve*Register[i] - *#i is not available as a general purpose register. + BitVector ReserveGRegister; s-barannikov wrote: Can this be a single `BitVector` indexed by physical register number? This would simplify `TRI.getReservedRegs()`, I think. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -80,6 +86,11 @@ class SparcSubtarget : public SparcGenSubtargetInfo { return is64Bit() ? 2047 : 0; } + bool isGRegisterReserved(size_t i) const { return ReserveGRegister[i]; } + bool isORegisterReserved(size_t i) const { return ReserveORegister[i]; } + bool isLRegisterReserved(size_t i) const { return ReserveLRegister[i]; } + bool isIRegisterReserved(size_t i) const { return ReserveIRegister[i]; } s-barannikov wrote: This could be a single interface accepting a physical register instead of an index. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -98,9 +96,34 @@ BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction ) const { for (unsigned n = 0; n < 31; n++) Reserved.set(SP::ASR1 + n); + for (size_t i = 0; i < SP::IntRegsRegClass.getNumRegs() / 4; ++i) { +// Mark both single register and register pairs. +if (MF.getSubtarget().isGRegisterReserved(i)) { + Reserved.set(SP::G0 + i); + Reserved.set(SP::G0_G1 + i / 2); +} s-barannikov wrote: ```suggestion if (MF.getSubtarget().isGRegisterReserved(i)) markSuperRegs(Reserved, SP::G0 + i); ``` https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -1125,6 +1130,10 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT, .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7) .Default(0); + const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo(); + if (!TRI->isReservedReg(MF, Reg)) +Reg = 0; jrtc27 wrote: ```not --crash``` Though you need to be sure it will deterministically crash even in non-assertions release builds https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -1125,6 +1130,10 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT, .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7) .Default(0); + const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo(); + if (!TRI->isReservedReg(MF, Reg)) +Reg = 0; koachan wrote: > Because of that, allocatable registers are not supported. Yeah, this seems to be the main difference between them, from what I understand. GCC does warn you about it, but it will still allow you to read/write allocatable registers. LLVM, on the other hand, will flat out refuse to do that (either by hard-crashing or turning the read/write_register intrinsics into nops). And yes, this should be enough for the Linux kernel, methinks. - - - - - Also, re:testing, how should I test this, given that the expected failure mode is a hard crash? I don't know if there's any way to tell the test framework that a hard crash is the intended result. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/74927 >From 956ca7e210a438caac7c5dda8c9945305a53de39 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 29 Nov 2023 08:08:29 +0700 Subject: [PATCH 1/3] [SPARC] Support reserving arbitrary general purpose registers This adds support for marking arbitrary general purpose registers - except for those with special purpose (G0, I6-I7, O6-O7) - as reserved, as needed by some software like the Linux kernel. --- clang/include/clang/Driver/Options.td| 12 ++ clang/lib/Driver/ToolChains/Arch/Sparc.cpp | 81 + clang/test/Driver/sparc-fixed-register.c | 181 +++ llvm/lib/Target/Sparc/Sparc.td | 14 ++ llvm/lib/Target/Sparc/SparcISelLowering.cpp | 23 +++ llvm/lib/Target/Sparc/SparcRegisterInfo.cpp | 45 - llvm/lib/Target/Sparc/SparcRegisterInfo.h| 3 + llvm/lib/Target/Sparc/SparcRegisterInfo.td | 4 + llvm/lib/Target/Sparc/SparcSubtarget.cpp | 6 +- llvm/lib/Target/Sparc/SparcSubtarget.h | 11 ++ llvm/test/CodeGen/SPARC/reserved-arg-regs.ll | 25 +++ llvm/test/CodeGen/SPARC/reserved-regs.ll | 17 ++ 12 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 clang/test/Driver/sparc-fixed-register.c create mode 100644 llvm/test/CodeGen/SPARC/reserved-arg-regs.ll diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index df12ba8fbcb296..94bdeff28d0146 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5730,6 +5730,18 @@ def mvis3 : Flag<["-"], "mvis3">, Group; def mno_vis3 : Flag<["-"], "mno-vis3">, Group; def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group; def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group; +foreach i = {1-7} in + def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group, +HelpText<"Reserve the G"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_o#i : Flag<["-"], "ffixed-o"#i>, Group, +HelpText<"Reserve the O"#i#" register (SPARC only)">; +foreach i = {0-7} in + def ffixed_l#i : Flag<["-"], "ffixed-l"#i>, Group, +HelpText<"Reserve the L"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_i#i : Flag<["-"], "ffixed-i"#i>, Group, +HelpText<"Reserve the I"#i#" register (SPARC only)">; } // let Flags = [TargetSpecific] // M68k features flags diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp index 22e583021515e5..ae1a4ba7882627 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -178,4 +178,85 @@ void sparc::getSparcTargetFeatures(const Driver , const ArgList , else Features.push_back("-hard-quad-float"); } + + if (Args.hasArg(options::OPT_ffixed_g1)) +Features.push_back("+reserve-g1"); + + if (Args.hasArg(options::OPT_ffixed_g2)) +Features.push_back("+reserve-g2"); + + if (Args.hasArg(options::OPT_ffixed_g3)) +Features.push_back("+reserve-g3"); + + if (Args.hasArg(options::OPT_ffixed_g4)) +Features.push_back("+reserve-g4"); + + if (Args.hasArg(options::OPT_ffixed_g5)) +Features.push_back("+reserve-g5"); + + if (Args.hasArg(options::OPT_ffixed_g6)) +Features.push_back("+reserve-g6"); + + if (Args.hasArg(options::OPT_ffixed_g7)) +Features.push_back("+reserve-g7"); + + if (Args.hasArg(options::OPT_ffixed_o0)) +Features.push_back("+reserve-o0"); + + if (Args.hasArg(options::OPT_ffixed_o1)) +Features.push_back("+reserve-o1"); + + if (Args.hasArg(options::OPT_ffixed_o2)) +Features.push_back("+reserve-o2"); + + if (Args.hasArg(options::OPT_ffixed_o3)) +Features.push_back("+reserve-o3"); + + if (Args.hasArg(options::OPT_ffixed_o4)) +Features.push_back("+reserve-o4"); + + if (Args.hasArg(options::OPT_ffixed_o5)) +Features.push_back("+reserve-o5"); + + if (Args.hasArg(options::OPT_ffixed_l0)) +Features.push_back("+reserve-l0"); + + if (Args.hasArg(options::OPT_ffixed_l1)) +Features.push_back("+reserve-l1"); + + if (Args.hasArg(options::OPT_ffixed_l2)) +Features.push_back("+reserve-l2"); + + if (Args.hasArg(options::OPT_ffixed_l3)) +Features.push_back("+reserve-l3"); + + if (Args.hasArg(options::OPT_ffixed_l4)) +Features.push_back("+reserve-l4"); + + if (Args.hasArg(options::OPT_ffixed_l5)) +Features.push_back("+reserve-l5"); + + if (Args.hasArg(options::OPT_ffixed_l6)) +Features.push_back("+reserve-l6"); + + if (Args.hasArg(options::OPT_ffixed_l7)) +Features.push_back("+reserve-l7"); + + if (Args.hasArg(options::OPT_ffixed_i0)) +Features.push_back("+reserve-i0"); + + if (Args.hasArg(options::OPT_ffixed_i1)) +Features.push_back("+reserve-i1"); + + if (Args.hasArg(options::OPT_ffixed_i2)) +Features.push_back("+reserve-i2"); + + if (Args.hasArg(options::OPT_ffixed_i3)) +Features.push_back("+reserve-i3"); + + if
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -1125,6 +1130,10 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT, .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7) .Default(0); + const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo(); + if (!TRI->isReservedReg(MF, Reg)) +Reg = 0; koachan wrote: Hmm, yeah, ideally we'd want to do that but I don't think we can do that easily? Even if I turn off all the errors, stuff like this, for example: ``` register unsigned long r asm("l0"); void set(unsigned long x) { r = x; } ``` Becomes a nop function on clang unless `l0` is reserved. Other LLVM backends also do this (and differ from GCC behavior) so I don't think the issue is localized to ours. So I believe it is better for us to throw an error instead of silently miscompiling code? https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -1125,6 +1130,10 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT, .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7) .Default(0); + const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo(); + if (!TRI->isReservedReg(MF, Reg)) +Reg = 0; s-barannikov wrote: I think we should follow gcc as much as possible. Some info can be found [here](https://gcc.gnu.org/onlinedocs/gcc/Global-Register-Variables.html). In particular, gcc does not seem to require -ffixed-reg option for a register used in 'register asm' construct (global or local). Reserving an ABI register does not prohibit function calls either. I've been only able to get an error when trying to reserve the frame pointer. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/74927 >From 956ca7e210a438caac7c5dda8c9945305a53de39 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 29 Nov 2023 08:08:29 +0700 Subject: [PATCH 1/2] [SPARC] Support reserving arbitrary general purpose registers This adds support for marking arbitrary general purpose registers - except for those with special purpose (G0, I6-I7, O6-O7) - as reserved, as needed by some software like the Linux kernel. --- clang/include/clang/Driver/Options.td| 12 ++ clang/lib/Driver/ToolChains/Arch/Sparc.cpp | 81 + clang/test/Driver/sparc-fixed-register.c | 181 +++ llvm/lib/Target/Sparc/Sparc.td | 14 ++ llvm/lib/Target/Sparc/SparcISelLowering.cpp | 23 +++ llvm/lib/Target/Sparc/SparcRegisterInfo.cpp | 45 - llvm/lib/Target/Sparc/SparcRegisterInfo.h| 3 + llvm/lib/Target/Sparc/SparcRegisterInfo.td | 4 + llvm/lib/Target/Sparc/SparcSubtarget.cpp | 6 +- llvm/lib/Target/Sparc/SparcSubtarget.h | 11 ++ llvm/test/CodeGen/SPARC/reserved-arg-regs.ll | 25 +++ llvm/test/CodeGen/SPARC/reserved-regs.ll | 17 ++ 12 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 clang/test/Driver/sparc-fixed-register.c create mode 100644 llvm/test/CodeGen/SPARC/reserved-arg-regs.ll diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index df12ba8fbcb296..94bdeff28d0146 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5730,6 +5730,18 @@ def mvis3 : Flag<["-"], "mvis3">, Group; def mno_vis3 : Flag<["-"], "mno-vis3">, Group; def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group; def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group; +foreach i = {1-7} in + def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group, +HelpText<"Reserve the G"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_o#i : Flag<["-"], "ffixed-o"#i>, Group, +HelpText<"Reserve the O"#i#" register (SPARC only)">; +foreach i = {0-7} in + def ffixed_l#i : Flag<["-"], "ffixed-l"#i>, Group, +HelpText<"Reserve the L"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_i#i : Flag<["-"], "ffixed-i"#i>, Group, +HelpText<"Reserve the I"#i#" register (SPARC only)">; } // let Flags = [TargetSpecific] // M68k features flags diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp index 22e583021515e5..ae1a4ba7882627 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -178,4 +178,85 @@ void sparc::getSparcTargetFeatures(const Driver , const ArgList , else Features.push_back("-hard-quad-float"); } + + if (Args.hasArg(options::OPT_ffixed_g1)) +Features.push_back("+reserve-g1"); + + if (Args.hasArg(options::OPT_ffixed_g2)) +Features.push_back("+reserve-g2"); + + if (Args.hasArg(options::OPT_ffixed_g3)) +Features.push_back("+reserve-g3"); + + if (Args.hasArg(options::OPT_ffixed_g4)) +Features.push_back("+reserve-g4"); + + if (Args.hasArg(options::OPT_ffixed_g5)) +Features.push_back("+reserve-g5"); + + if (Args.hasArg(options::OPT_ffixed_g6)) +Features.push_back("+reserve-g6"); + + if (Args.hasArg(options::OPT_ffixed_g7)) +Features.push_back("+reserve-g7"); + + if (Args.hasArg(options::OPT_ffixed_o0)) +Features.push_back("+reserve-o0"); + + if (Args.hasArg(options::OPT_ffixed_o1)) +Features.push_back("+reserve-o1"); + + if (Args.hasArg(options::OPT_ffixed_o2)) +Features.push_back("+reserve-o2"); + + if (Args.hasArg(options::OPT_ffixed_o3)) +Features.push_back("+reserve-o3"); + + if (Args.hasArg(options::OPT_ffixed_o4)) +Features.push_back("+reserve-o4"); + + if (Args.hasArg(options::OPT_ffixed_o5)) +Features.push_back("+reserve-o5"); + + if (Args.hasArg(options::OPT_ffixed_l0)) +Features.push_back("+reserve-l0"); + + if (Args.hasArg(options::OPT_ffixed_l1)) +Features.push_back("+reserve-l1"); + + if (Args.hasArg(options::OPT_ffixed_l2)) +Features.push_back("+reserve-l2"); + + if (Args.hasArg(options::OPT_ffixed_l3)) +Features.push_back("+reserve-l3"); + + if (Args.hasArg(options::OPT_ffixed_l4)) +Features.push_back("+reserve-l4"); + + if (Args.hasArg(options::OPT_ffixed_l5)) +Features.push_back("+reserve-l5"); + + if (Args.hasArg(options::OPT_ffixed_l6)) +Features.push_back("+reserve-l6"); + + if (Args.hasArg(options::OPT_ffixed_l7)) +Features.push_back("+reserve-l7"); + + if (Args.hasArg(options::OPT_ffixed_i0)) +Features.push_back("+reserve-i0"); + + if (Args.hasArg(options::OPT_ffixed_i1)) +Features.push_back("+reserve-i1"); + + if (Args.hasArg(options::OPT_ffixed_i2)) +Features.push_back("+reserve-i2"); + + if (Args.hasArg(options::OPT_ffixed_i3)) +Features.push_back("+reserve-i3"); + + if
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -98,9 +98,52 @@ BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction ) const { for (unsigned n = 0; n < 31; n++) Reserved.set(SP::ASR1 + n); + for (size_t i = 0; i < SP::IntRegsRegClass.getNumRegs() / 4; ++i) { +// Mark both single register and register pairs. +if (MF.getSubtarget().isGRegisterReserved(i)) { + Reserved.set(SP::G0 + i); + Reserved.set(SP::G0_G1 + i / 2); +} +if (MF.getSubtarget().isORegisterReserved(i)) { + Reserved.set(SP::O0 + i); + Reserved.set(SP::O0_O1 + i / 2); +} +if (MF.getSubtarget().isLRegisterReserved(i)) { + Reserved.set(SP::L0 + i); + Reserved.set(SP::L0_L1 + i / 2); +} +if (MF.getSubtarget().isIRegisterReserved(i)) { + Reserved.set(SP::I0 + i); + Reserved.set(SP::I0_I1 + i / 2); +} + } + return Reserved; } +bool SparcRegisterInfo::isReservedReg(const MachineFunction , + MCRegister Reg) const { + return getReservedRegs(MF)[Reg]; +} + +bool SparcRegisterInfo::isAnyArgRegReserved(const MachineFunction ) const { + bool Outgoing = + llvm::any_of(*SP::GPROutgoingArgRegClass.MC, s-barannikov wrote: ```suggestion llvm::any_of(SP::GPROutgoingArgRegClass, ``` MC is an internal field of TargetRegisterClass. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -5730,6 +5730,18 @@ def mvis3 : Flag<["-"], "mvis3">, Group; def mno_vis3 : Flag<["-"], "mno-vis3">, Group; def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group; def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group; +foreach i = {1-7} in s-barannikov wrote: The modern syntax is `foreach i = 1 ... 7 in`. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -1125,6 +1130,19 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT, .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7) .Default(0); + const SparcRegisterInfo *MRI = Subtarget->getRegisterInfo(); s-barannikov wrote: ```suggestion const SparcRegisterInfo *TRI = Subtarget->getRegisterInfo(); ``` https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
@@ -1125,6 +1130,19 @@ Register SparcTargetLowering::getRegisterByName(const char* RegName, LLT VT, .Case("g4", SP::G4).Case("g5", SP::G5).Case("g6", SP::G6).Case("g7", SP::G7) .Default(0); + const SparcRegisterInfo *MRI = Subtarget->getRegisterInfo(); + unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false); s-barannikov wrote: It looks strange to check dwarf register numbers here. Why don't compare register ids directly? E.g. `IsG = Reg >= SP::G0 && Reg <= SP::G7`. https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
koachan wrote: Ping? https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
koachan wrote: > Doesn’t the ABI require you to emit magic STT_REGISTER or whatever they are > symbols to mark this? Yeah, when targeting 64-bit and we're *not* reserving %g2, %g3, %g6, or %g7 then we should emit STT_SPARC_REGISTER entries for those registers. However, currently we never emit any of those in the first place. This should be fixed but I think it is better done as a separate PR? https://github.com/llvm/llvm-project/pull/74927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
llvmbot wrote: @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Koakuma (koachan) Changes This adds support for marking arbitrary general purpose registers - except for those with special purpose (G0, I6-I7, O6-O7) - as reserved, as needed by some software like the Linux kernel. --- Patch is 24.86 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74927.diff 12 Files Affected: - (modified) clang/include/clang/Driver/Options.td (+12) - (modified) clang/lib/Driver/ToolChains/Arch/Sparc.cpp (+81) - (added) clang/test/Driver/sparc-fixed-register.c (+181) - (modified) llvm/lib/Target/Sparc/Sparc.td (+14) - (modified) llvm/lib/Target/Sparc/SparcISelLowering.cpp (+23) - (modified) llvm/lib/Target/Sparc/SparcRegisterInfo.cpp (+44-1) - (modified) llvm/lib/Target/Sparc/SparcRegisterInfo.h (+3) - (modified) llvm/lib/Target/Sparc/SparcRegisterInfo.td (+4) - (modified) llvm/lib/Target/Sparc/SparcSubtarget.cpp (+5-1) - (modified) llvm/lib/Target/Sparc/SparcSubtarget.h (+11) - (added) llvm/test/CodeGen/SPARC/reserved-arg-regs.ll (+25) - (modified) llvm/test/CodeGen/SPARC/reserved-regs.ll (+17) ``diff diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index df12ba8fbcb29..94bdeff28d014 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5730,6 +5730,18 @@ def mvis3 : Flag<["-"], "mvis3">, Group; def mno_vis3 : Flag<["-"], "mno-vis3">, Group; def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group; def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group; +foreach i = {1-7} in + def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group, +HelpText<"Reserve the G"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_o#i : Flag<["-"], "ffixed-o"#i>, Group, +HelpText<"Reserve the O"#i#" register (SPARC only)">; +foreach i = {0-7} in + def ffixed_l#i : Flag<["-"], "ffixed-l"#i>, Group, +HelpText<"Reserve the L"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_i#i : Flag<["-"], "ffixed-i"#i>, Group, +HelpText<"Reserve the I"#i#" register (SPARC only)">; } // let Flags = [TargetSpecific] // M68k features flags diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp index 22e583021515e..ae1a4ba788262 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -178,4 +178,85 @@ void sparc::getSparcTargetFeatures(const Driver , const ArgList , else Features.push_back("-hard-quad-float"); } + + if (Args.hasArg(options::OPT_ffixed_g1)) +Features.push_back("+reserve-g1"); + + if (Args.hasArg(options::OPT_ffixed_g2)) +Features.push_back("+reserve-g2"); + + if (Args.hasArg(options::OPT_ffixed_g3)) +Features.push_back("+reserve-g3"); + + if (Args.hasArg(options::OPT_ffixed_g4)) +Features.push_back("+reserve-g4"); + + if (Args.hasArg(options::OPT_ffixed_g5)) +Features.push_back("+reserve-g5"); + + if (Args.hasArg(options::OPT_ffixed_g6)) +Features.push_back("+reserve-g6"); + + if (Args.hasArg(options::OPT_ffixed_g7)) +Features.push_back("+reserve-g7"); + + if (Args.hasArg(options::OPT_ffixed_o0)) +Features.push_back("+reserve-o0"); + + if (Args.hasArg(options::OPT_ffixed_o1)) +Features.push_back("+reserve-o1"); + + if (Args.hasArg(options::OPT_ffixed_o2)) +Features.push_back("+reserve-o2"); + + if (Args.hasArg(options::OPT_ffixed_o3)) +Features.push_back("+reserve-o3"); + + if (Args.hasArg(options::OPT_ffixed_o4)) +Features.push_back("+reserve-o4"); + + if (Args.hasArg(options::OPT_ffixed_o5)) +Features.push_back("+reserve-o5"); + + if (Args.hasArg(options::OPT_ffixed_l0)) +Features.push_back("+reserve-l0"); + + if (Args.hasArg(options::OPT_ffixed_l1)) +Features.push_back("+reserve-l1"); + + if (Args.hasArg(options::OPT_ffixed_l2)) +Features.push_back("+reserve-l2"); + + if (Args.hasArg(options::OPT_ffixed_l3)) +Features.push_back("+reserve-l3"); + + if (Args.hasArg(options::OPT_ffixed_l4)) +Features.push_back("+reserve-l4"); + + if (Args.hasArg(options::OPT_ffixed_l5)) +Features.push_back("+reserve-l5"); + + if (Args.hasArg(options::OPT_ffixed_l6)) +Features.push_back("+reserve-l6"); + + if (Args.hasArg(options::OPT_ffixed_l7)) +Features.push_back("+reserve-l7"); + + if (Args.hasArg(options::OPT_ffixed_i0)) +Features.push_back("+reserve-i0"); + + if (Args.hasArg(options::OPT_ffixed_i1)) +Features.push_back("+reserve-i1"); + + if (Args.hasArg(options::OPT_ffixed_i2)) +Features.push_back("+reserve-i2"); + + if (Args.hasArg(options::OPT_ffixed_i3)) +Features.push_back("+reserve-i3"); + + if (Args.hasArg(options::OPT_ffixed_i4)) +Features.push_back("+reserve-i4"); + + if (Args.hasArg(options::OPT_ffixed_i5)) +Features.push_back("+reserve-i5"); } diff --git
[llvm] [clang] [SPARC] Support reserving arbitrary general purpose registers (PR #74927)
https://github.com/koachan created https://github.com/llvm/llvm-project/pull/74927 This adds support for marking arbitrary general purpose registers - except for those with special purpose (G0, I6-I7, O6-O7) - as reserved, as needed by some software like the Linux kernel. >From 956ca7e210a438caac7c5dda8c9945305a53de39 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 29 Nov 2023 08:08:29 +0700 Subject: [PATCH] [SPARC] Support reserving arbitrary general purpose registers This adds support for marking arbitrary general purpose registers - except for those with special purpose (G0, I6-I7, O6-O7) - as reserved, as needed by some software like the Linux kernel. --- clang/include/clang/Driver/Options.td| 12 ++ clang/lib/Driver/ToolChains/Arch/Sparc.cpp | 81 + clang/test/Driver/sparc-fixed-register.c | 181 +++ llvm/lib/Target/Sparc/Sparc.td | 14 ++ llvm/lib/Target/Sparc/SparcISelLowering.cpp | 23 +++ llvm/lib/Target/Sparc/SparcRegisterInfo.cpp | 45 - llvm/lib/Target/Sparc/SparcRegisterInfo.h| 3 + llvm/lib/Target/Sparc/SparcRegisterInfo.td | 4 + llvm/lib/Target/Sparc/SparcSubtarget.cpp | 6 +- llvm/lib/Target/Sparc/SparcSubtarget.h | 11 ++ llvm/test/CodeGen/SPARC/reserved-arg-regs.ll | 25 +++ llvm/test/CodeGen/SPARC/reserved-regs.ll | 17 ++ 12 files changed, 420 insertions(+), 2 deletions(-) create mode 100644 clang/test/Driver/sparc-fixed-register.c create mode 100644 llvm/test/CodeGen/SPARC/reserved-arg-regs.ll diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index df12ba8fbcb296..94bdeff28d0146 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5730,6 +5730,18 @@ def mvis3 : Flag<["-"], "mvis3">, Group; def mno_vis3 : Flag<["-"], "mno-vis3">, Group; def mhard_quad_float : Flag<["-"], "mhard-quad-float">, Group; def msoft_quad_float : Flag<["-"], "msoft-quad-float">, Group; +foreach i = {1-7} in + def ffixed_g#i : Flag<["-"], "ffixed-g"#i>, Group, +HelpText<"Reserve the G"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_o#i : Flag<["-"], "ffixed-o"#i>, Group, +HelpText<"Reserve the O"#i#" register (SPARC only)">; +foreach i = {0-7} in + def ffixed_l#i : Flag<["-"], "ffixed-l"#i>, Group, +HelpText<"Reserve the L"#i#" register (SPARC only)">; +foreach i = {0-5} in + def ffixed_i#i : Flag<["-"], "ffixed-i"#i>, Group, +HelpText<"Reserve the I"#i#" register (SPARC only)">; } // let Flags = [TargetSpecific] // M68k features flags diff --git a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp index 22e583021515e5..ae1a4ba7882627 100644 --- a/clang/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/clang/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -178,4 +178,85 @@ void sparc::getSparcTargetFeatures(const Driver , const ArgList , else Features.push_back("-hard-quad-float"); } + + if (Args.hasArg(options::OPT_ffixed_g1)) +Features.push_back("+reserve-g1"); + + if (Args.hasArg(options::OPT_ffixed_g2)) +Features.push_back("+reserve-g2"); + + if (Args.hasArg(options::OPT_ffixed_g3)) +Features.push_back("+reserve-g3"); + + if (Args.hasArg(options::OPT_ffixed_g4)) +Features.push_back("+reserve-g4"); + + if (Args.hasArg(options::OPT_ffixed_g5)) +Features.push_back("+reserve-g5"); + + if (Args.hasArg(options::OPT_ffixed_g6)) +Features.push_back("+reserve-g6"); + + if (Args.hasArg(options::OPT_ffixed_g7)) +Features.push_back("+reserve-g7"); + + if (Args.hasArg(options::OPT_ffixed_o0)) +Features.push_back("+reserve-o0"); + + if (Args.hasArg(options::OPT_ffixed_o1)) +Features.push_back("+reserve-o1"); + + if (Args.hasArg(options::OPT_ffixed_o2)) +Features.push_back("+reserve-o2"); + + if (Args.hasArg(options::OPT_ffixed_o3)) +Features.push_back("+reserve-o3"); + + if (Args.hasArg(options::OPT_ffixed_o4)) +Features.push_back("+reserve-o4"); + + if (Args.hasArg(options::OPT_ffixed_o5)) +Features.push_back("+reserve-o5"); + + if (Args.hasArg(options::OPT_ffixed_l0)) +Features.push_back("+reserve-l0"); + + if (Args.hasArg(options::OPT_ffixed_l1)) +Features.push_back("+reserve-l1"); + + if (Args.hasArg(options::OPT_ffixed_l2)) +Features.push_back("+reserve-l2"); + + if (Args.hasArg(options::OPT_ffixed_l3)) +Features.push_back("+reserve-l3"); + + if (Args.hasArg(options::OPT_ffixed_l4)) +Features.push_back("+reserve-l4"); + + if (Args.hasArg(options::OPT_ffixed_l5)) +Features.push_back("+reserve-l5"); + + if (Args.hasArg(options::OPT_ffixed_l6)) +Features.push_back("+reserve-l6"); + + if (Args.hasArg(options::OPT_ffixed_l7)) +Features.push_back("+reserve-l7"); + + if (Args.hasArg(options::OPT_ffixed_i0)) +Features.push_back("+reserve-i0"); + + if (Args.hasArg(options::OPT_ffixed_i1)) +Features.push_back("+reserve-i1"); + + if