[RFC,V2] RISC-V : Support rv64 ilp32
Checks
Commit Message
This patch support ilp32 on rv64.
It remove option check when -march=rv64* -mabi=ilp32. And replace XLEN_SPEC in
LINK_SPEC by ABI_LEN_SPEC. In addition, it some machine descriptions.
The series kernel support in this link.
https://lore.kernel.org/linux-riscv/20230518131013.3366406-1-guoren@kernel.org/
gcc/ChangeLog:
* config.gcc:
* config/riscv/elf.h (LINK_SPEC):
* config/riscv/linux.h (LINK_SPEC):
* config/riscv/riscv.cc (riscv_option_override):
* config/riscv/riscv.h (TARGET_ILP32):
(POINTER_SIZE):
(Pmode):
(ABI_LEN_SPEC):
* config/riscv/riscv.md:
---
gcc/config.gcc | 3 +++
gcc/config/riscv/elf.h | 2 +-
gcc/config/riscv/linux.h | 2 +-
gcc/config/riscv/riscv.cc | 4 ----
gcc/config/riscv/riscv.h | 12 ++++++++++--
gcc/config/riscv/riscv.md | 8 ++++++--
6 files changed, 21 insertions(+), 10 deletions(-)
Comments
I am concern about we didn't define POINTERS_EXTEND_UNSIGNED here, and
also concern about the code model stuffs, I know currently Guo-Ren's
implementation is rely on some MMU trick, but I am not sure does it
also applicable on embedded applications.
> diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
> index b9557a75dc7..4f33c88ef6e 100644
> --- a/gcc/config/riscv/linux.h
> +++ b/gcc/config/riscv/linux.h
> @@ -58,7 +58,7 @@ along with GCC; see the file COPYING3. If not see
> "%{mabi=ilp32:_ilp32}"
>
> #define LINK_SPEC "\
> --melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
> +-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
> %{mno-relax:--no-relax} \
> %{mbig-endian:-EB} \
> %{mlittle-endian:-EL} \
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 5f44f6dc5c9..09ab940447d 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -6291,10 +6291,6 @@ riscv_option_override (void)
> && riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
> error ("z*inx requires ABI ilp32, ilp32e or lp64");
>
> - /* We do not yet support ILP32 on RV64. */
> - if (BITS_PER_WORD != POINTER_SIZE)
> - error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
It seems to also make -march=rv32g -mabi=lp64 become acceptable?
>
Thanks for your advice, Kito.
在 2023/5/19 15:35, Kito Cheng 写道:
> I am concern about we didn't define POINTERS_EXTEND_UNSIGNED here, and
> also concern about the code model stuffs, I know currently Guo-Ren's
> implementation is rely on some MMU trick, but I am not sure does it
> also applicable on embedded applications.
>
>
OK,we will verify this in the future.
>>
>> - /* We do not yet support ILP32 on RV64. */
>> - if (BITS_PER_WORD != POINTER_SIZE)
>> - error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
>
> It seems to also make -march=rv32g -mabi=lp64 become acceptable?
>
Oh, I was negligent and will make improvements in the next patch.
Best Regards
Liao Shihua
On Fri, May 19, 2023 at 3:35 PM Kito Cheng <kito.cheng@sifive.com> wrote:
>
> I am concern about we didn't define POINTERS_EXTEND_UNSIGNED here, and
> also concern about the code model stuffs, I know currently Guo-Ren's
> implementation is rely on some MMU trick, but I am not sure does it
> also applicable on embedded applications.
There are two ways:
- Limit address < 2GB. (Fortunately, most MCUs have a limit on their
address of less than 2GB.)
- The zjpm liked hardware extension could mask highest 32 bits of the address.
>
>
> > diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
> > index b9557a75dc7..4f33c88ef6e 100644
> > --- a/gcc/config/riscv/linux.h
> > +++ b/gcc/config/riscv/linux.h
> > @@ -58,7 +58,7 @@ along with GCC; see the file COPYING3. If not see
> > "%{mabi=ilp32:_ilp32}"
> >
> > #define LINK_SPEC "\
> > --melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
> > +-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
> > %{mno-relax:--no-relax} \
> > %{mbig-endian:-EB} \
> > %{mlittle-endian:-EL} \
> > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> > index 5f44f6dc5c9..09ab940447d 100644
> > --- a/gcc/config/riscv/riscv.cc
> > +++ b/gcc/config/riscv/riscv.cc
> > @@ -6291,10 +6291,6 @@ riscv_option_override (void)
> > && riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
> > error ("z*inx requires ABI ilp32, ilp32e or lp64");
> >
> > - /* We do not yet support ILP32 on RV64. */
> > - if (BITS_PER_WORD != POINTER_SIZE)
> > - error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
>
> It seems to also make -march=rv32g -mabi=lp64 become acceptable?
>
> >
On Mon, May 22, 2023 at 10:51 AM Guo Ren <guoren@kernel.org> wrote:
>
> On Fri, May 19, 2023 at 3:35 PM Kito Cheng <kito.cheng@sifive.com> wrote:
> >
> > I am concern about we didn't define POINTERS_EXTEND_UNSIGNED here, and
> > also concern about the code model stuffs, I know currently Guo-Ren's
> > implementation is rely on some MMU trick, but I am not sure does it
> > also applicable on embedded applications.
> There are two ways:
> - Limit address < 2GB. (Fortunately, most MCUs have a limit on their
> address of less than 2GB.)
> - The zjpm liked hardware extension could mask the highest 32 bits of the address.
I guess your question is: Shall we start the work of the GCC's
POINTERS_EXTEND_UNSIGNED?
If the SoC's start address of dram > 2GB, we need the GCC's
POINTERS_EXTEND_UNSIGNED.
>
> >
> >
> > > diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
> > > index b9557a75dc7..4f33c88ef6e 100644
> > > --- a/gcc/config/riscv/linux.h
> > > +++ b/gcc/config/riscv/linux.h
> > > @@ -58,7 +58,7 @@ along with GCC; see the file COPYING3. If not see
> > > "%{mabi=ilp32:_ilp32}"
> > >
> > > #define LINK_SPEC "\
> > > --melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
> > > +-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
> > > %{mno-relax:--no-relax} \
> > > %{mbig-endian:-EB} \
> > > %{mlittle-endian:-EL} \
> > > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> > > index 5f44f6dc5c9..09ab940447d 100644
> > > --- a/gcc/config/riscv/riscv.cc
> > > +++ b/gcc/config/riscv/riscv.cc
> > > @@ -6291,10 +6291,6 @@ riscv_option_override (void)
> > > && riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
> > > error ("z*inx requires ABI ilp32, ilp32e or lp64");
> > >
> > > - /* We do not yet support ILP32 on RV64. */
> > > - if (BITS_PER_WORD != POINTER_SIZE)
> > > - error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
> >
> > It seems to also make -march=rv32g -mabi=lp64 become acceptable?
> >
> > >
>
>
>
> --
> Best Regards
> Guo Ren
@@ -4658,6 +4658,9 @@ case "${target}" in
ilp32,rv32* | ilp32e,rv32e* \
| ilp32f,rv32*f* | ilp32f,rv32g* \
| ilp32d,rv32*d* | ilp32d,rv32g* \
+ | ilp32f,rv64*f* | ilp32f,rv64g* \
+ | ilp32d,rv64*d* | ilp32d,rv64g* \
+ | ilp32,rv64* \
| lp64,rv64* \
| lp64f,rv64*f* | lp64f,rv64g* \
| lp64d,rv64*d* | lp64d,rv64g*)
@@ -18,7 +18,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#define LINK_SPEC "\
--melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
+-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
%{mno-relax:--no-relax} \
%{mbig-endian:-EB} \
%{mlittle-endian:-EL} \
@@ -58,7 +58,7 @@ along with GCC; see the file COPYING3. If not see
"%{mabi=ilp32:_ilp32}"
#define LINK_SPEC "\
--melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
+-melf" ABI_LEN_SPEC DEFAULT_ENDIAN_SPEC "riscv" LD_EMUL_SUFFIX " \
%{mno-relax:--no-relax} \
%{mbig-endian:-EB} \
%{mlittle-endian:-EL} \
@@ -6291,10 +6291,6 @@ riscv_option_override (void)
&& riscv_abi != ABI_LP64 && riscv_abi != ABI_ILP32E)
error ("z*inx requires ABI ilp32, ilp32e or lp64");
- /* We do not yet support ILP32 on RV64. */
- if (BITS_PER_WORD != POINTER_SIZE)
- error ("ABI requires %<-march=rv%d%>", POINTER_SIZE);
-
/* Validate -mpreferred-stack-boundary= value. */
riscv_stack_boundary = ABI_STACK_BOUNDARY;
if (riscv_preferred_stack_boundary_arg)
@@ -77,6 +77,10 @@ extern const char *riscv_multi_lib_check (int argc, const char **argv);
#define TARGET_64BIT (__riscv_xlen == 64)
#endif /* IN_LIBGCC2 */
+#ifndef TARGET_ILP32
+#define TARGET_ILP32 (riscv_abi <= ABI_ILP32D)
+#endif /*TARGET_ILP32*/
+
#ifdef HAVE_AS_MISA_SPEC
#define ASM_MISA_SPEC "%{misa-spec=*}"
#else
@@ -172,7 +176,7 @@ ASM_MISA_SPEC
#define SHORT_TYPE_SIZE 16
#define INT_TYPE_SIZE 32
#define LONG_LONG_TYPE_SIZE 64
-#define POINTER_SIZE (riscv_abi >= ABI_LP64 ? 64 : 32)
+#define POINTER_SIZE (TARGET_ILP32 ? 32 : 64)
#define LONG_TYPE_SIZE POINTER_SIZE
#define FLOAT_TYPE_SIZE 32
@@ -789,7 +793,7 @@ typedef struct {
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
-#define Pmode word_mode
+#define Pmode (TARGET_ILP32 ? SImode : DImode)
/* Give call MEMs SImode since it is the "most permissive" mode
for both 32-bit and 64-bit targets. */
@@ -1039,6 +1043,10 @@ extern poly_int64 riscv_v_adjust_bytesize (enum machine_mode, int);
"%{march=rv32*:32}" \
"%{march=rv64*:64}" \
+#define ABI_LEN_SPEC \
+ "%{mabi=ilp32*:32}" \
+ "%{mabi=lp64*:64}" \
+
#define ABI_SPEC \
"%{mabi=ilp32:ilp32}" \
"%{mabi=ilp32e:ilp32e}" \
@@ -2737,6 +2737,10 @@
"reload_completed"
[(const_int 0)]
{
+ if (GET_MODE (operands[0]) != Pmode)
+ operands[0] = convert_to_mode (Pmode, operands[0], 0);
+ if (GET_MODE (operands[1]) != Pmode)
+ operands[1] = convert_to_mode (Pmode, operands[1], 0);
riscv_set_return_address (operands[0], operands[1]);
DONE;
})
@@ -2946,8 +2950,8 @@
(define_insn "stack_tie<mode>"
[(set (mem:BLK (scratch))
- (unspec:BLK [(match_operand:X 0 "register_operand" "r")
- (match_operand:X 1 "register_operand" "r")]
+ (unspec:BLK [(match_operand:P 0 "register_operand" "r")
+ (match_operand:P 1 "register_operand" "r")]
UNSPEC_TIE))]
""
""