Skip to content
50 changes: 40 additions & 10 deletions spec/schemas/inst_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -337,17 +337,47 @@
"hints": {
"type": "array",
"items": {
"type": "object",
"properties": {
"$ref": {
"type": "string",
"format": "uri-reference",
"pattern": "^inst/.+\\.yaml#.*$",
"description": "Ref to an instruction that is using a HINT codepoint(s) of this instruction"
"oneOf": [
{
"type": "object",
"properties": {
"$ref": {
"type": "string",
"format": "uri-reference",
"pattern": "^inst/.+\\.yaml#.*$",
"description": "Ref to an instruction that is using a HINT codepoint(s) of this instruction"
}
},
"required": ["$ref"],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"when": {
"type": "string",
"description": "Condition under which the following refs apply"
},
"refs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"$ref": {
"type": "string",
"format": "uri-reference",
"pattern": "^inst/.+\\.yaml#.*$"
}
},
"required": ["$ref"],
"additionalProperties": false
}
}
},
"required": ["when", "refs"],
"additionalProperties": false
}
},
"required": ["$ref"],
"additionalProperties": false
]
},
"description": "List of HINTs that use this instruction's codepoints"
},
Expand Down
7 changes: 7 additions & 0 deletions spec/std/isa/inst/Zcmop/c.mop.n.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ access:
vs: always
vu: always
data_independent_timing: false
hints:
- when: (n == 0)
refs:
- { $ref: inst/Zicfiss/c.sspush.yaml# }
- when: (n == 2)
refs:
- { $ref: inst/Zicfiss/c.sspopchk.yaml# }
pseudoinstructions:
- when: (n == 0)
to: c.mop.1
Expand Down
45 changes: 45 additions & 0 deletions spec/std/isa/inst/Zicfiss/c.sspopchk.x5.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../../../schemas/inst_schema.json

$schema: inst_schema.json#
kind: instruction
name: c.sspopchk.x5
long_name: Pop from the Shadow Stack, 16 bit version of sspopchk
description: |
The c.sspopchk x5 expands to sspopchk x5, which is defined for an XLEN wide read from
the current top of the shadow stack followed by an increment of the ssp by XLEN/8.
definedBy: Zicfiss
assembly: c.sspopchk_x5
encoding:
match: "0110001010000001"
variables: []
access:
s: always
u: always
vs: always
vu: always
data_independent_timing: false
operation(): |
Bits<12> ssp_addr = 0x011;
Csr csr_handle = direct_csr_lookup(ssp_addr);

if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1'b1) || (CSR[henvcfg].SSE == 1'b1) || (CSR[senvcfg].SSE == 1'b1)) {
Bits<XLEN> ssp = csr_sw_read(csr_handle);
XReg temp = read_memory<XLEN>(ssp, $encoding);
if (temp != X[5]) {
raise(ExceptionCode::SoftwareCheck, mode(), $encoding);
}
csr_sw_write(csr_handle, (ssp + (XLEN/8)));
}
43 changes: 43 additions & 0 deletions spec/std/isa/inst/Zicfiss/c.sspush.x1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
# SPDX-License-Identifier: BSD-3-Clause-Clear

# yaml-language-server: $schema=../../../../schemas/inst_schema.json

$schema: inst_schema.json#
kind: instruction
name: c.sspush.x1
long_name: Push to the Shadow Stack from register x1, 16 bit version of sspush
description: |
The c.sspush x1 expands to sspush x1, which is defined for decrement of the ssp by XLEN/8
followed by a store of the value in the link register x1 to memory at the new top of the
shadow stack.
definedBy: Zicfiss
assembly: c.sspush_x1
encoding:
match: "0110000010000001"
variables: []
access:
s: always
u: always
vs: always
vu: always
data_independent_timing: false
operation(): |
Bits<12> ssp_addr = 0x011;
Csr csr_handle = direct_csr_lookup(ssp_addr);

if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1'b1) || (CSR[henvcfg].SSE == 1'b1) || (CSR[senvcfg].SSE == 1'b1)) {
Bits<XLEN> ssp = csr_sw_read(csr_handle) - (XLEN/8);
write_memory<XLEN>(ssp, X[1], $encoding);
csr_sw_write(csr_handle, ssp);
}
21 changes: 19 additions & 2 deletions spec/std/isa/inst/Zicfiss/ssamoswap.d.yaml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you add:

