[PATCH v4 6/7] RISC-V: Fix matches against subreg with a bytenum of 0 in riscv.md

2021-03-19 Thread Marcus Comstedt
These all intend the least significant subpart of the register.
Use the same endian-neutral "subreg_lowpart_operator" predicate that
ARM does instead.

gcc/
* config/riscv/predicates.md (subreg_lowpart_operator): New predicate
* config/riscv/riscv.md (*addsi3_extended2, *subsi3_extended2)
(*negsi2_extended2, *mulsi3_extended2, *si3_mask)
(*si3_mask_1, *di3_mask, *di3_mask_1)
(*si3_extend_mask, *si3_extend_mask_1): Use
new predicate "subreg_lowpart_operator"
---
 gcc/config/riscv/predicates.md |  5 +++
 gcc/config/riscv/riscv.md  | 70 +-
 2 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index ef821add663..23211513554 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -198,6 +198,11 @@
 (define_predicate "signed_order_operator"
   (match_code "eq,ne,lt,le,ge,gt"))
 
+(define_predicate "subreg_lowpart_operator"
+  (ior (match_code "truncate")
+   (and (match_code "subreg")
+(match_test "subreg_lowpart_p (op)"
+
 (define_predicate "fp_native_comparison"
   (match_code "eq,lt,le,gt,ge"))
 
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index fcdcc3abaa0..c3687d57047 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -480,9 +480,9 @@
 (define_insn "*addsi3_extended2"
   [(set (match_operand:DI   0 "register_operand" "=r,r")
(sign_extend:DI
- (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
- (match_operand:DI 2 "arith_operand"" r,I"))
-0)))]
+ (match_operator:SI 3 "subreg_lowpart_operator"
+[(plus:DI (match_operand:DI 1 "register_operand" " r,r")
+  (match_operand:DI 2 "arith_operand"" r,I"))])))]
   "TARGET_64BIT"
   "add%i2w\t%0,%1,%2"
   [(set_attr "type" "arith")
@@ -536,9 +536,9 @@
 (define_insn "*subsi3_extended2"
   [(set (match_operand:DI0 "register_operand" "= r")
(sign_extend:DI
- (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
-  (match_operand:DI 2 "register_operand" "  r"))
-0)))]
+ (match_operator:SI 3 "subreg_lowpart_operator"
+   [(minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
+  (match_operand:DI 2 "register_operand" "  r"))])))]
   "TARGET_64BIT"
   "subw\t%0,%z1,%2"
   [(set_attr "type" "arith")
@@ -572,8 +572,8 @@
 (define_insn "*negsi2_extended2"
   [(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
-(subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r"))
-   0)))]
+(match_operator:SI 2 "subreg_lowpart_operator"
+  [(neg:DI (match_operand:DI 1 "register_operand" " r"))])))]
   "TARGET_64BIT"
   "negw\t%0,%1"
   [(set_attr "type" "arith")
@@ -627,9 +627,9 @@
 (define_insn "*mulsi3_extended2"
   [(set (match_operand:DI   0 "register_operand" "=r")
(sign_extend:DI
- (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
- (match_operand:DI 2 "register_operand" " r"))
-0)))]
+ (match_operator:SI 3 "subreg_lowpart_operator"
+   [(mult:DI (match_operand:DI 1 "register_operand" " r")
+ (match_operand:DI 2 "register_operand" " r"))])))]
   "TARGET_MUL && TARGET_64BIT"
   "mulw\t%0,%1,%2"
   [(set_attr "type" "imul")
@@ -1591,10 +1591,10 @@
   [(set (match_operand:SI 0 "register_operand" "= r")
(any_shift:SI
(match_operand:SI 1 "register_operand" "  r")
-   (subreg:QI
-(and:SI
- (match_operand:SI 2 "register_operand"  "r")
- (match_operand 3 "const_int_operand")) 0)))]
+   (match_operator 4 "subreg_lowpart_operator"
+[(and:SI
+  (match_operand:SI 2 "register_operand"  "r")
+  (match_operand 3 "const_int_operand"))])))]
   "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
== GET_MODE_BITSIZE (SImode)-1"
   "#"
@@ -1610,10 +1610,10 @@
   [(set (match_operand:SI 0 "register_operand" "= r")
(any_shift:SI
(match_operand:SI 1 "register_operand" "  r")
-   (subreg:QI
-(and:DI
- (match_operand:DI 2 "register_operand"  "r")
- (match_operand 3 "const_int_operand")) 0)))]
+   (match_operator 4 "subreg_lowpart_operator"
+[(and:DI
+  (match_operand:DI 2 "register_operand"  "r")
+  (match_operand 3 "const_int_operand"))])))]
   "TARGET_64BIT
&& (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
== GET_MODE_BITSIZE (SImode)-1"
@@ -1646,10 +1646,10 @@
   [(set (match_operand:DI 0 

[PATCH v4 7/7] RISC-V: Fix riscv_subword() for big endian

2021-03-19 Thread Marcus Comstedt
gcc/
* config/riscv/riscv.c (riscv_subword): Take endianness into
account when calculating the byte offset.
---
 gcc/config/riscv/riscv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 1cd795bd19c..2f624e2123d 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -1966,7 +1966,7 @@ riscv_address_cost (rtx addr, machine_mode mode,
 rtx
 riscv_subword (rtx op, bool high_p)
 {
-  unsigned int byte = high_p ? UNITS_PER_WORD : 0;
+  unsigned int byte = (high_p != BYTES_BIG_ENDIAN) ? UNITS_PER_WORD : 0;
   machine_mode mode = GET_MODE (op);
 
   if (mode == VOIDmode)
-- 
2.26.2



[PATCH v4 5/7] RISC-V: Update shift-shift-5.c testcase for big endian

2021-03-19 Thread Marcus Comstedt
gcc/
* testsuite/gcc.target/riscv/shift-shift-5.c (sub): Change
order of struct fields depending on byteorder.
---
 gcc/testsuite/gcc.target/riscv/shift-shift-5.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c 
b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
index 5b2ae89a471..0ecab9723c9 100644
--- a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
+++ b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
@@ -7,7 +7,11 @@ unsigned long
 sub (long l)
 {
   union u {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 struct s { int a : 19; unsigned int b : 13; int x; } s;
+#else
+struct s { int x; unsigned int b : 13; int a : 19; } s;
+#endif
 long l;
   } u;
   u.l = l;
-- 
2.26.2



[PATCH v4 4/7] RISC-V: Fix trampoline generation on big endian

2021-03-19 Thread Marcus Comstedt
gcc/
* config/riscv/riscv.c (riscv_swap_instruction): New function
to byteswap an SImode rtx containing an instruction.
(riscv_trampoline_init): Byteswap the generated instructions
when needed.
---
 gcc/config/riscv/riscv.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index eab14602355..1cd795bd19c 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -1073,6 +1073,15 @@ riscv_force_binary (machine_mode mode, enum rtx_code 
code, rtx x, rtx y)
   return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
 }
 
+static rtx
+riscv_swap_instruction (rtx inst)
+{
+  gcc_assert (GET_MODE (inst) == SImode);
+  if (BYTES_BIG_ENDIAN)
+inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1);
+  return inst;
+}
+
 /* Copy VALUE to a register and return that register.  If new pseudos
are allowed, copy it into a new register, otherwise use DEST.  */
 
@@ -4953,7 +4962,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
 gen_int_mode (lui_hi_chain_code, 
SImode));
 
   mem = adjust_address (m_tramp, SImode, 0);
-  riscv_emit_move (mem, lui_hi_chain);
+  riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain));
 
   /* Gen lui t0, hi(func).  */
   rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
@@ -4965,7 +4974,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
gen_int_mode (lui_hi_func_code, 
SImode));
 
   mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, lui_hi_func);
+  riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func));
 
   /* Gen addi t2, t2, lo(chain).  */
   rtx lo_chain = riscv_force_binary (SImode, AND, chain_value,
@@ -4980,7 +4989,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
  force_reg (SImode, GEN_INT 
(lo_chain_code)));
 
   mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, addi_lo_chain);
+  riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain));
 
   /* Gen jr t0, lo(func).  */
   rtx lo_func = riscv_force_binary (SImode, AND, target_function,
@@ -4993,7 +5002,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
   force_reg (SImode, GEN_INT 
(lo_func_code)));
 
   mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, jr_lo_func);
