From abc455352d493e07fbdfc644e4bc9490269b648d Mon Sep 17 00:00:00 2001 From: ShehrozKashif Date: Fri, 28 Mar 2025 21:15:55 +0000 Subject: [PATCH 1/2] Add Zclsd extension YAML --- arch/ext/Zclsd.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 arch/ext/Zclsd.yaml diff --git a/arch/ext/Zclsd.yaml b/arch/ext/Zclsd.yaml new file mode 100644 index 000000000..38a74510f --- /dev/null +++ b/arch/ext/Zclsd.yaml @@ -0,0 +1,17 @@ +$schema: "ext_schema.json#" +kind: extension +name: Zclsd +conflicts: Zcf +long_name: Compressed Load/Store Pair for RV32 +description: | + This specification adds load and store instructions using register pairs. It does so by reusing existing instruction encodings which are RV64-only. The specification defines 16-bit encodings. + Load and store instructions will use the same definition of even-odd pairs as defined by the Zdinx extension. + The extension improves static code density, by replacing two separate load or store instructions with a single one. In addition, it can provide a performance improvement for implementations that can make use of a wider than XLEN memory interface. + Zclsd depends on Zilsd and Zca. It has overlapping encodings with Zcf and is thus incompatible with Zcf. +type: unprivileged +versions: + - version: "1.0" + state: ratified + ratification_date: "2025-02" + requires: + allOf: [ Zilsd, Zca ] From d49cdebc14f939752032b1b3689e373dde2b339f Mon Sep 17 00:00:00 2001 From: ShehrozKashif Date: Mon, 7 Apr 2025 19:40:04 +0000 Subject: [PATCH 2/2] add Zclsd instructions --- arch/ext/Zclsd.yaml | 3 +-- arch/inst/C/c.ld.yaml | 20 ++++++++++++++------ arch/inst/C/c.sd.yaml | 18 ++++++++++++++++-- arch/inst/Zclsd/c.ldsp.yaml | 37 +++++++++++++++++++++++++++++++++++++ arch/inst/Zclsd/c.sd.yaml | 36 ++++++++++++++++++++++++++++++++++++ arch/inst/Zclsd/c.sdsp.yaml | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 arch/inst/Zclsd/c.ldsp.yaml create mode 100644 arch/inst/Zclsd/c.sd.yaml create mode 100644 arch/inst/Zclsd/c.sdsp.yaml diff --git a/arch/ext/Zclsd.yaml b/arch/ext/Zclsd.yaml index 38a74510f..ee17c5647 100644 --- a/arch/ext/Zclsd.yaml +++ b/arch/ext/Zclsd.yaml @@ -4,10 +4,9 @@ name: Zclsd conflicts: Zcf long_name: Compressed Load/Store Pair for RV32 description: | - This specification adds load and store instructions using register pairs. It does so by reusing existing instruction encodings which are RV64-only. The specification defines 16-bit encodings. + This extension adds load and store instructions using register pairs. It does so by reusing existing instruction encodings which are RV64-only. The specification defines 16-bit encodings. Load and store instructions will use the same definition of even-odd pairs as defined by the Zdinx extension. The extension improves static code density, by replacing two separate load or store instructions with a single one. In addition, it can provide a performance improvement for implementations that can make use of a wider than XLEN memory interface. - Zclsd depends on Zilsd and Zca. It has overlapping encodings with Zcf and is thus incompatible with Zcf. type: unprivileged versions: - version: "1.0" diff --git a/arch/inst/C/c.ld.yaml b/arch/inst/C/c.ld.yaml index b16adc092..6cb42e9d3 100644 --- a/arch/inst/C/c.ld.yaml +++ b/arch/inst/C/c.ld.yaml @@ -9,11 +9,12 @@ description: | It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1. It expands to `ld` `rd, offset(rs1)`. + For RV32, if the Zclsd extension is enabled, this instruction loads a 64-bit value into registers xd and xd+1. It computes an effective address by adding the zero-extended imm, scaled by 8, to the base address in register xs1. definedBy: anyOf: - C - Zca -base: 64 + - Zclsd assembly: xd, imm(xs1) encoding: match: 011-----------00 @@ -32,13 +33,20 @@ access: vu: always operation(): | if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) { - raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); } - XReg virtual_address = X[rs1] + imm; - - X[rd] = sext(read_memory<64>(virtual_address, $encoding), 64); - + if (XLEN == 32) { + if (implemented?(ExtensionName::Zclsd)) { + X[rd] = sext(read_memory<64>(X[rs1] + imm, $encoding), 64); + X[rd + 1] = sext(read_memory<64>(X[rs1] + imm + 8, $encoding), 64); + } else { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + } else { + XReg virtual_address = X[rs1] + imm; + X[rd] = sext(read_memory<64>(virtual_address, $encoding), 64); + } sail(): | { let offset : xlenbits = sign_extend(imm); diff --git a/arch/inst/C/c.sd.yaml b/arch/inst/C/c.sd.yaml index 5b72210fc..90a5aa34d 100644 --- a/arch/inst/C/c.sd.yaml +++ b/arch/inst/C/c.sd.yaml @@ -13,6 +13,7 @@ definedBy: anyOf: - C - Zca + - Zclsd base: 64 assembly: xs2, imm(xs1) encoding: @@ -32,9 +33,22 @@ access: vu: always operation(): | if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) { - raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); } XReg virtual_address = X[rs1] + imm; - write_memory<64>(virtual_address, X[rs2], $encoding); + if (XLEN == 32) { + if (implemented?(ExtensionName::Zclsd)) { + if (rs2 % 2 != 0) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + Bits<64> data = {X[rs2+1], X[rs2]}; + write_memory<64>(virtual_address, data, $encoding); + } else { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + } else { + write_memory<64>(virtual_address, X[rs2], $encoding); + } diff --git a/arch/inst/Zclsd/c.ldsp.yaml b/arch/inst/Zclsd/c.ldsp.yaml new file mode 100644 index 000000000..32f777211 --- /dev/null +++ b/arch/inst/Zclsd/c.ldsp.yaml @@ -0,0 +1,37 @@ +# yaml-language-server: $schema=../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: c.ldsp +long_name: Stack-pointer based load doubleword to even/odd register pair +description: | + Loads stack-pointer relative 64-bit value into registers rd and rd+1. It computes its effective + address by adding the zero-extended offset, scaled by 8, to the stack pointer, sp. It expands to ld + rd, offset(sp). C.LDSP is only valid when rd≠x0; the code points with rd=x0 are reserved. +definedBy: Zclsd +assembly: rd, offset(sp) +encoding: + match: 011-----------01 + variables: + - name: rd + location: 11-7 + not: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] + - name: imm + location: 4-2|12|6-5 + left_shift: 3 +access: + s: always + u: always + vs: always + vu: always +operation(): | + + Bits base = X[2]; + Bits offset = imm; + Bits eff_addr = base + offset; + + Bits<64> data = read_memory<64>(eff_addr, $encoding); + + X[rd] = data[31:0]; + X[rd+1] = data[63:32]; +sail(): "" #not implemented in the sail model yet diff --git a/arch/inst/Zclsd/c.sd.yaml b/arch/inst/Zclsd/c.sd.yaml new file mode 100644 index 000000000..54e658995 --- /dev/null +++ b/arch/inst/Zclsd/c.sd.yaml @@ -0,0 +1,36 @@ +# yaml-language-server: $schema=../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: c.sd +long_name: Store doubleword from even/odd register pair +description: | + Stores a 64-bit value from registers rs2' and rs2'+1. It computes an effective address by adding + the zero-extended offset, scaled by 8, to the base address in register rs1'. It expands to sd rs2', + offset(rs1'). +definedBy: Zclsd +assembly: c.sd rs2, offset(rs1) +encoding: + match: 111-----------00 + variables: + - name: rs2 + location: 4-2 + - name: rs1 + location: 9-7 + - name: imm + location: 12-10|6-5 +access: + s: always + u: always + vs: always + vu: always +operation(): | + + Bits base = X[2]; + Bits offset = imm << 3; + Bits eff_addr = base + offset; + + Bits<64> data = {X[rs2+1], X[rs2]}; + + write_memory<64>(eff_addr, data, $encoding); +sail(): "" #not implemented in the sail model yet diff --git a/arch/inst/Zclsd/c.sdsp.yaml b/arch/inst/Zclsd/c.sdsp.yaml new file mode 100644 index 000000000..60c91fbda --- /dev/null +++ b/arch/inst/Zclsd/c.sdsp.yaml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: c.sdsp +long_name: Stack-pointer based store doubleword from even/odd register pair +description: | + Stores a stack-pointer relative 64-bit value from registers rs2 and rs2+1. It computes an effective + address by adding the zero-extended offset, scaled by 8, to the stack pointer, sp. It expands to sd + `sd rs2, offset(sp)`. +definedBy: Zclsd +assembly: rs2, offset(sp) +encoding: + match: 111-----------10 + variables: + - name: rs2 + location: 6-2 + - name: imm + location: 9-7|12-10 + left_shift: 3 +access: + s: always + u: always + vs: always + vu: always +operation(): | + + Bits base = X[2]; + Bits offset = imm; + Bits eff_addr = base + offset; + + Bits<64> data = {X[rs2+1], X[rs2]}; + + write_memory<64>(eff_addr, data, $encoding); +sail(): "" #not implemented in the sail model yet