diff --git a/arch/inst/I/fence.tso.yaml b/arch/inst/I/fence.tso.yaml new file mode 100644 index 0000000000..a5dd8a8a59 --- /dev/null +++ b/arch/inst/I/fence.tso.yaml @@ -0,0 +1,47 @@ +# 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: 100000110011-----000-----0001111 + variables: + - 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 + } diff --git a/arch/inst/I/fence.yaml b/arch/inst/I/fence.yaml index 7d77592fcc..ec761d8829 100644 --- a/arch/inst/I/fence.yaml +++ b/arch/inst/I/fence.yaml @@ -141,17 +141,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) && (xd == 0) && (xs1 == 0)) { + if ((pred == 1) && (succ == 0) && (xd == 0) && (xs1 == 0)) { # this is a PAUSE instruction is_pause = true; } @@ -167,9 +160,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 { @@ -202,10 +193,10 @@ operation(): | succ_i, succ_o, succ_r, succ_w ); } +hints: + - { $ref: inst/I/fence.tso.yaml# } pseudoinstructions: - - when: (pred == 0x3) && (succ == 0x3) && (fm == 1) - to: fence.tso - - when: (pred == 1) && (succ == 0) && (fm == 0) && (xd == 0) && (xs1 == 0) + - when: (pred == 1) && (succ == 0) && (xd == 0) && (xs1 == 0) to: pause # SPDX-SnippetBegin