+  riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func));
 }
   else
 {
@@ -5019,6 +5028,8 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
   /* Copy the trampoline code.  */
   for (i = 0; i < ARRAY_SIZE (trampoline); i++)
{
+ if (BYTES_BIG_ENDIAN)
+   trampoline[i] = __builtin_bswap32(trampoline[i]);
  mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
  riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
}
-- 
2.26.2



[PATCH v4 3/7] RISC-V: Update soft-fp config for big-endian

2021-03-19 Thread Marcus Comstedt
libgcc/
* config/riscv/sfp-machine.h (__BYTE_ORDER): Set according
to __BYTE_ORDER__.
---
 libgcc/config/riscv/sfp-machine.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgcc/config/riscv/sfp-machine.h 
b/libgcc/config/riscv/sfp-machine.h
index db2697157ce..8adbf4b8b2e 100644
--- a/libgcc/config/riscv/sfp-machine.h
+++ b/libgcc/config/riscv/sfp-machine.h
@@ -128,7 +128,11 @@ do {   
\
 #define__LITTLE_ENDIAN 1234
 #define__BIG_ENDIAN4321
 
+#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
 #define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
 
 
 /* Define ALIASNAME as a strong alias for NAME.  */
-- 
2.26.2



[PATCH v4 2/7] RISC-V: Add riscv{32,64}be with big endian as default

2021-03-19 Thread Marcus Comstedt
gcc/
* common/config/riscv/riscv-common.c
(TARGET_DEFAULT_TARGET_FLAGS): Set default endianness.
* config.gcc (riscv32be-*, riscv64be-*): Set
TARGET_BIG_ENDIAN_DEFAULT to 1.
* config/riscv/elf.h (LINK_SPEC): Change -melf* value
depending on default endianness.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.c (TARGET_DEFAULT_TARGET_FLAGS): Set
default endianness.
* config/riscv/riscv.h (DEFAULT_ENDIAN_SPEC): New macro.
---
 gcc/common/config/riscv/riscv-common.c |  5 +
 gcc/config.gcc | 15 +++
 gcc/config/riscv/elf.h |  2 +-
 gcc/config/riscv/freebsd.h |  2 +-
 gcc/config/riscv/linux.h   |  2 +-
 gcc/config/riscv/riscv.c   |  5 +
 gcc/config/riscv/riscv.h   |  6 ++
 7 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.c 
b/gcc/common/config/riscv/riscv-common.c
index 6bbe25dba89..34b74e52a2d 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -32,6 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "config/riscv/riscv-protos.h"
 #include "config/riscv/riscv-subset.h"
 
+#ifdef  TARGET_BIG_ENDIAN_DEFAULT
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
+#endif
+
 /* Type for implied ISA info.  */
 struct riscv_implied_info_t
 {
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 17fea83b2e4..ae47e430062 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2464,6 +2464,11 @@ riscv*-*-linux*)
tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2487,6 +2492,11 @@ riscv*-*-elf* | riscv*-*-rtems*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2496,6 +2506,11 @@ riscv*-*-freebsd*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index 973efdaed7b..7e65e499031 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -18,7 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #define LINK_SPEC "\
--melf" XLEN_SPEC "lriscv \
+-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
 %{mno-relax:--no-relax} \
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index f3aca9f7673..6018e7bb764 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef LINK_SPEC
 #define LINK_SPEC "\
-  -melf" XLEN_SPEC "lriscv \
+  -melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv  \
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index e74f5d3f914..fce5b896e6e 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 "lriscv" LD_EMUL_SUFFIX " \
+-melf" XLEN_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.c b/gcc/config/riscv/riscv.c
index fffd0814eee..eab14602355 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -5524,6 +5524,11 @@ riscv_asan_shadow_offset (void)
 #undef TARGET_ASAN_SHADOW_OFFSET
 #define TARGET_ASAN_SHADOW_OFFSET 

[PATCH v4 1/7] RISC-V: Support -mlittle-endian and -mbig-endian

2021-03-19 Thread Marcus Comstedt
gcc/
* config/riscv/elf.h (LINK_SPEC): Pass linker endianness flag.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.h (ASM_SPEC): Pass -mbig-endian and
-mlittle-endian.
(BYTES_BIG_ENDIAN): Handle big endian.
(WORDS_BIG_ENDIAN): Define to BYTES_BIG_ENDIAN.
* config/riscv/riscv.opt (-mbig-endian, -mlittle-endian): New
options.
* doc/invoke.texi (-mbig-endian, -mlittle-endian): Document.
---
 gcc/config/riscv/elf.h |  2 ++
 gcc/config/riscv/freebsd.h |  2 ++
 gcc/config/riscv/linux.h   |  2 ++
 gcc/config/riscv/riscv.h   |  6 --
 gcc/config/riscv/riscv.opt |  8 
 gcc/doc/invoke.texi| 12 
 6 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index d136d46e4fa..973efdaed7b 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared}"
 
 /* Link against Newlib libraries, because the ELF backend assumes Newlib.
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index a48bf9bffe4..f3aca9f7673 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -44,6 +44,8 @@ along with GCC; see the file COPYING3.  If not see
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
+  %{mbig-endian:-EB}   \
+  %{mlittle-endian:-EL}\
   %{shared:-Bshareable %{h*} %{soname*}}   \
   %{symbolic:-Bsymbolic}   \
   %{static:-Bstatic}   \
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index 9238de5bc92..e74f5d3f914 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -60,6 +60,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv" LD_EMUL_SUFFIX " \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared} \
   %{!shared: \
 %{!static: \
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index c6f8bee07ef..0b667d2e8b9 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -91,6 +91,8 @@ extern const char *riscv_default_mtune (int argc, const char 
**argv);
 %{" FPIE_OR_FPIC_SPEC ":-fpic} \
 %{march=*} \
 %{mabi=*} \
+%{mbig-endian} \
+%{mlittle-endian} \
 %(subtarget_asm_spec)" \
 ASM_MISA_SPEC
 
@@ -126,8 +128,8 @@ ASM_MISA_SPEC
 /* Target machine storage layout */
 
 #define BITS_BIG_ENDIAN 0
-#define BYTES_BIG_ENDIAN 0
-#define WORDS_BIG_ENDIAN 0
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
+#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
 
 #define MAX_BITS_PER_WORD 64
 
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 761a09d18c3..e294e223151 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -21,6 +21,14 @@
 HeaderInclude
 config/riscv/riscv-opts.h
 
+mbig-endian
+Target RejectNegative Mask(BIG_ENDIAN)
+Assume target CPU is configured as big endian.
+
+mlittle-endian
+Target RejectNegative InverseMask(BIG_ENDIAN)
+Assume target CPU is configured as little endian.
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(riscv_branch_cost)
 -mbranch-cost=NSet the cost of branches to roughly N instructions.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e8baa545eee..9279a37a832 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1169,6 +1169,7 @@ See RS/6000 and PowerPC Options.
 -mrelax  -mno-relax @gol
 -mriscv-attribute  -mmo-riscv-attribute @gol
 -malign-data=@var{type} @gol
+-mbig-endian  -mlittle-endian @gol
 +-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
 +-mstack-protector-guard-offset=@var{offset}}
 
@@ -26721,6 +26722,17 @@ types.  Supported values for @var{type} are 
@samp{xlen} which uses x register
 width as the alignment value, and @samp{natural} which uses natural alignment.
 @samp{xlen} is the default.
 
+@item -mbig-endian
+@opindex mbig-endian
+Generate big-endian code.  This is the default when GCC is configured for a
+@samp{riscv64be-*-*} or @samp{riscv32be-*-*} target.
+
+@item -mlittle-endian
+@opindex mlittle-endian
+Generate little-endian code.  This is the default when GCC is configured for a
+@samp{riscv64-*-*} or @samp{riscv32-*-*} but not a @samp{riscv64be-*-*} or
+@samp{riscv32be-*-*} target.
+
 @item -mstack-protector-guard=@var{guard}
 @itemx -mstack-protector-guard-reg=@var{reg}
 @itemx 

[PATCH v4 0/7] RISC-V big endian support

2021-03-19 Thread Marcus Comstedt
New update of the RISC-V big endian support.

Changes since v3:

* Changed riscv_subword to take endianness into account.  This
  fixed multiple issues with long long on 32-bit.

Testsuite results are now on par with little endian also on 32 bit.
The only exception is gcc.c-torture/compile/pr35318.c, which has an
internal compiler error (test fail) on 32 bit big endian, but not
on 32 bit little endian (test pass, even though the generated code
looks suspicious).


  // Marcus




Re: [PATCH v2 0/5] RISC-V big endian support

2021-03-14 Thread Marcus Comstedt


Hello again Kito.

I've now delved a bit deeper into the failure of the testcase
gcc.c-torture/compile/pr35318.c on big endian RV32.

The point at which big endian diverges from little endian is where
process_alt_operands() is processing the "%0" constraint.  It calls
operands_match_p(), which succeeds on little endian but fails on
big endian.

On little endian, the two rtx:es passed to operands_match_p are
"r79:DF#0" and "r79:DF", while on big endian they are "r79:DF#4" and
"r79:DF".  While the first operand is different, it's actually saying
the same thing: The subreg with the least significant bits (meaning
the second register in the pair on big endian, and the first register
in the pair on little endian, what with two 32-bit integer registers
being allocated to hold a single 64-bit float).

