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

Zcb spec support initial add #333

Merged
merged 1 commit into from
Dec 2, 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
42 changes: 42 additions & 0 deletions arch/ext/Zcb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# yaml-language-server: $schema=../../schemas/ext_schema.json

$schema: "ext_schema.json#"
kind: extension
name: Zcb
long_name: Simple code-size saving instructions
description: |
Zcb has simple code-size saving instructions which are easy to implement on all CPUs.
All proposed encodings are currently reserved for all architectures, and have no conflicts with any existing extensions.

The Zcb extension depends on the Zca extension.

As shown on the individual instruction pages, many of the instructions in Zcb depend upon another extension being implemented.
For example, c.mul is only implemented if M or Zmmul is implemented, and c.sext.b is only implemented if Zbb is implemented.

type: unprivileged
company:
name: RISC-V International
url: https://riscv.org
versions:
- version: "1.0.0"
state: ratified
ratification_date: 2023-04
repositories:
- url: https://github.com/riscv/riscv-code-size-reduction
branch: main
contributors:
- name: Tariq Kurd
- name: Ibrahim Abu Kharmeh
- name: Torbjørn Viem Ness
- name: Matteo Perotti
- name: Nidal Faour
- name: Bill Traynor
- name: Rafael Sene
- name: Xinlong Wu
- name: sinan
- name: Jeremy Bennett
- name: Heda Chen
- name: Alasdair Armstrong
- name: Graeme Smecher
- name: Nicolas Brunie
- name: Jiawei
65 changes: 65 additions & 0 deletions arch/inst/Zcb/c.lbu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: c.lbu
long_name: Load unsigned byte, 16-bit encoding
description: |
Loads a 8-bit value from memory into register rd.
It computes an effective address by adding the zero-extended offset, to the base address in register rs1.
It expands to `lbu` `rd, offset(rs1)`.
definedBy:
anyOf:
- Zcb
- Zce
assembly: xd, imm(xs1)
encoding:
match: 100000--------00
variables:
- name: imm
location: 5|6
- name: rd
location: 4-2
- name: rs1
location: 9-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

XReg virtual_address = X[rs1+8] + imm;

X[rd+8] = zext(read_memory<8>(virtual_address, $encoding), 8);

sail(): |
{
let offset : xlenbits = zero_extend(imm);
/* Get the address, X(rs1c) + offset.
Some extensions perform additional checks on address validity. */
match ext_data_get_addr(rs1c, offset, Read(Data), width) {
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
Ext_DataAddr_OK(vaddr) =>
if check_misaligned(vaddr, width)
then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }
else match translateAddr(vaddr, Read(Data)) {
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
TR_Address(paddr, _) =>
match (width) {
BYTE =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),
HALF =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),
WORD =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),
DOUBLE if sizeof(xlen) >= 64 =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),
_ => report_invalid_width(__FILE__, __LINE__, width, "load")
}
}
}
}
66 changes: 66 additions & 0 deletions arch/inst/Zcb/c.lh.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: c.lh
long_name: Load signed halfword, 16-bit encoding
description: |
Loads a 16-bit value from memory into register rd.
It computes an effective address by adding the zero-extended offset, to the base address in register rs1.
It expands to `lh` `rd, offset(rs1)`.
definedBy:
anyOf:
- Zcb
- Zce
assembly: xd, imm(xs1)
encoding:
match: 100001---1----00
variables:
- name: imm
location: 5
left_shift: 1
- name: rd
location: 4-2
- name: rs1
location: 9-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

XReg virtual_address = X[rs1+8] + imm;

X[rd+8] = sext(read_memory<16>(virtual_address, $encoding), 16);

sail(): |
{
let offset : xlenbits = zero_extend(imm);
/* Get the address, X(rs1c) + offset.
Some extensions perform additional checks on address validity. */
match ext_data_get_addr(rs1c, offset, Read(Data), width) {
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
Ext_DataAddr_OK(vaddr) =>
if check_misaligned(vaddr, width)
then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }
else match translateAddr(vaddr, Read(Data)) {
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
TR_Address(paddr, _) =>
match (width) {
BYTE =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),
HALF =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),
WORD =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),
DOUBLE if sizeof(xlen) >= 64 =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),
_ => report_invalid_width(__FILE__, __LINE__, width, "load")
}
}
}
}
66 changes: 66 additions & 0 deletions arch/inst/Zcb/c.lhu.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: c.lhu
long_name: Load unsigned halfword, 16-bit encoding
description: |
Loads a 16-bit value from memory into register rd.
It computes an effective address by adding the zero-extended offset, to the base address in register rs1.
It expands to `lhu` `rd, offset(rs1)`.
definedBy:
anyOf:
- Zcb
- Zce
assembly: xd, imm(xs1)
encoding:
match: 100001---0----00
variables:
- name: imm
location: 5
left_shift: 1
- name: rd
location: 4-2
- name: rs1
location: 9-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

