Skip to content

Commit

Permalink
RISC-V: Add Ztso atomic mappings
Browse files Browse the repository at this point in the history
The RISC-V Ztso extension currently has no effect on generated code.
With the additional ordering constraints guarenteed by Ztso, we can emit
more optimized atomic mappings than the RVWMO mappings.

This PR implements the Ztso psABI mappings[1].

[1] riscv-non-isa/riscv-elf-psabi-doc#391

2023-08-08 Patrick O'Neill <[email protected]>

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc: Add Ztso and mark Ztso as
	dependent on 'a' extension.
	* config/riscv/riscv-opts.h (MASK_ZTSO): New mask.
	(TARGET_ZTSO): New target.
	* config/riscv/riscv.cc (riscv_memmodel_needs_amo_acquire): Add
	Ztso case.
	(riscv_memmodel_needs_amo_release): Add Ztso case.
	(riscv_print_operand): Add Ztso case for LR/SC annotations.
	* config/riscv/riscv.md: Import sync-rvwmo.md and sync-ztso.md.
	* config/riscv/riscv.opt: Add Ztso target variable.
	* config/riscv/sync.md (mem_thread_fence_1): Expand to RVWMO or
	Ztso specific insn.
	(atomic_load<mode>): Expand to RVWMO or Ztso specific insn.
	(atomic_store<mode>): Expand to RVWMO or Ztso specific insn.
	* config/riscv/sync-rvwmo.md: New file. Seperate out RVWMO
	specific load/store/fence mappings.
	* config/riscv/sync-ztso.md: New file. Seperate out Ztso
	specific load/store/fence mappings.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/amo-table-ztso-amo-add-1.c: New test.
	* gcc.target/riscv/amo-table-ztso-amo-add-2.c: New test.
	* gcc.target/riscv/amo-table-ztso-amo-add-3.c: New test.
	* gcc.target/riscv/amo-table-ztso-amo-add-4.c: New test.
	* gcc.target/riscv/amo-table-ztso-amo-add-5.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-1.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-2.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-3.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-4.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-5.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-6.c: New test.
	* gcc.target/riscv/amo-table-ztso-compare-exchange-7.c: New test.
	* gcc.target/riscv/amo-table-ztso-fence-1.c: New test.
	* gcc.target/riscv/amo-table-ztso-fence-2.c: New test.
	* gcc.target/riscv/amo-table-ztso-fence-3.c: New test.
	* gcc.target/riscv/amo-table-ztso-fence-4.c: New test.
	* gcc.target/riscv/amo-table-ztso-fence-5.c: New test.
	* gcc.target/riscv/amo-table-ztso-load-1.c: New test.
	* gcc.target/riscv/amo-table-ztso-load-2.c: New test.
	* gcc.target/riscv/amo-table-ztso-load-3.c: New test.
	* gcc.target/riscv/amo-table-ztso-store-1.c: New test.
	* gcc.target/riscv/amo-table-ztso-store-2.c: New test.
	* gcc.target/riscv/amo-table-ztso-store-3.c: New test.
	* gcc.target/riscv/amo-table-ztso-subword-amo-add-1.c: New test.
	* gcc.target/riscv/amo-table-ztso-subword-amo-add-2.c: New test.
	* gcc.target/riscv/amo-table-ztso-subword-amo-add-3.c: New test.
	* gcc.target/riscv/amo-table-ztso-subword-amo-add-4.c: New test.
	* gcc.target/riscv/amo-table-ztso-subword-amo-add-5.c: New test.

Signed-off-by: Patrick O'Neill <[email protected]>
  • Loading branch information
patrick-rivos authored and Liaoshihua committed Mar 15, 2024
1 parent 0e88072 commit 1b51834
Show file tree
Hide file tree
Showing 36 changed files with 612 additions and 74 deletions.
6 changes: 6 additions & 0 deletions gcc/common/config/riscv/riscv-common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ static const riscv_implied_info_t riscv_implied_info[] =
{"zks", "zksed"},
{"zks", "zksh"},

{"ztso", "a"},

{"v", "zvl128b"},
{"v", "zve64d"},

Expand Down Expand Up @@ -218,6 +220,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
{"zkn", ISA_SPEC_CLASS_NONE, 1, 0},
{"zks", ISA_SPEC_CLASS_NONE, 1, 0},