The helper function lra_constraint_offset(), which is used by
operands_match_p, seems to be intended to handle this discrepancy.  It
contains the code

  if (WORDS_BIG_ENDIAN
  && is_a  (mode, _mode)
  && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD)
return hard_regno_nregs (regno, mode) - 1;

However, in this case the rule does not trigger because the mode of
the second operand (which is the one where an adjustment would be
needed) does not have a scalar_int_mode, it has DFmode.  If I relax
this code to also allow scalar_float_mode, then the operands_match_p
call succeeds also on big endian.  There is still an ICE triggered
further down the line though.

I seem to be finding more questions than answers here.  Questions such
as "is it really correct that the first operand to operands_match_p()
has modeSI but the second one has modeDF?", "_should_ the operands
match?", and "why is the least significant half singled out when there
is no computation being perfomed".

Given that the code generated for LE seems incorrect, I still suspect
that there is some deeper issue here not related to endianness (but
possibly related to using integer registers for passing floating point
values to/from asm statements) and that it just happens to not cause
an internal error (only bad code) on LE.

How would you like to proceed?  I don't feel confident that I will
find a definitive solution to this issue anytime soon, but it feels
like such a weird special case (who passes 64-bit floats in 32-bit
integer registers to their asm?) that it might be ok to just ignore
it.  If you agree I'll just repost the patchset with the final fix
added (solves all remaining 32-bit testcases save for this one)...


  // Marcus




Re: [PATCH v2 0/5] RISC-V big endian support

2021-02-26 Thread Marcus Comstedt


Hi Kito.

I fixed almost all of the rv32be testcase failures simply by taking
endianness into account on the first line of riscv_subword, which is
used for long long handling on 32-bit.

Now, I only have one failing testcase (which does not also fail on
little endian), and it's a doozy.

The test in question is gcc.c-torture/compile/pr35318.c.  The test in
its entirety is

  
  double x = 4, y;
  __asm__ volatile ("# %0,%1,%2,%3" : "=r,r" (x), "=r,r" (y) : "%0,0" (x), 
"m,r" (8));


(the asm comment in the first argument was added by me to track what
 the actual assignments were.)

When compiled with -mbig-endian, this results in an ICE:

---8<---
/tmp/pr35318.c: In function 'foo':
/tmp/pr35318.c:9:1: error: unrecognizable insn:
9 | }
  | ^
(insn 12 24 25 2 (parallel [
(set (reg:DF 11 a1 [orig:74 x ] [74])
(asm_operands/v:DF ("# %0,%1,%2,%3") ("=r,r") 0 [
(reg:SI 12 a2 [orig:74 x+4 ] [74])
(mem/c:DF (plus:SI (reg/f:SI 8 s0)
(const_int -40 [0xffd8])) [2 
%sfp+-24 S8 A64])
]
 [
(asm_input:DF ("%0,0") /tmp/pr35318.c:8)
(asm_input:SI ("m,r") /tmp/pr35318.c:8)
]
 [] /tmp/pr35318.c:8))
(set (reg:DF 15 a5 [orig:75 y ] [75])
(asm_operands/v:DF ("# %0,%1,%2,%3") ("=r,r") 1 [
(reg:SI 12 a2 [orig:74 x+4 ] [74])
(mem/c:DF (plus:SI (reg/f:SI 8 s0)
(const_int -40 [0xffd8])) [2 
%sfp+-24 S8 A64])
]
 [
(asm_input:DF ("%0,0") /tmp/pr35318.c:8)
(asm_input:SI ("m,r") /tmp/pr35318.c:8)
]
 [] /tmp/pr35318.c:8))
]) "/tmp/pr35318.c":8:3 -1
 (nil))
during RTL pass: reload
dump file: /tmp/pr35318b.txt
/tmp/pr35318.c:9:1: internal compiler error: in extract_constrain_insn, at 
recog.c:2670
0x101bf90b _fatal_insn(char const*, rtx_def const*, char const*, int, char 
const*)
../../../riscv-gcc/gcc/rtl-error.c:108
0x101bf953 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
../../../riscv-gcc/gcc/rtl-error.c:116
0x10a1193f extract_constrain_insn(rtx_insn*)
../../../riscv-gcc/gcc/recog.c:2670
0x1088fc77 check_rtl
../../../riscv-gcc/gcc/lra.c:2087
0x108971c7 lra(_IO_FILE*)
../../../riscv-gcc/gcc/lra.c:2505
0x1082fcb7 do_reload
../../../riscv-gcc/gcc/ira.c:5827
0x1082fcb7 execute
../../../riscv-gcc/gcc/ira.c:6013
---8<---

This insn looks extremely similar to one that's in the dump-rtl for
little endian:

---8<---
(insn 12 20 21 2 (parallel [
(set (reg:DF 13 a3 [orig:74 x ] [74])
(asm_operands/v:DF ("# %0,%1,%2,%3") ("=r,r") 0 [
(reg:SI 13 a3 [orig:74 x ] [74])
(mem/c:DF (plus:SI (reg/f:SI 8 s0)
(const_int -40 [0xffd8])) [2 
%sfp+-24 S8 A64])
]
 [
(asm_input:DF ("%0,0") /tmp/pr35318.c:8)
(asm_input:SI ("m,r") /tmp/pr35318.c:8)
]
 [] /tmp/pr35318.c:8))
(set (reg:DF 15 a5 [orig:75 y ] [75])
(asm_operands/v:DF ("# %0,%1,%2,%3") ("=r,r") 1 [
(reg:SI 13 a3 [orig:74 x ] [74])
(mem/c:DF (plus:SI (reg/f:SI 8 s0)
(const_int -40 [0xffd8])) [2 
%sfp+-24 S8 A64])
]
 [
(asm_input:DF ("%0,0") /tmp/pr35318.c:8)
(asm_input:SI ("m,r") /tmp/pr35318.c:8)
]
 [] /tmp/pr35318.c:8))
]) "/tmp/pr35318.c":8:3 -1
 (nil))
---8<---

So I don't know what's "unrecognizable" about it...

I also don't understand the code that is actually generated in the
little-endian case.

The way I read the asm statement, %2 should be a register (same as %0)
containing the (floating point?) value "4", and %3 should be a memory
location (assuming the first alternative is chosen) containing the
value "8".

However, looking at the generated assembler code, it seems that %2 is
a register (a3) which contains the integer value "8" and %3 is a
memory location (-40(s0)) which contains the floating point value
"4.0".  This seems mixed up.

---8<---
foo:
addisp,sp,-48
sw  s0,44(sp)
addis0,sp,48
lui a5,%hi(.LC0)
fld fa5,%lo(.LC0)(a5)
fsd fa5,-24(s0)
fld fa5,-24(s0)
li  a5,8
fsd fa5,-40(s0)
mv  a3,a5
 #APP
# 8 "/tmp/pr35318.c" 1
# a3,a5,a3,-40(s0)
# 0 "" 2
 #NO_APP
sw  

[PATCH v3 6/6] RISC-V: Fix matches against subreg with a bytenum of 0 in riscv.md

2021-02-24 Thread Marcus Comstedt
These all intend the least significant subpart of the register.
Use the same endian-neutral "subreg_lowpart_operator" predicate that
ARM does instead.

gcc/
* config/riscv/predicates.md (subreg_lowpart_operator): New predicate
* config/riscv/riscv.md (*addsi3_extended2, *subsi3_extended2)
(*negsi2_extended2, *mulsi3_extended2, *si3_mask)
(*si3_mask_1, *di3_mask, *di3_mask_1)
(*si3_extend_mask, *si3_extend_mask_1): Use
new predicate "subreg_lowpart_operator"
---
 gcc/config/riscv/predicates.md |  5 +++
 gcc/config/riscv/riscv.md  | 70 +-
 2 files changed, 40 insertions(+), 35 deletions(-)

diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
index ef821add663..23211513554 100644
--- a/gcc/config/riscv/predicates.md
+++ b/gcc/config/riscv/predicates.md
@@ -198,6 +198,11 @@
 (define_predicate "signed_order_operator"
   (match_code "eq,ne,lt,le,ge,gt"))
 