XReg virtual_address = X[rs1+8] + imm;

X[rd+8] = zext(read_memory<16>(virtual_address, $encoding), 16);

sail(): |
{
let offset : xlenbits = zero_extend(imm);
/* Get the address, X(rs1c) + offset.
Some extensions perform additional checks on address validity. */
match ext_data_get_addr(rs1c, offset, Read(Data), width) {
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
Ext_DataAddr_OK(vaddr) =>
if check_misaligned(vaddr, width)
then { handle_mem_exception(vaddr, E_Load_Addr_Align()); RETIRE_FAIL }
else match translateAddr(vaddr, Read(Data)) {
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
TR_Address(paddr, _) =>
match (width) {
BYTE =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 1, aq, rl, false), is_unsigned),
HALF =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 2, aq, rl, false), is_unsigned),
WORD =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 4, aq, rl, false), is_unsigned),
DOUBLE if sizeof(xlen) >= 64 =>
process_load(rdc, vaddr, mem_read(Read(Data), paddr, 8, aq, rl, false), is_unsigned),
_ => report_invalid_width(__FILE__, __LINE__, width, "load")
}
}
}
}
48 changes: 48 additions & 0 deletions arch/inst/Zcb/c.mul.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: c.mul
long_name: Multiply, 16-bit encoding
description: |
This instruction multiplies XLEN bits of the source operands from rsd' and rs2' and writes the lowest XLEN bits of the result to rsd'.

definedBy:
allOf:
- Zcb
- Zmmul
assembly: xd, xs2
encoding:
match: 100111---10---01
variables:
- name: rd
location: 9-7
- name: rs2
location: 4-2
access:
s: always
u: always
vs: always
vu: always
operation(): |

if (implemented?(ExtensionName::M) && (CSR[misa].M == 1'b0)) {
raise (ExceptionCode::IllegalInstruction, mode(), $encoding);
}

if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

X[rd+8] = X[rd+8] * X[rs2+8];

sail(): |
{
let result_wide = to_bits(2 * sizeof(xlen), signed(X(rsdc)) * signed(X(rs2c)));
X(rsdc) = result_wide[(sizeof(xlen) - 1) .. 0];
RETIRE_SUCCESS
}




42 changes: 42 additions & 0 deletions arch/inst/Zcb/c.not.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: c.not
long_name: Bitwise not, 16-bit encoding
description: |
This instruction takes a single source/destination operand.
This instruction takes the one’s complement of rd'/rs1' and writes the result to the same register.

definedBy:
anyOf:
- Zcb
- Zce
assembly: xd
encoding:
match: 100111---1110101
variables:
- name: rd
location: 9-7
access:
s: always
u: always
vs: always
vu: always
operation(): |

if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

X[rd+8] = ~X[rd+8];

sail(): |
{
X(rsdc) = X(rsdc) XOR -1;
RETIRE_SUCCESS
}




37 changes: 37 additions & 0 deletions arch/inst/Zcb/c.sb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# yaml-language-server: $schema=../../../schemas/inst_schema.json

$schema: "inst_schema.json#"
kind: instruction
name: c.sb
long_name: Store unsigned byte, 16-bit encoding
description: |
Stores a 8-bit value from register rs2 into memory.
It computes an effective address by adding the zero-extended offset, to the base address in register rs1.
It expands to `sb` `rs2, offset(rs1)`.
definedBy:
anyOf:
- Zcb
- Zce
assembly: xs2, imm(xs1)
encoding:
match: 100010--------00
variables:
- name: imm
location: 5|6
- name: rs2
location: 4-2
- name: rs1
location: 9-7
access:
s: always
u: always
vs: always
vu: always
operation(): |
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}

XReg virtual_address = X[rs1+8] + imm;

write_memory<8>(virtual_address, X[rs2+8][7:0], $encoding);
Loading