From d6cc22b9025b4e3a4a82d5b2ac764eb23a205b6b Mon Sep 17 00:00:00 2001 From: Albert Yosher Date: Thu, 23 Jan 2025 21:33:07 +0200 Subject: [PATCH 1/3] Xqccmp extension: initiall add: Similar to Zcmp extension, but with different register storing order + qc.cm.pushfp instruction Signed-off-by: Albert Yosher --- cfgs/qc_iu/arch_overlay/ext/Xqccmp.yaml | 100 ++++++++++++++++++ .../inst/Xqccmp/qc.cm.mva01s.yaml | 33 ++++++ .../inst/Xqccmp/qc.cm.mvsa01.yaml | 35 ++++++ .../arch_overlay/inst/Xqccmp/qc.cm.pop.yaml | 83 +++++++++++++++ .../inst/Xqccmp/qc.cm.popret.yaml | 84 +++++++++++++++ .../inst/Xqccmp/qc.cm.popretz.yaml | 85 +++++++++++++++ .../arch_overlay/inst/Xqccmp/qc.cm.push.yaml | 84 +++++++++++++++ .../inst/Xqccmp/qc.cm.pushfp.yaml | 85 +++++++++++++++ cfgs/qc_iu/cfg.yaml | 5 + 9 files changed, 594 insertions(+) create mode 100644 cfgs/qc_iu/arch_overlay/ext/Xqccmp.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml create mode 100644 cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml diff --git a/cfgs/qc_iu/arch_overlay/ext/Xqccmp.yaml b/cfgs/qc_iu/arch_overlay/ext/Xqccmp.yaml new file mode 100644 index 000000000..fa630e675 --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/ext/Xqccmp.yaml @@ -0,0 +1,100 @@ +# yaml-language-server: $schema=../../../../schemas/ext_schema.json + +$schema: ext_schema.json# +kind: extension +name: Xqccmp +long_name: 16-bit Push/Pop instructions and double-moves +type: unprivileged +versions: +- version: "0.1.0" + state: development + ratification_date: null + contributors: + - name: Albert Yosher + company: Qualcomm Technologies, Inc. + email: ayosher@qti.qualcomm.com + - name: Derek Hower + company: Qualcomm Technologies, Inc. + email: dhower@qti.qualcomm.com + - name: Ana Pazos + company: Qualcomm Technologies, Inc. + email: apazos@qti.qualcomm.com + - name: James Ball + company: Qualcomm Technologies, Inc. + email: jameball@qti.qualcomm.com + requires: + name: Zca + version: ">= 1.0.0" +description: | + The Xqccmp extension is a set of instructions which may be executed as a series of existing 32-bit RISC-V instructions. + + This extension reuses some encodings from _c.fsdsp_. Therefore it is _incompatible_ with <>, + which is included when C and D extensions are both present. + + NOTE: Xqccmp is primarily targeted at embedded class CPUs due to implementation complexity. Additionally, it is not compatible with architecture class profiles. + + The Xqccmp extension depends on the <> extension. + + The Xqccmp extension using same encodings as Zcmp extension for similar instructions, with 2 major differences: + + * Order of load and store of registers is opposite to Zcmp order, but compliant with SW ABI + * Xqccmp on top of Zcmp instructions defines qc.cm.pushfp instruction to manage frame pointer + + The PUSH/POP assembly syntax uses several variables, the meaning of which are: + + * _reg_list_ is a list containing 1 to 13 registers (ra and 0 to 12 s registers) + ** valid values: {ra}, {ra, s0}, {ra, s0-s1}, {ra, s0-s2}, ..., {ra, s0-s8}, {ra, s0-s9}, {ra, s0-s11} + ** note that {ra, s0-s10} is _not_ valid, giving 12 lists not 13 for better encoding + * _stack_adj_ is the total size of the stack frame. + ** valid values vary with register list length and the specific encoding, see the instruction pages for details. + + [%header,cols="^1,^1,4,8"] + |=== + |RV32 + |RV64 + |Mnemonic + |Instruction + + |yes + |yes + |qc.cm.push _{reg_list}, -stack_adj_ + |<<#insns-qc_cm_push>> + + |yes + |yes + |qc.cm.pushfp _{reg_list}, -stack_adj_ + |<<#insns-qc_cm_pushfp>> + + |yes + |yes + |qc.cm.pop _{reg_list}, stack_adj_ + |<<#insns-qc_cm_pop>> + + |yes + |yes + |qc.cm.popret _{reg_list}, stack_adj_ + |<<#insns-qc_cm_popret>> + + |yes + |yes + |qc.cm.popretz _{reg_list}, stack_adj_ + |<<#insns-qc_cm_popretz>> + + |yes + |yes + |qc.cm.mva01s _rs1', rs2'_ + |<<#insns-qc_cm_mva01s>> + + |yes + |yes + |qc.cm.mvsa01 _r1s', r2s'_ + |<<#insns-qc_cm_mvsa01>> + + |=== + +doc_license: + name: Creative Commons Attribution 4.0 International License + url: https://creativecommons.org/licenses/by/4.0/ +company: + name: Qualcomm Technologies, Inc. + url: https://qualcomm.com diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml new file mode 100644 index 000000000..746844335 --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.mva01s +long_name: Move two s0-s7 registers into a0-a1 +description: | + This instruction moves r1s' into a0 and r2s' into a1. The execution is atomic, so it is not possible to observe state where only one of a0 or a1 have been updated. + The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. The mapping between them is specified in the pseudo-code below. +definedBy: + anyOf: + - Xqccmp +assembly: r1s, r2s +encoding: + match: 101011---11---10 + variables: + - name: r1s + location: 9-7 + - name: r2s + location: 4-2 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Zcmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + XReg xreg1 = (r1s[2:1]>0) ? {1,0,r1s[2:0]} : {0,1,r1s[2:0]}; + XReg xreg2 = (r2s[2:1]>0) ? {1,0,r2s[2:0]} : {0,1,r2s[2:0]}; + X[10] = X[xreg1]; + X[11] = X[xreg2]; diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml new file mode 100644 index 000000000..e9a190135 --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml @@ -0,0 +1,35 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.mvsa01 +long_name: Move a0-a1 into two registers of s0-s7 +description: | + This instruction moves a0 into r1s' and a1 into r2s'. r1s' and r2s' must be different. + The execution is atomic, so it is not possible to observe state where only one of r1s' or r2s' has been updated. + The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. + The mapping between them is specified in the pseudo-code below. +definedBy: + anyOf: + - Xqccmp +assembly: r1s, r2s +encoding: + match: 101011---01---10 + variables: + - name: r1s + location: 9-7 + - name: r2s + location: 4-2 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Zcmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + XReg xreg1 = (r1s[2:1]>0) ? {1,0,r1s[2:0]} : {0,1,r1s[2:0]}; + XReg xreg2 = (r2s[2:1]>0) ? {1,0,r2s[2:0]} : {0,1,r2s[2:0]}; + X[xreg1] = X[10]; + X[xreg2] = X[11]; diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml new file mode 100644 index 000000000..e81e9c625 --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml @@ -0,0 +1,83 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.pop +long_name: Destroy function call stack frame +description: | + Destroy stack frame: load ra and 0 to 12 saved registers from the stack frame, deallocate the stack frame. + This instruction pops (loads) the registers in `reg_list` from stack memory, and then adjusts the stack pointer by `stack_adj`. + + Restrictions on stack_adj: + + * it must be enough to store all of the listed registers + * it must be a multiple of 16 (bytes): + ** for RV32 the allowed values are: 16, 32, 48, 64, 80, 96, 112 + ** for RV64 the allowed values are: 16, 32, 48, 64, 80, 96, 112, 128, 144, 160 +definedBy: + anyOf: + - Xqccmp +assembly: reg_list, stack_adj +encoding: + match: 10111010------10 + variables: + - name: rlist + location: 7-4 + not: [0, 1, 2, 3] + - name: spimm + location: 3-2 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Xqccmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg size = xlen(); + XReg nreg = (rlist == 15) ? 13 : (rlist - 3); + XReg stack_aligned_adj = (nreg * 4 + 15) & ~0xF; + XReg virtual_address_sp = X[2]; + XReg virtual_address_new_sp = virtual_address_sp + stack_aligned_adj + spimm; + XReg virtual_address_base = virtual_address_new_sp - size; + + + X[ 1] = read_memory_xlen(virtual_address_base - 0*size, $encoding); + if (nreg > 1) { + X[ 8] = read_memory_xlen(virtual_address_base - 1*size, $encoding); + } + if (nreg > 2) { + X[ 9] = read_memory_xlen(virtual_address_base - 2*size, $encoding); + } + if (nreg > 3) { + X[18] = read_memory_xlen(virtual_address_base - 3*size, $encoding); + } + if (nreg > 4) { + X[19] = read_memory_xlen(virtual_address_base - 4*size, $encoding); + } + if (nreg > 5) { + X[20] = read_memory_xlen(virtual_address_base - 5*size, $encoding); + } + if (nreg > 6) { + X[21] = read_memory_xlen(virtual_address_base - 6*size, $encoding); + } + if (nreg > 7) { + X[22] = read_memory_xlen(virtual_address_base - 7*size, $encoding); + } + if (nreg > 8) { + X[23] = read_memory_xlen(virtual_address_base - 8*size, $encoding); + } + if (nreg > 9) { + X[24] = read_memory_xlen(virtual_address_base - 9*size, $encoding); + } + if (nreg > 10) { + X[25] = read_memory_xlen(virtual_address_base - 10*size, $encoding); + } + if (nreg > 11) { + X[26] = read_memory_xlen(virtual_address_base - 11*size, $encoding); + X[27] = read_memory_xlen(virtual_address_base - 12*size, $encoding); + } + + X[2] = virtual_address_new_sp; diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml new file mode 100644 index 000000000..89db4241f --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml @@ -0,0 +1,84 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.popret +long_name: Destroy function call stack frame and return to `ra`. +description: | + Destroy stack frame: load ra and 0 to 12 saved registers from the stack frame, deallocate the stack frame, return to `ra`. + This instruction pops (loads) the registers in `reg_list` from stack memory, and then adjusts the stack pointer by `stack_adj` and then return to ra. + + Restrictions on stack_adj: + + * it must be enough to store all of the listed registers + * it must be a multiple of 16 (bytes): + ** for RV32 the allowed values are: 16, 32, 48, 64, 80, 96, 112 + ** for RV64 the allowed values are: 16, 32, 48, 64, 80, 96, 112, 128, 144, 160 +definedBy: + anyOf: + - Xqccmp +assembly: reg_list, stack_adj +encoding: + match: 10111110------10 + variables: + - name: rlist + location: 7-4 + not: [0, 1, 2, 3] + - name: spimm + location: 3-2 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Xqccmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg size = xlen(); + XReg nreg = (rlist == 15) ? 13 : (rlist - 3); + XReg stack_aligned_adj = (nreg * 4 + 15) & ~0xF; + XReg virtual_address_sp = X[2]; + XReg virtual_address_new_sp = virtual_address_sp + stack_aligned_adj + spimm; + XReg virtual_address_base = virtual_address_new_sp - size; + + + X[ 1] = read_memory_xlen(virtual_address_base - 0*size, $encoding); + if (nreg > 1) { + X[ 8] = read_memory_xlen(virtual_address_base - 1*size, $encoding); + } + if (nreg > 2) { + X[ 9] = read_memory_xlen(virtual_address_base - 2*size, $encoding); + } + if (nreg > 3) { + X[18] = read_memory_xlen(virtual_address_base - 3*size, $encoding); + } + if (nreg > 4) { + X[19] = read_memory_xlen(virtual_address_base - 4*size, $encoding); + } + if (nreg > 5) { + X[20] = read_memory_xlen(virtual_address_base - 5*size, $encoding); + } + if (nreg > 6) { + X[21] = read_memory_xlen(virtual_address_base - 6*size, $encoding); + } + if (nreg > 7) { + X[22] = read_memory_xlen(virtual_address_base - 7*size, $encoding); + } + if (nreg > 8) { + X[23] = read_memory_xlen(virtual_address_base - 8*size, $encoding); + } + if (nreg > 9) { + X[24] = read_memory_xlen(virtual_address_base - 9*size, $encoding); + } + if (nreg > 10) { + X[25] = read_memory_xlen(virtual_address_base - 10*size, $encoding); + } + if (nreg > 11) { + X[26] = read_memory_xlen(virtual_address_base - 11*size, $encoding); + X[27] = read_memory_xlen(virtual_address_base - 12*size, $encoding); + } + + X[2] = virtual_address_new_sp; + jump(X[1]); diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml new file mode 100644 index 000000000..a8e24a92b --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml @@ -0,0 +1,85 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.popretz +long_name: Destroy function call stack frame, move zero to `a0` and return to `ra`. +description: | + Destroy stack frame: load `ra` and 0 to 12 saved registers from the stack frame, deallocate the stack frame, move zero to `a0`, return to `ra`. + This instruction pops (loads) the registers in `reg_list` from stack memory, and then adjusts the stack pointer by `stack_adj`, move zero to `a0` and then return to `ra`. + + Restrictions on stack_adj: + + * it must be enough to store all of the listed registers + * it must be a multiple of 16 (bytes): + ** for RV32 the allowed values are: 16, 32, 48, 64, 80, 96, 112 + ** for RV64 the allowed values are: 16, 32, 48, 64, 80, 96, 112, 128, 144, 160 +definedBy: + anyOf: + - Xqccmp +assembly: reg_list, stack_adj +encoding: + match: 10111100------10 + variables: + - name: rlist + location: 7-4 + not: [0, 1, 2, 3] + - name: spimm + location: 3-2 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Xqccmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg size = xlen(); + XReg nreg = (rlist == 15) ? 13 : (rlist - 3); + XReg stack_aligned_adj = (nreg * 4 + 15) & ~0xF; + XReg virtual_address_sp = X[2]; + XReg virtual_address_new_sp = virtual_address_sp + stack_aligned_adj + spimm; + XReg virtual_address_base = virtual_address_new_sp - size; + + + X[ 1] = read_memory_xlen(virtual_address_base - 0*size, $encoding); + if (nreg > 1) { + X[ 8] = read_memory_xlen(virtual_address_base - 1*size, $encoding); + } + if (nreg > 2) { + X[ 9] = read_memory_xlen(virtual_address_base - 2*size, $encoding); + } + if (nreg > 3) { + X[18] = read_memory_xlen(virtual_address_base - 3*size, $encoding); + } + if (nreg > 4) { + X[19] = read_memory_xlen(virtual_address_base - 4*size, $encoding); + } + if (nreg > 5) { + X[20] = read_memory_xlen(virtual_address_base - 5*size, $encoding); + } + if (nreg > 6) { + X[21] = read_memory_xlen(virtual_address_base - 6*size, $encoding); + } + if (nreg > 7) { + X[22] = read_memory_xlen(virtual_address_base - 7*size, $encoding); + } + if (nreg > 8) { + X[23] = read_memory_xlen(virtual_address_base - 8*size, $encoding); + } + if (nreg > 9) { + X[24] = read_memory_xlen(virtual_address_base - 9*size, $encoding); + } + if (nreg > 10) { + X[25] = read_memory_xlen(virtual_address_base - 10*size, $encoding); + } + if (nreg > 11) { + X[26] = read_memory_xlen(virtual_address_base - 11*size, $encoding); + X[27] = read_memory_xlen(virtual_address_base - 12*size, $encoding); + } + + X[2] = virtual_address_new_sp; + X[10] = 0; + jump(X[1]); diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml new file mode 100644 index 000000000..383a099ee --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml @@ -0,0 +1,84 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.push +long_name: Create function call stack frame +description: | + Create stack frame: store `ra` and 0 to 12 saved registers to the stack frame, optionally allocate additional stack space. + This instruction pushes (stores) the registers in rlist to the memory below the stack pointer, + and then creates the stack frame by decrementing the stack pointer by stack_adj, including any additional stack space requested by the value of `spimm`. + + Restrictions on stack_adj: + + * it must be enough to store all of the listed registers + * it must be a multiple of 16 (bytes): + ** for RV32 the allowed values are: 16, 32, 48, 64, 80, 96, 112 + ** for RV64 the allowed values are: 16, 32, 48, 64, 80, 96, 112, 128, 144, 160 +definedBy: + anyOf: + - Xqccmp +assembly: reg_list, -stack_adj +encoding: + match: 10111000------10 + variables: + - name: rlist + location: 7-4 + not: [0, 1, 2, 3] + - name: spimm + location: 3-2 + left_shift: 4 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Xqccmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg size = xlen(); + XReg nreg = (rlist == 15) ? 13 : (rlist - 3); + XReg stack_aligned_adj = (nreg * 4 + 15) & ~0xF; + XReg virtual_address_sp = X[2]; + XReg virtual_address_new_sp = virtual_address_sp - stack_aligned_adj - spimm; + XReg virtual_address_base = virtual_address_sp - size; + + write_memory_xlen(virtual_address_base - 0*size, X[ 1], $encoding); + if (nreg > 1) { + write_memory_xlen(virtual_address_base - 1*size, X[ 8], $encoding); + } + if (nreg > 2) { + write_memory_xlen(virtual_address_base - 2*size, X[ 9], $encoding); + } + if (nreg > 3) { + write_memory_xlen(virtual_address_base - 3*size, X[18], $encoding); + } + if (nreg > 4) { + write_memory_xlen(virtual_address_base - 4*size, X[19], $encoding); + } + if (nreg > 5) { + write_memory_xlen(virtual_address_base - 5*size, X[20], $encoding); + } + if (nreg > 6) { + write_memory_xlen(virtual_address_base - 6*size, X[21], $encoding); + } + if (nreg > 7) { + write_memory_xlen(virtual_address_base - 7*size, X[22], $encoding); + } + if (nreg > 8) { + write_memory_xlen(virtual_address_base - 8*size, X[23], $encoding); + } + if (nreg > 9) { + write_memory_xlen(virtual_address_base - 9*size, X[24], $encoding); + } + if (nreg > 10) { + write_memory_xlen(virtual_address_base - 10*size, X[25], $encoding); + } + if (nreg > 11) { + write_memory_xlen(virtual_address_base - 11*size, X[26], $encoding); + write_memory_xlen(virtual_address_base - 12*size, X[27], $encoding); + } + + X[2] = virtual_address_new_sp; diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml new file mode 100644 index 000000000..893fcc615 --- /dev/null +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml @@ -0,0 +1,85 @@ +# yaml-language-server: $schema=../../../../../schemas/inst_schema.json + +$schema: "inst_schema.json#" +kind: instruction +name: qc.cm.pushfp +long_name: Create function call stack frame with frame pointer +description: | + Create stack frame: store `ra` and 0 to 12 saved registers to the stack frame, optionally allocate additional stack space. + As well, instruction initializes frame pointer (`fp`, aka `x8`) to the Canonical Frame Address (`sp` aka `x2`) on function entry. + This instruction pushes (stores) the registers in rlist to the memory below the stack pointer, + and then creates the stack frame by decrementing the stack pointer by stack_adj, including any additional stack space requested by the value of `spimm`. + + Restrictions on stack_adj: + + * it must be enough to store all of the listed registers + * it must be a multiple of 16 (bytes): + ** for RV32 the allowed values are: 16, 32, 48, 64, 80, 96, 112 + ** for RV64 the allowed values are: 16, 32, 48, 64, 80, 96, 112, 128, 144, 160 +definedBy: + anyOf: + - Xqccmp +assembly: reg_list, -stack_adj +encoding: + match: 10111001------10 + variables: + - name: rlist + location: 7-4 + not: [0, 1, 2, 3] + - name: spimm + location: 3-2 +access: + s: always + u: always + vs: always + vu: always +operation(): | + if (implemented?(ExtensionName::Xqccmp) && (CSR[misa].C == 1'b0)) { + raise(ExceptionCode::IllegalInstruction, mode(), $encoding); + } + + XReg size = xlen(); + XReg nreg = (rlist == 15) ? 13 : (rlist - 3); + XReg stack_aligned_adj = (nreg * 4 + 15) & ~0xF; + XReg virtual_address_sp = X[2]; + XReg virtual_address_new_sp = virtual_address_sp - stack_aligned_adj - spimm; + XReg virtual_address_base = virtual_address_sp - size; + + write_memory_xlen(virtual_address_base - 0*size, X[ 1], $encoding); + if (nreg > 1) { + write_memory_xlen(virtual_address_base - 1*size, X[ 8], $encoding); + } + if (nreg > 2) { + write_memory_xlen(virtual_address_base - 2*size, X[ 9], $encoding); + } + if (nreg > 3) { + write_memory_xlen(virtual_address_base - 3*size, X[18], $encoding); + } + if (nreg > 4) { + write_memory_xlen(virtual_address_base - 4*size, X[19], $encoding); + } + if (nreg > 5) { + write_memory_xlen(virtual_address_base - 5*size, X[20], $encoding); + } + if (nreg > 6) { + write_memory_xlen(virtual_address_base - 6*size, X[21], $encoding); + } + if (nreg > 7) { + write_memory_xlen(virtual_address_base - 7*size, X[22], $encoding); + } + if (nreg > 8) { + write_memory_xlen(virtual_address_base - 8*size, X[23], $encoding); + } + if (nreg > 9) { + write_memory_xlen(virtual_address_base - 9*size, X[24], $encoding); + } + if (nreg > 10) { + write_memory_xlen(virtual_address_base - 10*size, X[25], $encoding); + } + if (nreg > 11) { + write_memory_xlen(virtual_address_base - 11*size, X[26], $encoding); + write_memory_xlen(virtual_address_base - 12*size, X[27], $encoding); + } + + X[8] = virtual_address_sp; + X[2] = virtual_address_new_sp; diff --git a/cfgs/qc_iu/cfg.yaml b/cfgs/qc_iu/cfg.yaml index a28bdd53a..2d6fd2b91 100644 --- a/cfgs/qc_iu/cfg.yaml +++ b/cfgs/qc_iu/cfg.yaml @@ -8,6 +8,11 @@ description: Configuration with the Xqci custom extension. mandatory_extensions: - { name: Sm } - { name: I } + - { name: M } + - { name: B } + - { name: Zca } + - { name: Zcb } + - { name: Xqccmp, version: "~> 0.1" } - { name: Xqci, version: "~> 0.5" } params: XLEN: 32 From 57b05e0448c11914117e35b3ad02bc2a22fefd15 Mon Sep 17 00:00:00 2001 From: Albert Yosher Date: Sun, 26 Jan 2025 19:47:56 +0200 Subject: [PATCH 2/3] Xqccmp extension: add excludedBy statement to all instructions like for Zcmp extension Signed-off-by: Albert Yosher --- cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml | 4 ++++ cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml | 4 ++++ cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml | 4 ++++ cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml | 4 ++++ cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml | 4 ++++ cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml | 4 ++++ cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml | 4 ++++ 7 files changed, 28 insertions(+) diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml index 746844335..bd358bb09 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml @@ -10,6 +10,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: r1s, r2s encoding: match: 101011---11---10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml index e9a190135..4cb79a324 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml @@ -12,6 +12,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: r1s, r2s encoding: match: 101011---01---10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml index e81e9c625..50f2b85c1 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml @@ -17,6 +17,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: reg_list, stack_adj encoding: match: 10111010------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml index 89db4241f..298fbe161 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml @@ -17,6 +17,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: reg_list, stack_adj encoding: match: 10111110------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml index a8e24a92b..bc4aeea70 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml @@ -17,6 +17,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: reg_list, stack_adj encoding: match: 10111100------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml index 383a099ee..9129dbc7f 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml @@ -18,6 +18,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: reg_list, -stack_adj encoding: match: 10111000------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml index 893fcc615..71569b8b5 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml @@ -19,6 +19,10 @@ description: | definedBy: anyOf: - Xqccmp +excludedBy: + anyOf: + - allOf: [C, D] + - Zcd assembly: reg_list, -stack_adj encoding: match: 10111001------10 From a1a928b365a9765daa093ec8f0bbf58dc4c73b62 Mon Sep 17 00:00:00 2001 From: Albert Yosher Date: Mon, 27 Jan 2025 19:13:20 +0200 Subject: [PATCH 3/3] Xqccmp extension: all instructions of this extensions is mutually exclusive with Zcmp Signed-off-by: Albert Yosher --- cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml | 1 + cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml | 1 + cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml | 1 + cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml | 1 + cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml | 1 + cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml | 1 + cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml | 1 + 7 files changed, 7 insertions(+) diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml index bd358bb09..f6eef31eb 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mva01s.yaml @@ -14,6 +14,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: r1s, r2s encoding: match: 101011---11---10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml index 4cb79a324..2fbb3d1f6 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.mvsa01.yaml @@ -16,6 +16,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: r1s, r2s encoding: match: 101011---01---10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml index 50f2b85c1..df46657eb 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pop.yaml @@ -21,6 +21,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: reg_list, stack_adj encoding: match: 10111010------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml index 298fbe161..324b9da5c 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popret.yaml @@ -21,6 +21,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: reg_list, stack_adj encoding: match: 10111110------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml index bc4aeea70..ae7c70fec 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.popretz.yaml @@ -21,6 +21,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: reg_list, stack_adj encoding: match: 10111100------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml index 9129dbc7f..fb6d5cb61 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.push.yaml @@ -22,6 +22,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: reg_list, -stack_adj encoding: match: 10111000------10 diff --git a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml index 71569b8b5..1f79b4c2c 100644 --- a/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml +++ b/cfgs/qc_iu/arch_overlay/inst/Xqccmp/qc.cm.pushfp.yaml @@ -23,6 +23,7 @@ excludedBy: anyOf: - allOf: [C, D] - Zcd + - Zcmp assembly: reg_list, -stack_adj encoding: match: 10111001------10