+(define_predicate "subreg_lowpart_operator"
+  (ior (match_code "truncate")
+   (and (match_code "subreg")
+(match_test "subreg_lowpart_p (op)"
+
 (define_predicate "fp_native_comparison"
   (match_code "eq,lt,le,gt,ge"))
 
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index fcdcc3abaa0..c3687d57047 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -480,9 +480,9 @@
 (define_insn "*addsi3_extended2"
   [(set (match_operand:DI   0 "register_operand" "=r,r")
(sign_extend:DI
- (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" " r,r")
- (match_operand:DI 2 "arith_operand"" r,I"))
-0)))]
+ (match_operator:SI 3 "subreg_lowpart_operator"
+[(plus:DI (match_operand:DI 1 "register_operand" " r,r")
+  (match_operand:DI 2 "arith_operand"" r,I"))])))]
   "TARGET_64BIT"
   "add%i2w\t%0,%1,%2"
   [(set_attr "type" "arith")
@@ -536,9 +536,9 @@
 (define_insn "*subsi3_extended2"
   [(set (match_operand:DI0 "register_operand" "= r")
(sign_extend:DI
- (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
-  (match_operand:DI 2 "register_operand" "  r"))
-0)))]
+ (match_operator:SI 3 "subreg_lowpart_operator"
+   [(minus:DI (match_operand:DI 1 "reg_or_0_operand" " rJ")
+  (match_operand:DI 2 "register_operand" "  r"))])))]
   "TARGET_64BIT"
   "subw\t%0,%z1,%2"
   [(set_attr "type" "arith")
@@ -572,8 +572,8 @@
 (define_insn "*negsi2_extended2"
   [(set (match_operand:DI 0 "register_operand" "=r")
(sign_extend:DI
-(subreg:SI (neg:DI (match_operand:DI 1 "register_operand" " r"))
-   0)))]
+(match_operator:SI 2 "subreg_lowpart_operator"
+  [(neg:DI (match_operand:DI 1 "register_operand" " r"))])))]
   "TARGET_64BIT"
   "negw\t%0,%1"
   [(set_attr "type" "arith")
@@ -627,9 +627,9 @@
 (define_insn "*mulsi3_extended2"
   [(set (match_operand:DI   0 "register_operand" "=r")
(sign_extend:DI
- (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" " r")
- (match_operand:DI 2 "register_operand" " r"))
-0)))]
+ (match_operator:SI 3 "subreg_lowpart_operator"
+   [(mult:DI (match_operand:DI 1 "register_operand" " r")
+ (match_operand:DI 2 "register_operand" " r"))])))]
   "TARGET_MUL && TARGET_64BIT"
   "mulw\t%0,%1,%2"
   [(set_attr "type" "imul")
@@ -1591,10 +1591,10 @@
   [(set (match_operand:SI 0 "register_operand" "= r")
(any_shift:SI
(match_operand:SI 1 "register_operand" "  r")
-   (subreg:QI
-(and:SI
- (match_operand:SI 2 "register_operand"  "r")
- (match_operand 3 "const_int_operand")) 0)))]
+   (match_operator 4 "subreg_lowpart_operator"
+[(and:SI
+  (match_operand:SI 2 "register_operand"  "r")
+  (match_operand 3 "const_int_operand"))])))]
   "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
== GET_MODE_BITSIZE (SImode)-1"
   "#"
@@ -1610,10 +1610,10 @@
   [(set (match_operand:SI 0 "register_operand" "= r")
(any_shift:SI
(match_operand:SI 1 "register_operand" "  r")
-   (subreg:QI
-(and:DI
- (match_operand:DI 2 "register_operand"  "r")
- (match_operand 3 "const_int_operand")) 0)))]
+   (match_operator 4 "subreg_lowpart_operator"
+[(and:DI
+  (match_operand:DI 2 "register_operand"  "r")
+  (match_operand 3 "const_int_operand"))])))]
   "TARGET_64BIT
&& (INTVAL (operands[3]) & (GET_MODE_BITSIZE (SImode)-1))
== GET_MODE_BITSIZE (SImode)-1"
@@ -1646,10 +1646,10 @@
   [(set (match_operand:DI 0 

[PATCH v3 5/6] RISC-V: Update shift-shift-5.c testcase for big endian

2021-02-24 Thread Marcus Comstedt
gcc/
* testsuite/gcc.target/riscv/shift-shift-5.c (sub): Change
order of struct fields depending on byteorder.
---
 gcc/testsuite/gcc.target/riscv/shift-shift-5.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c 
b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
index 5b2ae89a471..0ecab9723c9 100644
--- a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
+++ b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
@@ -7,7 +7,11 @@ unsigned long
 sub (long l)
 {
   union u {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 struct s { int a : 19; unsigned int b : 13; int x; } s;
+#else
+struct s { int x; unsigned int b : 13; int a : 19; } s;
+#endif
 long l;
   } u;
   u.l = l;
-- 
2.26.2



[PATCH v3 4/6] RISC-V: Fix trampoline generation on big endian

2021-02-24 Thread Marcus Comstedt
gcc/
* config/riscv/riscv.c (riscv_swap_instruction): New function
to byteswap an SImode rtx containing an instruction.
(riscv_trampoline_init): Byteswap the generated instructions
when needed.
---
 gcc/config/riscv/riscv.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index eab14602355..1cd795bd19c 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -1073,6 +1073,15 @@ riscv_force_binary (machine_mode mode, enum rtx_code 
code, rtx x, rtx y)
   return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
 }
 
+static rtx
+riscv_swap_instruction (rtx inst)
+{
+  gcc_assert (GET_MODE (inst) == SImode);
+  if (BYTES_BIG_ENDIAN)
+inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1);
+  return inst;
+}
+
 /* Copy VALUE to a register and return that register.  If new pseudos
are allowed, copy it into a new register, otherwise use DEST.  */
 
@@ -4953,7 +4962,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
 gen_int_mode (lui_hi_chain_code, 
SImode));
 
   mem = adjust_address (m_tramp, SImode, 0);
-  riscv_emit_move (mem, lui_hi_chain);
+  riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain));
 
   /* Gen lui t0, hi(func).  */
   rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
@@ -4965,7 +4974,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
gen_int_mode (lui_hi_func_code, 
SImode));
 
   mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, lui_hi_func);
+  riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func));
 
   /* Gen addi t2, t2, lo(chain).  */
   rtx lo_chain = riscv_force_binary (SImode, AND, chain_value,
@@ -4980,7 +4989,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
  force_reg (SImode, GEN_INT 
(lo_chain_code)));
 
   mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, addi_lo_chain);
+  riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain));
 
   /* Gen jr t0, lo(func).  */
   rtx lo_func = riscv_force_binary (SImode, AND, target_function,
@@ -4993,7 +5002,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
   force_reg (SImode, GEN_INT 
(lo_func_code)));
 
   mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, jr_lo_func);
