Skip to content
51 changes: 51 additions & 0 deletions arch/inst/I/fence.tso.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: fence.tso
long_name: Memory ordering fence, total store ordering
description: |
Orders memory operations.

`fence.tso` orders all load operations
in its predecessor set before all memory operations in its successor set, and all store operations
in its predecessor set before all store operations in its successor set. This leaves non-AMO store
operations in the 'fence.tso's predecessor set unordered with non-AMO loads in its successor set.

The `rs1` and `rd` fields are unused and ignored.

In modes other than M-mode, `fence.tso` is further affected by `menvcfg.FIOM`,
`senvcfg.FIOM`<% if ext?(:H) %>, and/or `henvcfg.FIOM`<% end %>.

definedBy: I
assembly: ""
encoding:
match: 1000-------------000-----0001111
variables:
- name: pred
location: 27-24
- name: succ
location: 23-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
fence_tso();

sail(): |
{
match (pred, succ) {
(_ : bits(2) @ 0b11, _ : bits(2) @ 0b11) => sail_barrier(Barrier_RISCV_tso),
(_ : bits(2) @ 0b00, _ : bits(2) @ 0b00) => (),

_ => { print("FIXME: unsupported fence");
() }
};
RETIRE_SUCCESS
}
21 changes: 4 additions & 17 deletions arch/inst/I/fence.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,8 @@ description: |
definedBy: I
assembly: "TODO"
encoding:
match: -----------------000-----0001111
match: 0000-------------000-----0001111
variables:
- name: fm
location: 31-28
- name: pred
location: 27-24
- name: succ
Expand All @@ -141,17 +139,10 @@ access:
vs: always
vu: always
operation(): |
Boolean is_fence_tso;
Boolean is_pause;

if (fm == 1) {
if (pred == 0x3 && succ == 0x3) {
# this is a fence.tso instruction
is_fence_tso = true;
}
}
if (implemented?(ExtensionName::Zihintpause)) {
if ((pred == 1) && (succ == 0) && (fm == 0) && (rd == 0) && (rs1 == 0)) {
if ((pred == 1) && (succ == 0) && (rd == 0) && (rs1 == 0)) {
# this is a PAUSE instruction
is_pause = true;
}
Expand All @@ -167,9 +158,7 @@ operation(): |
Boolean succ_r = succ[1] == 1;
Boolean succ_w = succ[0] == 1;

if (is_fence_tso) {
fence_tso();
} else if (is_pause) {
if (is_pause) {
pause();
} else {

Expand Down Expand Up @@ -203,9 +192,7 @@ operation(): |
);
}
pseudoinstructions:
- when: (pred == 0x3) && (succ == 0x3) && (fm == 1)
to: fence.tso
- when: (pred == 1) && (succ == 0) && (fm == 0) && (rd == 0) && (rs1 == 0)
- when: (pred == 1) && (succ == 0) && (rd == 0) && (rs1 == 0)
to: pause

sail(): |
Expand Down
Loading