Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Zaamo instructions. #15

Merged
merged 1 commit into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion arch/ext/I.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,47 @@ I:
maximum: 127
MISALIGNED_LDST:
description: |
Whether or not the implementation supports misaligned loads and stores in
Whether or not the implementation supports non-atomic misaligned loads and stores in
main memory (does *not* affect misaligned support to device memory)
schema:
type: boolean
MISALIGNED_LDST_EXCEPTION_PRIORITY:
description: |
The relative priority of a load/store/AMO exception vs. load/store/AMO page-fault
or access-fault exceptions.

May be one of:

[separator="!"]
!===
! high ! Misaligned load/store/AMO exceptions are always higher priority than load/store/AMO page-fault and access-fault exceptions.
! low ! Misaligned load/store/AMO exceptions are always lower priority than load/store/AMO page-fault and access-fault exceptions.
!===

MISALIGNED_LDST_EXCEPTION_PRIORITY cannot be "high" when MAX_MISALIGNED_ATOMICITY_GRANULE_SIZE
is non-zero, since the atomicity of an access cannot be determined in that case until after
address translation.
schema:
type: string
enum: ["high", "low"]
extra_validation: |
assert (MISALIGNED_LDST_EXCEPTION_PRIORITY == "low") if MAX_MISALIGNED_ATOMICITY_GRANULE_SIZE.positive?
MAX_MISALIGNED_ATOMICITY_GRANULE_SIZE:
description: |
The maximum granule size, in bytes, that the hart can atomically perform a
misligned load/store/AMO without raising a Misaligned exception. When MAX_MISALIGNED_ATOMICITY_GRANULE_SIZE is 0, the hart
cannot atomically perform a misaligned load/store/AMO. When a power of two, the hart can
atomically load/store/AMO a misaligned access that is fully contained in a
MAX_MISALIGNED_ATOMICITY_GRANULE_SIZE-aligned region.

[NOTE]
Even if the hart is capable of performing a misligned load/store/AMO atomically,
a misaligned exception may still occur if the access does not have the appropriate
Misaligned Atomicity Granule PMA set.
schema:
type: integer
# can't be larger than a page, since there is no way to reconcile that with virtual memory
enum: [0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096]
MISALIGNED_SPLIT_STRATEGY:
description: |
when misaligned accesses are supported, this determines the *order* in the implementation appears
Expand Down
40 changes: 40 additions & 0 deletions arch/inst/A/amoadd.d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amoadd.d:
long_name: Atomic fetch-and-add doubleword
description: |
Atomically:

* Load the doubleword at address _rs1_
* Write the loaded value into _rd_
* Add the value of register _rs2_ to the loaded value
* Write the sum to the address in _rs1_
definedBy: [A, Zaamo]
base: 64
assembly: xd, xs2, (xrs1)
encoding:
match: 00000------------011-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<64>(virtual_address, X[rs2], AmoOperation::Add, aq, rl);
39 changes: 39 additions & 0 deletions arch/inst/A/amoadd.w.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amoadd.w:
long_name: Atomic fetch-and-add word
description: |
Atomically:

* Load the word at address _rs1_
* Write the sign-extended value into _rd_
* Add the least-significant word of register _rs2_ to the loaded value
* Write the sum to the address in _rs1_
definedBy: [A, Zaamo]
assembly: xd, xs2, (xrs1)
encoding:
match: 00000------------010-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<32>(virtual_address, X[rs2][31:0], AmoOperation::Add, aq, rl);
40 changes: 40 additions & 0 deletions arch/inst/A/amoand.d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amoand.d:
long_name: Atomic fetch-and-and doubleword
description: |
Atomically:

* Load the doubleword at address _rs1_
* Write the loaded value into _rd_
* AND the value of register _rs2_ to the loaded value
* Write the result to the address in _rs1_
definedBy: [A, Zaamo]
base: 64
assembly: xd, xs2, (xrs1)
encoding:
match: 01100------------011-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<64>(virtual_address, X[rs2], AmoOperation::And, aq, rl);
39 changes: 39 additions & 0 deletions arch/inst/A/amoand.w.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amoand.w:
long_name: Atomic fetch-and-and word
description: |
Atomically:

* Load the word at address _rs1_
* Write the sign-extended value into _rd_
* AND the least-significant word of register _rs2_ to the loaded value
* Write the result to the address in _rs1_
definedBy: [A, Zaamo]
assembly: xd, xs2, (xrs1)
encoding:
match: 01100------------010-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<32>(virtual_address, X[rs2][31:0], AmoOperation::And, aq, rl);
40 changes: 40 additions & 0 deletions arch/inst/A/amomax.d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amomax.d:
long_name: Atomic MAX doubleword
description: |
Atomically:

* Load the doubleword at address _rs1_
* Write the loaded value into _rd_
* Signed compare the value of register _rs2_ to the loaded value, and select the maximum value
* Write the maximum to the address in _rs1_
definedBy: [A, Zaamo]
base: 64
assembly: xd, xs2, (xrs1)
encoding:
match: 10100------------011-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<64>(virtual_address, X[rs2], AmoOperation::Max, aq, rl);
39 changes: 39 additions & 0 deletions arch/inst/A/amomax.w.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amomax.w:
long_name: Atomic MAX word
description: |
Atomically:

* Load the word at address _rs1_
* Write the sign-extended value into _rd_
* Signed compare the least-significant word of register _rs2_ to the loaded value, and select the maximum value
* Write the maximum to the address in _rs1_
definedBy: [A, Zaamo]
assembly: xd, xs2, (xrs1)
encoding:
match: 10100------------010-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<32>(virtual_address, X[rs2][31:0], AmoOperation::Max, aq, rl);
40 changes: 40 additions & 0 deletions arch/inst/A/amomaxu.d.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amomaxu.d:
long_name: Atomic MAX unsigned doubleword
description: |
Atomically:

* Load the doubleword at address _rs1_
* Write the loaded value into _rd_
* Unsigned compare the value of register _rs2_ to the loaded value, and select the maximum value
* Write the maximum to the address in _rs1_
definedBy: [A, Zaamo]
base: 64
assembly: xd, xs2, (xrs1)
encoding:
match: 11100------------011-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<64>(virtual_address, X[rs2], AmoOperation::Maxu, aq, rl);
39 changes: 39 additions & 0 deletions arch/inst/A/amomaxu.w.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

amomaxu.w:
long_name: Atomic MAX unsigned word
description: |
Atomically:

* Load the word at address _rs1_
* Write the sign-extended value into _rd_
* Unsigned compare the least-significant word of register _rs2_ to the loaded value, and select the maximum value
* Write the maximum to the address in _rs1_
definedBy: [A, Zaamo]
assembly: xd, xs2, (xrs1)
encoding:
match: 11100------------010-----0101111
variables:
- name: aq
location: 26
- name: rl
location: 27
- name: rs2
location: 24-20
- name: rs1
location: 19-15
- name: rd
location: 11-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::A) && (CSR[misa].A == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, $encoding);
}

XReg virtual_address = X[rs1];

X[rd] = amo<32>(virtual_address, X[rs2][31:0], AmoOperation::Maxu, aq, rl);
Loading
Loading