+  riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func));
 }
   else
 {
@@ -5019,6 +5028,8 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
   /* Copy the trampoline code.  */
   for (i = 0; i < ARRAY_SIZE (trampoline); i++)
{
+ if (BYTES_BIG_ENDIAN)
+   trampoline[i] = __builtin_bswap32(trampoline[i]);
  mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
  riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
}
-- 
2.26.2



[PATCH v3 3/6] RISC-V: Update soft-fp config for big-endian

2021-02-24 Thread Marcus Comstedt
libgcc/
* config/riscv/sfp-machine.h (__BYTE_ORDER): Set according
to __BYTE_ORDER__.
---
 libgcc/config/riscv/sfp-machine.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgcc/config/riscv/sfp-machine.h 
b/libgcc/config/riscv/sfp-machine.h
index db2697157ce..8adbf4b8b2e 100644
--- a/libgcc/config/riscv/sfp-machine.h
+++ b/libgcc/config/riscv/sfp-machine.h
@@ -128,7 +128,11 @@ do {   
\
 #define__LITTLE_ENDIAN 1234
 #define__BIG_ENDIAN4321
 
+#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
 #define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
 
 
 /* Define ALIASNAME as a strong alias for NAME.  */
-- 
2.26.2



[PATCH v3 2/6] RISC-V: Add riscv{32,64}be with big endian as default

2021-02-24 Thread Marcus Comstedt
gcc/
* common/config/riscv/riscv-common.c
(TARGET_DEFAULT_TARGET_FLAGS): Set default endianness.
* config.gcc (riscv32be-*, riscv64be-*): Set
TARGET_BIG_ENDIAN_DEFAULT to 1.
* config/riscv/elf.h (LINK_SPEC): Change -melf* value
depending on default endianness.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.c (TARGET_DEFAULT_TARGET_FLAGS): Set
default endianness.
* config/riscv/riscv.h (DEFAULT_ENDIAN_SPEC): New macro.
---
 gcc/common/config/riscv/riscv-common.c |  5 +
 gcc/config.gcc | 15 +++
 gcc/config/riscv/elf.h |  2 +-
 gcc/config/riscv/freebsd.h |  2 +-
 gcc/config/riscv/linux.h   |  2 +-
 gcc/config/riscv/riscv.c   |  5 +
 gcc/config/riscv/riscv.h   |  6 ++
 7 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.c 
b/gcc/common/config/riscv/riscv-common.c
index 6bbe25dba89..34b74e52a2d 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -32,6 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "config/riscv/riscv-protos.h"
 #include "config/riscv/riscv-subset.h"
 
+#ifdef  TARGET_BIG_ENDIAN_DEFAULT
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
+#endif
+
 /* Type for implied ISA info.  */
 struct riscv_implied_info_t
 {
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 17fea83b2e4..ae47e430062 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2464,6 +2464,11 @@ riscv*-*-linux*)
tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2487,6 +2492,11 @@ riscv*-*-elf* | riscv*-*-rtems*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2496,6 +2506,11 @@ riscv*-*-freebsd*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index 973efdaed7b..7e65e499031 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -18,7 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #define LINK_SPEC "\
--melf" XLEN_SPEC "lriscv \
+-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
 %{mno-relax:--no-relax} \
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index f3aca9f7673..6018e7bb764 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef LINK_SPEC
 #define LINK_SPEC "\
-  -melf" XLEN_SPEC "lriscv \
+  -melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv  \
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index e74f5d3f914..fce5b896e6e 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 "lriscv" LD_EMUL_SUFFIX " \
+-melf" XLEN_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.c b/gcc/config/riscv/riscv.c
index fffd0814eee..eab14602355 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -5524,6 +5524,11 @@ riscv_asan_shadow_offset (void)
 #undef TARGET_ASAN_SHADOW_OFFSET
 #define TARGET_ASAN_SHADOW_OFFSET 

[PATCH v3 1/6] RISC-V: Support -mlittle-endian and -mbig-endian

2021-02-24 Thread Marcus Comstedt
gcc/
* config/riscv/elf.h (LINK_SPEC): Pass linker endianness flag.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.h (ASM_SPEC): Pass -mbig-endian and
-mlittle-endian.
(BYTES_BIG_ENDIAN): Handle big endian.
(WORDS_BIG_ENDIAN): Define to BYTES_BIG_ENDIAN.
* config/riscv/riscv.opt (-mbig-endian, -mlittle-endian): New
options.
* doc/invoke.texi (-mbig-endian, -mlittle-endian): Document.
---
 gcc/config/riscv/elf.h |  2 ++
 gcc/config/riscv/freebsd.h |  2 ++
 gcc/config/riscv/linux.h   |  2 ++
 gcc/config/riscv/riscv.h   |  6 --
 gcc/config/riscv/riscv.opt |  8 
 gcc/doc/invoke.texi| 12 
 6 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index d136d46e4fa..973efdaed7b 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared}"
 
 /* Link against Newlib libraries, because the ELF backend assumes Newlib.
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index a48bf9bffe4..f3aca9f7673 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -44,6 +44,8 @@ along with GCC; see the file COPYING3.  If not see
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
+  %{mbig-endian:-EB}   \
+  %{mlittle-endian:-EL}\
   %{shared:-Bshareable %{h*} %{soname*}}   \
   %{symbolic:-Bsymbolic}   \
   %{static:-Bstatic}   \
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index 9238de5bc92..e74f5d3f914 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -60,6 +60,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv" LD_EMUL_SUFFIX " \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared} \
   %{!shared: \
 %{!static: \
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index c6f8bee07ef..0b667d2e8b9 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -91,6 +91,8 @@ extern const char *riscv_default_mtune (int argc, const char 
**argv);
 %{" FPIE_OR_FPIC_SPEC ":-fpic} \
 %{march=*} \
 %{mabi=*} \
+%{mbig-endian} \
+%{mlittle-endian} \
 %(subtarget_asm_spec)" \
 ASM_MISA_SPEC
 
@@ -126,8 +128,8 @@ ASM_MISA_SPEC
 /* Target machine storage layout */
 
 #define BITS_BIG_ENDIAN 0
-#define BYTES_BIG_ENDIAN 0
-#define WORDS_BIG_ENDIAN 0
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
+#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
 
 #define MAX_BITS_PER_WORD 64
 
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 761a09d18c3..e294e223151 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -21,6 +21,14 @@
 HeaderInclude
 config/riscv/riscv-opts.h
 
+mbig-endian
+Target RejectNegative Mask(BIG_ENDIAN)
+Assume target CPU is configured as big endian.
+
+mlittle-endian
+Target RejectNegative InverseMask(BIG_ENDIAN)
+Assume target CPU is configured as little endian.
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(riscv_branch_cost)
 -mbranch-cost=NSet the cost of branches to roughly N instructions.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e8baa545eee..9279a37a832 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1169,6 +1169,7 @@ See RS/6000 and PowerPC Options.
 -mrelax  -mno-relax @gol
 -mriscv-attribute  -mmo-riscv-attribute @gol
 -malign-data=@var{type} @gol
+-mbig-endian  -mlittle-endian @gol
 +-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
 +-mstack-protector-guard-offset=@var{offset}}
 
@@ -26721,6 +26722,17 @@ types.  Supported values for @var{type} are 
@samp{xlen} which uses x register
 width as the alignment value, and @samp{natural} which uses natural alignment.
 @samp{xlen} is the default.
 
+@item -mbig-endian
+@opindex mbig-endian
+Generate big-endian code.  This is the default when GCC is configured for a
+@samp{riscv64be-*-*} or @samp{riscv32be-*-*} target.
+
+@item -mlittle-endian
+@opindex mlittle-endian
+Generate little-endian code.  This is the default when GCC is configured for a
+@samp{riscv64-*-*} or @samp{riscv32-*-*} but not a @samp{riscv64be-*-*} or
+@samp{riscv32be-*-*} target.
+
 @item -mstack-protector-guard=@var{guard}
 @itemx -mstack-protector-guard-reg=@var{reg}
 @itemx 

[PATCH v3 0/6] RISC-V big endian support

2021-02-24 Thread Marcus Comstedt
New update of the RISC-V big endian support.

Changes since v2:

* Replaced matches of (subreg ... 0) in riscv.md with calls to
  a predicate "subreg_lowpart_operator", modeled on how
  arm.md and aarch64.md works.

Testsuite result on 64-bit is now

 rv64gc/   lp64/ medlow |   12 / 6 |   39 /10 |  - |

on both big-endian and little-endian.

On 32-bit I'm seeing a lot of

  User store segfault @ 0x7f7f

in the execution tests.  Need to investigate this further.


  // Marcus





Re: [PATCH v2 0/5] RISC-V big endian support

2021-02-24 Thread Marcus Comstedt


Hi again.

I've found the reason for the shift-and test fails.

riscv.md does a match on

  (subreg:QI (and:SI ...) 0)

Unfortunately, due to the way "subreg" is defined, this needs to be

  (subreg:QI (and:SI ...) 3)

on big endian.  I can fix the failures by duplicating the rule and
making the one with "0" check !BYTES_BIG_ENDIAN and the one with "3"
check BYTES_BIG_ENDIAN.  But that's a bit heavy handed of course.
I'll try to come up with a solution using subreg_lowpart_p instead of
hardcoding "0" or "3".


  // Marcus




Re: [PATCH v2 0/5] RISC-V big endian support

2021-02-24 Thread Marcus Comstedt


Hi Kito,

Kito Cheng  writes:

> I just spend some time on those two testcase, I think this those two
> testcase could just skip in big-endinan.

Well, that sounds like a pretty big cop out.  If the software doesn't
behave like we expect it too I feel we should at least have some idea
_why_...


>> FAIL: gcc.target/riscv/shift-and-1.c scan-assembler-not andi
>> FAIL: gcc.target/riscv/shift-and-2.c scan-assembler-not andi
>
> However seems like rv32be has still has some strange fail there,
> do you mind take a look for that?

Do you mean in those two test cases specifically?  Or rv32be in
general?


  // Marcus




Re: [PATCH v2 0/5] RISC-V big endian support

2021-02-22 Thread Marcus Comstedt


Hi Kito,

Kito Cheng  writes:

> FAIL: gcc.c-torture/execute/string-opt-5.c
> FAIL: gcc.target/riscv/shift-and-1.c scan-assembler-not andi
> FAIL: gcc.target/riscv/shift-and-2.c scan-assembler-not andi

string-opt-5.c is one of the newlib issues I mentioned (handcoded
assembler for strcmp which assumed LE (it was intended to #error out
on BE, but used "BYTE_ORDER" instead of "__BYTE_ORDER__", so the check
never worked)).  I'll send the fixes later today.

The shift-and tests don't generate incorrect code or anything, but
it's still puzzling why the generated code is different from with
-mlittle-endian.


  // Marcus




[PATCH v2 5/5] RISC-V: Update shift-shift-5.c testcase for big endian

2021-02-20 Thread Marcus Comstedt
gcc/
* testsuite/gcc.target/riscv/shift-shift-5.c (sub): Change
order of struct fields depending on byteorder.
---
 gcc/testsuite/gcc.target/riscv/shift-shift-5.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c 