{"ztso", ISA_SPEC_CLASS_NONE, 1, 0},

{"zve32x", ISA_SPEC_CLASS_NONE, 1, 0},
{"zve32f", ISA_SPEC_CLASS_NONE, 1, 0},
{"zve64x", ISA_SPEC_CLASS_NONE, 1, 0},
Expand Down Expand Up @@ -1406,6 +1410,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
{"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL},
{"svnapot", &gcc_options::x_riscv_sv_subext, MASK_SVNAPOT},

{"ztso", &gcc_options::x_riscv_ztso_subext, MASK_ZTSO},

{"xtheadba", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
{"xtheadbb", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
{"xtheadbs", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBS},
Expand Down
4 changes: 4 additions & 0 deletions gcc/config/riscv/riscv-opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ enum riscv_entity
#define TARGET_ZKSH ((riscv_zk_subext & MASK_ZKSH) != 0)
#define TARGET_ZKT ((riscv_zk_subext & MASK_ZKT) != 0)

#define MASK_ZTSO (1 << 0)

#define TARGET_ZTSO ((riscv_ztso_subext & MASK_ZTSO) != 0)

#define MASK_VECTOR_ELEN_32 (1 << 0)
#define MASK_VECTOR_ELEN_64 (1 << 1)
#define MASK_VECTOR_ELEN_FP_32 (1 << 2)
Expand Down
20 changes: 18 additions & 2 deletions gcc/config/riscv/riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4808,6 +4808,10 @@ riscv_union_memmodels (enum memmodel model1, enum memmodel model2)
static bool
riscv_memmodel_needs_amo_acquire (enum memmodel model)
{
/* ZTSO amo mappings require no annotations. */
if (TARGET_ZTSO)
return false;

switch (model)
{
case MEMMODEL_ACQ_REL:
Expand All @@ -4831,6 +4835,10 @@ riscv_memmodel_needs_amo_acquire (enum memmodel model)
static bool
riscv_memmodel_needs_amo_release (enum memmodel model)
{
/* ZTSO amo mappings require no annotations. */
if (TARGET_ZTSO)
return false;

switch (model)
{
case MEMMODEL_ACQ_REL:
Expand Down Expand Up @@ -5050,7 +5058,10 @@ riscv_print_operand (FILE *file, rtx op, int letter)

case 'I': {
const enum memmodel model = memmodel_base (INTVAL (op));
if (model == MEMMODEL_SEQ_CST)
if (TARGET_ZTSO && model != MEMMODEL_SEQ_CST)
/* LR ops only have an annotation for SEQ_CST in the Ztso mapping. */
break;
else if (model == MEMMODEL_SEQ_CST)
fputs (".aqrl", file);
else if (riscv_memmodel_needs_amo_acquire (model))
fputs (".aq", file);
Expand All @@ -5059,7 +5070,12 @@ riscv_print_operand (FILE *file, rtx op, int letter)

case 'J': {
const enum memmodel model = memmodel_base (INTVAL (op));
if (riscv_memmodel_needs_amo_release (model))
if (TARGET_ZTSO && model == MEMMODEL_SEQ_CST)
/* SC ops only have an annotation for SEQ_CST in the Ztso mapping. */
fputs (".rl", file);
else if (TARGET_ZTSO)
break;
else if (riscv_memmodel_needs_amo_release (model))
fputs (".rl", file);
break;
}
Expand Down
2 changes: 2 additions & 0 deletions gcc/config/riscv/riscv.md
Original file line number Diff line number Diff line change
Expand Up @@ -3321,6 +3321,8 @@
(include "bitmanip.md")
(include "crypto.md")
(include "sync.md")
(include "sync-rvwmo.md")
(include "sync-ztso.md")
(include "peephole.md")
(include "pic.md")
(include "generic.md")
Expand Down
3 changes: 3 additions & 0 deletions gcc/config/riscv/riscv.opt
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ int riscv_zm_subext
TargetVariable
int riscv_sv_subext

TargetVariable
int riscv_ztso_subext

TargetVariable
int riscv_xthead_subext

Expand Down
96 changes: 96 additions & 0 deletions gcc/config/riscv/sync-rvwmo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
;; Machine description for RISC-V atomic operations.
;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
;; Contributed by Andrew Waterman ([email protected]).
;; Based on MIPS target for GNU compiler.

;; This file is part of GCC.

;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.

;; Memory barrier.

(define_insn "mem_thread_fence_rvwmo"
[(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
(match_operand:SI 1 "const_int_operand" "")] ;; model
"!TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[1]);
model = memmodel_base (model);

if (model == MEMMODEL_SEQ_CST)
return "fence\trw,rw";
else if (model == MEMMODEL_ACQ_REL)
return "fence.tso";
else if (model == MEMMODEL_ACQUIRE)
return "fence\tr,rw";
else if (model == MEMMODEL_RELEASE)
return "fence\trw,w";
else
gcc_unreachable ();
}
[(set (attr "length") (const_int 4))])

;; Atomic memory operations.

(define_insn "atomic_load_rvwmo<mode>"
[(set (match_operand:GPR 0 "register_operand" "=r")
(unspec_volatile:GPR
[(match_operand:GPR 1 "memory_operand" "A")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_LOAD))]
"TARGET_ATOMIC && !TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);

if (model == MEMMODEL_SEQ_CST)
return "fence\trw,rw\;"
"l<amo>\t%0,%1\;"
"fence\tr,rw";
if (model == MEMMODEL_ACQUIRE)
return "l<amo>\t%0,%1\;"
"fence\tr,rw";
else
return "l<amo>\t%0,%1";
}
[(set_attr "type" "atomic")
(set (attr "length") (const_int 12))])

;; Implement atomic stores with conservative fences.
;; This allows us to be compatible with the ISA manual Table A.6 and Table A.7.
(define_insn "atomic_store_rvwmo<mode>"
[(set (match_operand:GPR 0 "memory_operand" "=A")
(unspec_volatile:GPR
[(match_operand:GPR 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_STORE))]
"TARGET_ATOMIC && !TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);

if (model == MEMMODEL_SEQ_CST)
return "fence\trw,w\;"
"s<amo>\t%z1,%0\;"
"fence\trw,rw";
if (model == MEMMODEL_RELEASE)
return "fence\trw,w\;"
"s<amo>\t%z1,%0";
else
return "s<amo>\t%z1,%0";
}
[(set_attr "type" "atomic")
(set (attr "length") (const_int 12))])
80 changes: 80 additions & 0 deletions gcc/config/riscv/sync-ztso.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
;; Machine description for RISC-V atomic operations.
;; Copyright (C) 2011-2023 Free Software Foundation, Inc.
;; Contributed by Andrew Waterman ([email protected]).
;; Based on MIPS target for GNU compiler.

;; This file is part of GCC.

;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.

;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.

;; Memory barriers.

(define_insn "mem_thread_fence_ztso"
[(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
(match_operand:SI 1 "const_int_operand" "")] ;; model
"TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[1]);
model = memmodel_base (model);

if (model == MEMMODEL_SEQ_CST)
return "fence\trw,rw";
else
gcc_unreachable ();
}
[(set (attr "length") (const_int 4))])

;; Atomic memory operations.

(define_insn "atomic_load_ztso<mode>"
[(set (match_operand:GPR 0 "register_operand" "=r")
(unspec_volatile:GPR
[(match_operand:GPR 1 "memory_operand" "A")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_LOAD))]
"TARGET_ATOMIC && TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);

if (model == MEMMODEL_SEQ_CST)
return "fence\trw,rw\;"
"l<amo>\t%0,%1\;";
else
return "l<amo>\t%0,%1";
}
[(set_attr "type" "atomic")
(set (attr "length") (const_int 12))])

(define_insn "atomic_store_ztso<mode>"
[(set (match_operand:GPR 0 "memory_operand" "=A")
(unspec_volatile:GPR
[(match_operand:GPR 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_STORE))]
"TARGET_ATOMIC && TARGET_ZTSO"
{
enum memmodel model = (enum memmodel) INTVAL (operands[2]);
model = memmodel_base (model);

if (model == MEMMODEL_SEQ_CST)
return "s<amo>\t%z1,%0\;"
"fence\trw,rw";
else
return "s<amo>\t%z1,%0";
}
[(set_attr "type" "atomic")
(set (attr "length") (const_int 8))])
Loading

0 comments on commit 1b51834

Please sign in to comment.