base: 64

to this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I've added this in ssamoswap.d.yaml file. One more question, am I supposed to add new files for C.SSPOPCHK and C.SSPUSH under the Zicfiss extension?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are present as sspopchk.x1.yaml and similar, although they is not really correct. I have PR #872 that needs attention which fixes these, but I haven't finished getting it to pass CI yet. (And haven't had a chance to do so recently.) You can proceed as you already have.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that PR, I can see that you merged sspopchk.x1.yaml & sspopchk.x5.yaml into single file sspopchk.yaml and sspush.x1.yaml & sspush.x5.yaml into file sspush.yaml, but can't see 16 bit version of sspush and sspopchk. Do we need to create separate files for that or I'm missing something?

You can proceed as you already have.
You mean I should pick the changes from there, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I conflated the two. Yes, we do need C.SSPOPCHK and C.SSPUSH. Note that they're a little weird because their encoding overrides some C.MOP encodings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll give it some time to understand and then will try to write those files as well.

Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
$schema: inst_schema.json#
kind: instruction
name: ssamoswap.d
long_name: No synopsis available
long_name: Atomic Swap Doubleword from a Shadow Stack Location
description: |
No description available.
The `ssamoswap.w` atomically loads a 64-bit data value from address of a shadow
stack location in xs1, puts the loaded value into register xd, and stores the
64-bit value held in xs2 to the original address in xs1.
definedBy: Zicfiss
assembly: xd, xs2, xs1
base: 64
encoding:
match: 01001------------011-----0101111
variables:
Expand All @@ -31,3 +34,17 @@ access:
vu: always
data_independent_timing: false
operation(): |
if (!implemented?(ExtensionName::S)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1'b1) || (CSR[henvcfg].SSE == 1'b1) || (CSR[senvcfg].SSE == 1'b1)) {
XReg addr_in_ssp = X[xs1];
X[xd] = amo<64>(addr_in_ssp, X[xs2], AmoOperation::Swap, aq, rl, $encoding);
}
20 changes: 18 additions & 2 deletions spec/std/isa/inst/Zicfiss/ssamoswap.w.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
$schema: inst_schema.json#
kind: instruction
name: ssamoswap.w
long_name: No synopsis available
long_name: Atomic Swap Word from a Shadow Stack Location
description: |
No description available.
The `ssamoswap.w` atomically loads a 32-bit data value from address of a shadow
stack location in xs1, puts the loaded value into register xd, and stores the
32-bit value held in xs2 to the original address in xs1.
definedBy: Zicfiss
assembly: xd, xs2, xs1
encoding:
Expand All @@ -31,3 +33,17 @@ access:
vu: always
data_independent_timing: false
operation(): |
if (!implemented?(ExtensionName::S)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1'b1) || (CSR[henvcfg].SSE == 1'b1) || (CSR[senvcfg].SSE == 1'b1)) {
XReg addr_in_ssp = X[xs1];
X[xd] = amo<32>(addr_in_ssp, X[xs2][31:0], AmoOperation::Swap, aq, rl, $encoding);
}
26 changes: 24 additions & 2 deletions spec/std/isa/inst/Zicfiss/sspopchk.x1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
$schema: inst_schema.json#
kind: instruction
name: sspopchk.x1
long_name: No synopsis available
long_name: Pop from the Shadow Stack
description: |
No description available.
A shadow stack pop operation is defined as an XLEN wide read from the current top
of the shadow stack followed by an increment of the ssp by XLEN/8.
definedBy: Zicfiss
assembly: sspopchk_x1
encoding:
Expand All @@ -21,3 +22,24 @@ access:
vu: always
data_independent_timing: false
operation(): |
Bits<12> ssp_addr = 0x011;
Csr csr_handle = direct_csr_lookup(ssp_addr);

if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1) || (CSR[henvcfg].SSE == 1) || (CSR[senvcfg].SSE == 1)) {
Bits<XLEN> ssp = csr_sw_read(csr_handle);
XReg temp = read_memory<XLEN>(ssp, $encoding);
if (temp != X[1]) {
raise(ExceptionCode::SoftwareCheck, mode(), $encoding);
}
csr_sw_write(csr_handle, (ssp + (XLEN/8)));
}
26 changes: 24 additions & 2 deletions spec/std/isa/inst/Zicfiss/sspopchk.x5.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
$schema: inst_schema.json#
kind: instruction
name: sspopchk.x5
long_name: No synopsis available
long_name: Pop from the Shadow Stack
description: |
No description available.
A shadow stack pop operation is defined as an XLEN wide read from the current top
of the shadow stack followed by an increment of the ssp by XLEN/8.
definedBy: Zicfiss
assembly: sspopchk_x5
encoding:
Expand All @@ -21,3 +22,24 @@ access:
vu: always
data_independent_timing: false
operation(): |
Bits<12> ssp_addr = 0x011;
Csr csr_handle = direct_csr_lookup(ssp_addr);