b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
index 5b2ae89a471..0ecab9723c9 100644
--- a/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
+++ b/gcc/testsuite/gcc.target/riscv/shift-shift-5.c
@@ -7,7 +7,11 @@ unsigned long
 sub (long l)
 {
   union u {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 struct s { int a : 19; unsigned int b : 13; int x; } s;
+#else
+struct s { int x; unsigned int b : 13; int a : 19; } s;
+#endif
 long l;
   } u;
   u.l = l;
-- 
2.26.2



[PATCH v2 4/5] RISC-V: Fix trampoline generation on big endian

2021-02-20 Thread Marcus Comstedt
gcc/
* config/riscv/riscv.c (riscv_swap_instruction): New function
to byteswap an SImode rtx containing an instruction.
(riscv_trampoline_init): Byteswap the generated instructions
when needed.
---
 gcc/config/riscv/riscv.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index eab14602355..1cd795bd19c 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -1073,6 +1073,15 @@ riscv_force_binary (machine_mode mode, enum rtx_code 
code, rtx x, rtx y)
   return riscv_emit_binary (code, gen_reg_rtx (mode), x, y);
 }
 
+static rtx
+riscv_swap_instruction (rtx inst)
+{
+  gcc_assert (GET_MODE (inst) == SImode);
+  if (BYTES_BIG_ENDIAN)
+inst = expand_unop (SImode, bswap_optab, inst, gen_reg_rtx (SImode), 1);
+  return inst;
+}
+
 /* Copy VALUE to a register and return that register.  If new pseudos
are allowed, copy it into a new register, otherwise use DEST.  */
 
@@ -4953,7 +4962,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
 gen_int_mode (lui_hi_chain_code, 
SImode));
 
   mem = adjust_address (m_tramp, SImode, 0);
-  riscv_emit_move (mem, lui_hi_chain);
+  riscv_emit_move (mem, riscv_swap_instruction (lui_hi_chain));
 
   /* Gen lui t0, hi(func).  */
   rtx hi_func = riscv_force_binary (SImode, PLUS, target_function,
@@ -4965,7 +4974,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
gen_int_mode (lui_hi_func_code, 
SImode));
 
   mem = adjust_address (m_tramp, SImode, 1 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, lui_hi_func);
+  riscv_emit_move (mem, riscv_swap_instruction (lui_hi_func));
 
   /* Gen addi t2, t2, lo(chain).  */
   rtx lo_chain = riscv_force_binary (SImode, AND, chain_value,
@@ -4980,7 +4989,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
  force_reg (SImode, GEN_INT 
(lo_chain_code)));
 
   mem = adjust_address (m_tramp, SImode, 2 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, addi_lo_chain);
+  riscv_emit_move (mem, riscv_swap_instruction (addi_lo_chain));
 
   /* Gen jr t0, lo(func).  */
   rtx lo_func = riscv_force_binary (SImode, AND, target_function,
@@ -4993,7 +5002,7 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
   force_reg (SImode, GEN_INT 
(lo_func_code)));
 
   mem = adjust_address (m_tramp, SImode, 3 * GET_MODE_SIZE (SImode));
-  riscv_emit_move (mem, jr_lo_func);
+  riscv_emit_move (mem, riscv_swap_instruction (jr_lo_func));
 }
   else
 {
@@ -5019,6 +5028,8 @@ riscv_trampoline_init (rtx m_tramp, tree fndecl, rtx 
chain_value)
   /* Copy the trampoline code.  */
   for (i = 0; i < ARRAY_SIZE (trampoline); i++)
{
+ if (BYTES_BIG_ENDIAN)
+   trampoline[i] = __builtin_bswap32(trampoline[i]);
  mem = adjust_address (m_tramp, SImode, i * GET_MODE_SIZE (SImode));
  riscv_emit_move (mem, gen_int_mode (trampoline[i], SImode));
}
-- 
2.26.2



[PATCH v2 3/5] RISC-V: Update soft-fp config for big-endian

2021-02-20 Thread Marcus Comstedt
libgcc/
* config/riscv/sfp-machine.h (__BYTE_ORDER): Set according
to __BYTE_ORDER__.
---
 libgcc/config/riscv/sfp-machine.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/libgcc/config/riscv/sfp-machine.h 
b/libgcc/config/riscv/sfp-machine.h
index db2697157ce..8adbf4b8b2e 100644
--- a/libgcc/config/riscv/sfp-machine.h
+++ b/libgcc/config/riscv/sfp-machine.h
@@ -128,7 +128,11 @@ do {   
\
 #define__LITTLE_ENDIAN 1234
 #define__BIG_ENDIAN4321
 
+#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
 #define __BYTE_ORDER __LITTLE_ENDIAN
+#endif
 
 
 /* Define ALIASNAME as a strong alias for NAME.  */
-- 
2.26.2



[PATCH v2 2/5] RISC-V: Add riscv{32,64}be with big endian as default

2021-02-20 Thread Marcus Comstedt
gcc/
* common/config/riscv/riscv-common.c
(TARGET_DEFAULT_TARGET_FLAGS): Set default endianness.
* config.gcc (riscv32be-*, riscv64be-*): Set
TARGET_BIG_ENDIAN_DEFAULT to 1.
* config/riscv/elf.h (LINK_SPEC): Change -melf* value
depending on default endianness.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.c (TARGET_DEFAULT_TARGET_FLAGS): Set
default endianness.
* config/riscv/riscv.h (DEFAULT_ENDIAN_SPEC): New macro.
---
 gcc/common/config/riscv/riscv-common.c |  5 +
 gcc/config.gcc | 15 +++
 gcc/config/riscv/elf.h |  2 +-
 gcc/config/riscv/freebsd.h |  2 +-
 gcc/config/riscv/linux.h   |  2 +-
 gcc/config/riscv/riscv.c   |  5 +
 gcc/config/riscv/riscv.h   |  6 ++
 7 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.c 
b/gcc/common/config/riscv/riscv-common.c
index 6bbe25dba89..34b74e52a2d 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -32,6 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "config/riscv/riscv-protos.h"
 #include "config/riscv/riscv-subset.h"
 
+#ifdef  TARGET_BIG_ENDIAN_DEFAULT
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
+#endif
+
 /* Type for implied ISA info.  */
 struct riscv_implied_info_t
 {
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 17fea83b2e4..ae47e430062 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2464,6 +2464,11 @@ riscv*-*-linux*)
tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2487,6 +2492,11 @@ riscv*-*-elf* | riscv*-*-rtems*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2496,6 +2506,11 @@ riscv*-*-freebsd*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index 973efdaed7b..7e65e499031 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -18,7 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #define LINK_SPEC "\
--melf" XLEN_SPEC "lriscv \
+-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
 %{mno-relax:--no-relax} \
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index f3aca9f7673..6018e7bb764 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef LINK_SPEC
 #define LINK_SPEC "\
-  -melf" XLEN_SPEC "lriscv \
+  -melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv  \
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index e74f5d3f914..fce5b896e6e 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 "lriscv" LD_EMUL_SUFFIX " \
+-melf" XLEN_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.c b/gcc/config/riscv/riscv.c
index fffd0814eee..eab14602355 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -5524,6 +5524,11 @@ riscv_asan_shadow_offset (void)
 #undef TARGET_ASAN_SHADOW_OFFSET
 #define TARGET_ASAN_SHADOW_OFFSET 

[PATCH v2 1/5] RISC-V: Support -mlittle-endian and -mbig-endian

2021-02-20 Thread Marcus Comstedt
gcc/
* config/riscv/elf.h (LINK_SPEC): Pass linker endianness flag.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.h (ASM_SPEC): Pass -mbig-endian and
-mlittle-endian.
(BYTES_BIG_ENDIAN): Handle big endian.
(WORDS_BIG_ENDIAN): Define to BYTES_BIG_ENDIAN.
* config/riscv/riscv.opt (-mbig-endian, -mlittle-endian): New
options.
* doc/invoke.texi (-mbig-endian, -mlittle-endian): Document.
---
 gcc/config/riscv/elf.h |  2 ++
 gcc/config/riscv/freebsd.h |  2 ++
 gcc/config/riscv/linux.h   |  2 ++
 gcc/config/riscv/riscv.h   |  6 --
 gcc/config/riscv/riscv.opt |  8 
 gcc/doc/invoke.texi| 12 
 6 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index d136d46e4fa..973efdaed7b 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared}"
 
 /* Link against Newlib libraries, because the ELF backend assumes Newlib.
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index a48bf9bffe4..f3aca9f7673 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -44,6 +44,8 @@ along with GCC; see the file COPYING3.  If not see
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
+  %{mbig-endian:-EB}   \
+  %{mlittle-endian:-EL}\
   %{shared:-Bshareable %{h*} %{soname*}}   \
   %{symbolic:-Bsymbolic}   \
   %{static:-Bstatic}   \
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index 9238de5bc92..e74f5d3f914 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -60,6 +60,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv" LD_EMUL_SUFFIX " \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared} \
   %{!shared: \
 %{!static: \
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index c6f8bee07ef..0b667d2e8b9 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -91,6 +91,8 @@ extern const char *riscv_default_mtune (int argc, const char 
**argv);
 %{" FPIE_OR_FPIC_SPEC ":-fpic} \
 %{march=*} \
 %{mabi=*} \
+%{mbig-endian} \
+%{mlittle-endian} \
 %(subtarget_asm_spec)" \
 ASM_MISA_SPEC
 
@@ -126,8 +128,8 @@ ASM_MISA_SPEC
 /* Target machine storage layout */
 
 #define BITS_BIG_ENDIAN 0
-#define BYTES_BIG_ENDIAN 0
-#define WORDS_BIG_ENDIAN 0
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
+#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
 
 #define MAX_BITS_PER_WORD 64
 
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 761a09d18c3..e294e223151 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -21,6 +21,14 @@
 HeaderInclude
 config/riscv/riscv-opts.h
 
+mbig-endian
+Target RejectNegative Mask(BIG_ENDIAN)
+Assume target CPU is configured as big endian.
+
+mlittle-endian
+Target RejectNegative InverseMask(BIG_ENDIAN)
+Assume target CPU is configured as little endian.
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(riscv_branch_cost)
 -mbranch-cost=NSet the cost of branches to roughly N instructions.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e8baa545eee..9279a37a832 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1169,6 +1169,7 @@ See RS/6000 and PowerPC Options.
 -mrelax  -mno-relax @gol
 -mriscv-attribute  -mmo-riscv-attribute @gol
 -malign-data=@var{type} @gol
+-mbig-endian  -mlittle-endian @gol
 +-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol
 +-mstack-protector-guard-offset=@var{offset}}
 
@@ -26721,6 +26722,17 @@ types.  Supported values for @var{type} are 
@samp{xlen} which uses x register
 width as the alignment value, and @samp{natural} which uses natural alignment.
 @samp{xlen} is the default.
 
+@item -mbig-endian
+@opindex mbig-endian
+Generate big-endian code.  This is the default when GCC is configured for a
+@samp{riscv64be-*-*} or @samp{riscv32be-*-*} target.
+
+@item -mlittle-endian
+@opindex mlittle-endian
+Generate little-endian code.  This is the default when GCC is configured for a
+@samp{riscv64-*-*} or @samp{riscv32-*-*} but not a @samp{riscv64be-*-*} or
+@samp{riscv32be-*-*} target.
+
 @item -mstack-protector-guard=@var{guard}
 @itemx -mstack-protector-guard-reg=@var{reg}
 @itemx 

[PATCH v2 0/5] RISC-V big endian support

2021-02-20 Thread Marcus Comstedt
This is an update to the patch series for big endian RISC-V support.

Changes since last version:

  * Added documentation of -mbig-endian and -mlittle-endian

  * New patch: Fix soft-fp endianness setting

  * New patch: Fix trampoline generation on big endian

  * New patch: Update the shift-shift-5.c testcase to work correctly
on big endian

With these changes, and two fixes to newlib (setting correct floating
point byteorder, and an update to the handcoded assembler for strcmp),
I'm now down to

   = Summary of gcc testsuite =
| # of unexpected case / # of unique unexpected case
|  gcc |  g++ | gfortran |
 rv64gc/   lp64/ medlow |   14 / 8 |   39 /10 |  - |

and of these only two failures do not also occur for little endian:

FAIL: gcc.target/riscv/shift-and-1.c scan-assembler-not andi
FAIL: gcc.target/riscv/shift-and-2.c scan-assembler-not andi

I'm quite puzzled why these two testcases give different results with
-mbig-endian compared to with -mlittle-endian though, since they only
deal with register-to-register operations so the memory model should be
completely irrelevant...


  // Marcus





Re: [PATCH 0/2] RISC-V big endian support

2021-02-20 Thread Marcus Comstedt


Hi Kito,

Kito Cheng  writes:

> I tried to run with gcc testsuite on spike + pk, seems got a bunch
> extra fail cases,
> could you take a look for that?

Looking at it now.

I'm getting a large number of failures in floating point tests, which
turn out to be due to a newlib problem;
newlib/libc/include/machine/ieeefp.h uncoditionally defines
__IEEE_LITTLE_ENDIAN on riscv.

Should I make a PR against riscv-newlib on GitHub, or would you prefer
some other process for dealing with newlib fixes related to these
patches?


  // Marcus




Re: [PATCH 2/2] RISC-V: Add riscv{32, 64}be with big endian as default

2021-02-07 Thread Marcus Comstedt


Hi again.

Sorry, but I just realized that the "-melf" part isn't the same in all
of {elf,linux,freebsd}.h; linux.h has a LD_EMUL_SUFFIX which the other
two are lacking.  Which means that the only truly common part is

  %{mbig-endian:-EB} \
  %{mlittle-endian:-EL} \

So is it worth a define to change two lines duplicated in three files
into one line duplicated in three files?  The define would not even
cover all of the endianness stuff.


  // Marcus




Re: [PATCH 2/2] RISC-V: Add riscv{32, 64}be with big endian as default

2021-02-03 Thread Marcus Comstedt


Kito Cheng  writes:

> Yeah, but I'd like to include following 2 lines too:
>
> %{mbig-endian:-EB} \
> %{mlittle-endian:-EL} \
>
> I saw it's just the same among 3 files.

Ah, I see.  Then it becomes a little more of a mixed grab bag.

I see that SuperH has a spec "subtarget_link_spec" which includes
-EL/-EB as well as other stuff, and then includes that into a
SH_LINK_SPEC, which also adds the link emulation as well as
e.g. mrelax.

Maybe we could take a page from their playbook but skip the extra
complexity, and just use "RISCV_LINK_SPEC" for the common stuff?

What about "%{mno-relax:--no-relax}"?  It's the same in linux.h and
elf.h, but missing from freebsd.h.  Intentional, or is this another
candidate for putting in the common define?


  // Marcus




Re: [PATCH 2/2] RISC-V: Add riscv{32, 64}be with big endian as default

2021-01-29 Thread Marcus Comstedt


Kito Cheng  writes:

>> diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
>> index 973efdaed7b..7e65e499031 100644
>> --- a/gcc/config/riscv/elf.h
>> +++ b/gcc/config/riscv/elf.h
>> @@ -18,7 +18,7 @@ along with GCC; see the file COPYING3.  If not see
>>  .  */
>>
>>  #define LINK_SPEC "\
>> --melf" XLEN_SPEC "lriscv \
>> +-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
>
> Could you extract the endian related LINK_SPEC change to
> ENDIAN_LINK_SPEC to riscv.h, so that we can prevent
> duplicate this several times.

You mean a define which expands to

  "-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv"

?  Sure, but I don't think ENDIAN_LINK_SPEC would be a good name for
it since it defines the word size as well as the endianness, and also
ELF in general.

Maybe ELF_LINK_SPEC?  The word size and endianness are also ELF
properties (as encoded in EI_CLASS and EI_DATA).


  // Marcus




Re: [PATCH 1/2] RISC-V: Support -mlittle-endian and -mbig-endian

2021-01-29 Thread Marcus Comstedt


Kito Cheng  writes:

> Could you document -mbig-endian and -mlittle-endian in gcc/doc/invoke.texi?


Sure, I'll add that.


  // Marcus




Re: [PATCH 0/2] RISC-V big endian support

2021-01-29 Thread Marcus Comstedt


Hi Kito,

Kito Cheng  writes:

> You can add a check in configure.ac and config.in to detect whether
> binutils is supported or not.
> here is example, search HAVE_AS_MISA_SPEC in this patch:
> https://github.com/gcc-mirror/gcc/commit/4b81528241ca682025d92558ff6aeec91dafdca8

Ok, but I specifically _don't_ want to require a newer binutils for
the little endian triplets (unless there is also some other RISC-V
change meaning that the newer binutils is needed anyway, in which case
this point becomes moot).

I could check the binutils version in the case of big endian triplets
only, but since older binutils can't be built for those triplets
anyway (due to config.sub), I don't think it would do much.

I could also disable the -mlittle-endian and -mbig-endian options if
the binutils is too old, but it's questionable if getting a "I don't
understand -mbig-endian" from gcc is more useful than getting it from
gas.  And it would be more work for the user to fix it since then they
would have to also rebuild gcc after upgrading binutils.


  // Marcus




[PATCH 2/2] RISC-V: Add riscv{32,64}be with big endian as default