if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1) || (CSR[henvcfg].SSE == 1) || (CSR[senvcfg].SSE == 1)) {
Bits<XLEN> ssp = csr_sw_read(csr_handle);
XReg temp = read_memory<XLEN>(ssp, $encoding);
if (temp != X[5]) {
raise(ExceptionCode::SoftwareCheck, mode(), $encoding);
}
csr_sw_write(csr_handle, (ssp + (XLEN/8)));
}
24 changes: 22 additions & 2 deletions spec/std/isa/inst/Zicfiss/sspush.x1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
$schema: inst_schema.json#
kind: instruction
name: sspush.x1
long_name: No synopsis available
long_name: Push to the Shadow Stack from register x1
description: |
No description available.
A shadow stack push operation is defined as decrement of the ssp by XLEN/8
followed by a store of the value in the link register x1 to memory at the
new top of the shadow stack.
definedBy: Zicfiss
assembly: sspush_x1
encoding:
Expand All @@ -21,3 +23,21 @@ access:
vu: always
data_independent_timing: false
operation(): |
Bits<12> ssp_addr = 0x011;
Csr csr_handle = direct_csr_lookup(ssp_addr);

if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1'b1) || (CSR[henvcfg].SSE == 1'b1) || (CSR[senvcfg].SSE == 1'b1)) {
Bits<XLEN> ssp = csr_sw_read(csr_handle) - (XLEN/8);
write_memory<XLEN>(ssp, X[1], $encoding);
csr_sw_write(csr_handle, ssp);
}
24 changes: 22 additions & 2 deletions spec/std/isa/inst/Zicfiss/sspush.x5.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
$schema: inst_schema.json#
kind: instruction
name: sspush.x5
long_name: No synopsis available
long_name: Push to the Shadow Stack from register x5
description: |
No description available.
A shadow stack push operation is defined as decrement of the ssp by XLEN/8
followed by a store of the value in the link register x5 to memory at the
new top of the shadow stack.
definedBy: Zicfiss
assembly: sspush_x5
encoding:
Expand All @@ -21,3 +23,21 @@ access:
vu: always
data_independent_timing: false
operation(): |
Bits<12> ssp_addr = 0x011;
Csr csr_handle = direct_csr_lookup(ssp_addr);

if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if ((mode() < PrivilegeMode::M && CSR[menvcfg].SSE == 0) ||
(mode() == PrivilegeMode::U && CSR[senvcfg].SSE == 0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if ((mode() == PrivilegeMode::VS && CSR[henvcfg].SSE == 0) ||
(mode() == PrivilegeMode::VU && (CSR[henvcfg].SSE == 0 || CSR[senvcfg].SSE == 0))) {
raise(ExceptionCode::VirtualInstruction, mode(), $encoding);
}

if ((CSR[menvcfg].SSE == 1'b1) || (CSR[henvcfg].SSE == 1'b1) || (CSR[senvcfg].SSE == 1'b1)) {
Bits<XLEN> ssp = csr_sw_read(csr_handle) - (XLEN/8);
write_memory<XLEN>(ssp, X[5], $encoding);
csr_sw_write(csr_handle, ssp);
}
Loading
Loading