2021-01-25 Thread Marcus Comstedt
gcc/
* common/config/riscv/riscv-common.c
(TARGET_DEFAULT_TARGET_FLAGS): Set default endianness.
* config.gcc (riscv32be-*, riscv64be-*): Set
TARGET_BIG_ENDIAN_DEFAULT to 1.
* config/riscv/elf.h (LINK_SPEC): Change -melf* value
depending on default endianness.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.c (TARGET_DEFAULT_TARGET_FLAGS): Set
default endianness.
* config/riscv/riscv.h (DEFAULT_ENDIAN_SPEC): New macro.
---
 gcc/common/config/riscv/riscv-common.c |  5 +
 gcc/config.gcc | 15 +++
 gcc/config/riscv/elf.h |  2 +-
 gcc/config/riscv/freebsd.h |  2 +-
 gcc/config/riscv/linux.h   |  2 +-
 gcc/config/riscv/riscv.c   |  5 +
 gcc/config/riscv/riscv.h   |  6 ++
 7 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/gcc/common/config/riscv/riscv-common.c 
b/gcc/common/config/riscv/riscv-common.c
index b3f5c07c819..88c368f6c72 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -32,6 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "config/riscv/riscv-protos.h"
 #include "config/riscv/riscv-subset.h"
 
+#ifdef  TARGET_BIG_ENDIAN_DEFAULT
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (MASK_BIG_ENDIAN)
+#endif
+
 /* Type for implied ISA info.  */
 struct riscv_implied_info_t
 {
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 17fea83b2e4..ae47e430062 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2464,6 +2464,11 @@ riscv*-*-linux*)
tmake_file="${tmake_file} riscv/t-riscv riscv/t-linux"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2487,6 +2492,11 @@ riscv*-*-elf* | riscv*-*-rtems*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
@@ -2496,6 +2506,11 @@ riscv*-*-freebsd*)
tmake_file="${tmake_file} riscv/t-riscv"
gnu_ld=yes
gas=yes
+   case $target in
+   riscv32be-*|riscv64be-*)
+   tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
+   ;;
+   esac
# Force .init_array support.  The configure script cannot always
# automatically detect that GAS supports it, yet we require it.
gcc_cv_initfini_array=yes
diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index 973efdaed7b..7e65e499031 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -18,7 +18,7 @@ along with GCC; see the file COPYING3.  If not see
 .  */
 
 #define LINK_SPEC "\
--melf" XLEN_SPEC "lriscv \
+-melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv \
 %{mno-relax:--no-relax} \
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index f3aca9f7673..6018e7bb764 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #undef LINK_SPEC
 #define LINK_SPEC "\
-  -melf" XLEN_SPEC "lriscv \
+  -melf" XLEN_SPEC DEFAULT_ENDIAN_SPEC "riscv  \
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index e74f5d3f914..fce5b896e6e 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 "lriscv" LD_EMUL_SUFFIX " \
+-melf" XLEN_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.c b/gcc/config/riscv/riscv.c
index ff41795a031..06f4739db79 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -5499,6 +5499,11 @@ riscv_asan_shadow_offset (void)
 #undef TARGET_ASAN_SHADOW_OFFSET
 #define TARGET_ASAN_SHADOW_OFFSET 

[PATCH 1/2] RISC-V: Support -mlittle-endian and -mbig-endian

2021-01-25 Thread Marcus Comstedt
gcc/
* config/riscv/elf.h (LINK_SPEC): Pass linker endianness flag.
* config/riscv/freebsd.h (LINK_SPEC): Likewise.
* config/riscv/linux.h (LINK_SPEC): Likewise.
* config/riscv/riscv.h (ASM_SPEC): Pass -mbig-endian and
-mlittle-endian.
(BYTES_BIG_ENDIAN): Handle big endian.
(WORDS_BIG_ENDIAN): Define to BYTES_BIG_ENDIAN.
* config/riscv/riscv.opt (-mbig-endian, -mlittle-endian): New
options.
---
 gcc/config/riscv/elf.h | 2 ++
 gcc/config/riscv/freebsd.h | 2 ++
 gcc/config/riscv/linux.h   | 2 ++
 gcc/config/riscv/riscv.h   | 6 --
 gcc/config/riscv/riscv.opt | 8 
 5 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/gcc/config/riscv/elf.h b/gcc/config/riscv/elf.h
index d136d46e4fa..973efdaed7b 100644
--- a/gcc/config/riscv/elf.h
+++ b/gcc/config/riscv/elf.h
@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared}"
 
 /* Link against Newlib libraries, because the ELF backend assumes Newlib.
diff --git a/gcc/config/riscv/freebsd.h b/gcc/config/riscv/freebsd.h
index a48bf9bffe4..f3aca9f7673 100644
--- a/gcc/config/riscv/freebsd.h
+++ b/gcc/config/riscv/freebsd.h
@@ -44,6 +44,8 @@ along with GCC; see the file COPYING3.  If not see
   %{p:%nconsider using `-pg' instead of `-p' with gprof (1)}   \
   %{v:-V}  \
   %{assert*} %{R*} %{rpath*} %{defsym*}\
+  %{mbig-endian:-EB}   \
+  %{mlittle-endian:-EL}\
   %{shared:-Bshareable %{h*} %{soname*}}   \
   %{symbolic:-Bsymbolic}   \
   %{static:-Bstatic}   \
diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h
index 9238de5bc92..e74f5d3f914 100644
--- a/gcc/config/riscv/linux.h
+++ b/gcc/config/riscv/linux.h
@@ -60,6 +60,8 @@ along with GCC; see the file COPYING3.  If not see
 #define LINK_SPEC "\
 -melf" XLEN_SPEC "lriscv" LD_EMUL_SUFFIX " \
 %{mno-relax:--no-relax} \
+%{mbig-endian:-EB} \
+%{mlittle-endian:-EL} \
 %{shared} \
   %{!shared: \
 %{!static: \
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index c6f8bee07ef..0b667d2e8b9 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -91,6 +91,8 @@ extern const char *riscv_default_mtune (int argc, const char 
**argv);
 %{" FPIE_OR_FPIC_SPEC ":-fpic} \
 %{march=*} \
 %{mabi=*} \
+%{mbig-endian} \
+%{mlittle-endian} \
 %(subtarget_asm_spec)" \
 ASM_MISA_SPEC
 
@@ -126,8 +128,8 @@ ASM_MISA_SPEC
 /* Target machine storage layout */
 
 #define BITS_BIG_ENDIAN 0
-#define BYTES_BIG_ENDIAN 0
-#define WORDS_BIG_ENDIAN 0
+#define BYTES_BIG_ENDIAN (TARGET_BIG_ENDIAN != 0)
+#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN)
 
 #define MAX_BITS_PER_WORD 64
 
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 761a09d18c3..e294e223151 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -21,6 +21,14 @@
 HeaderInclude
 config/riscv/riscv-opts.h
 
+mbig-endian
+Target RejectNegative Mask(BIG_ENDIAN)
+Assume target CPU is configured as big endian.
+
+mlittle-endian
+Target RejectNegative InverseMask(BIG_ENDIAN)
+Assume target CPU is configured as little endian.
+
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(riscv_branch_cost)
 -mbranch-cost=NSet the cost of branches to roughly N instructions.
-- 
2.26.2



[PATCH 0/2] RISC-V big endian support

2021-01-25 Thread Marcus Comstedt
Greetings.

Big endian support for RISC-V was added in binutils 2.36, released
yesterday.  This patch set adds support to gcc for exploting this mode.

Please note that in addition to these patches, an pull of config.sub
from upstreams is needed.

In adding the big endian support, I had the following goals:

* Apply default endianness based on triplet

* Allow endianness override with -mbig-endian / -mlittle-endian

* Retain compatibility with older binutils for use cases which do not
  explicitly invoke new functionality (i.e. specify new command line
  options or target a new triplet)

Based on these goals, this is what I did _not_ do:

* Implicitly pass default endianness as -mbig-endian / -mlittle-endian
  to gas, since older binutils targeting little endian will not understand
  -mlittle-endian.  Instead assume gas has the same default as gcc.
  If -mbig-endian or -mlittle-endian is explicitly given, it is passed
  on to gas since this use is under the discretion of the user.
  (This means that DRIVER_SELF_SPECS can not be used to set the default.) 

* Configure multilib for big/little endian, since that would require
  newest binutils when building for a little endian target, due to the
  requirement to build libgcc et al as big endian.

For ld, I think it would have been ok to pass -EL to older binutils,
but for symmetry reasons I keep the ld commandline identical to before
when default is little endian, and change the '-melf64lriscv' into
'-melf64briscv' when the default is big endian.  This has the desired
effect of informing ld what the default endianness is, and still
allows it to be overridden with -EB and -EL (translated from
-mbig-endian and -mlittle-endian).


  // Marcus


 gcc/common/config/riscv/riscv-common.c |  5 +
 gcc/config.gcc | 15 +++
 gcc/config/riscv/elf.h |  4 +++-
 gcc/config/riscv/freebsd.h |  4 +++-
 gcc/config/riscv/linux.h   |  4 +++-
 gcc/config/riscv/riscv.c   |  5 +
 gcc/config/riscv/riscv.h   | 12 ++--
 gcc/config/riscv/riscv.opt |  8 
 8 files changed, 52 insertions(+), 5 deletions(-)