:sectnums:
:version-label: v1.0.0-RC5.7
:lifecycle-state: frozen

[#Zc]
== Zc* {version-label}

=== Change history since v0.70.1 (tagged release)

.Change history
[width="100%",options=header]
|====================================================================================
|Version  | change
|v1.0.0-RC5.7| Add Zcb description and fix some typos. PUBLIC REVIEW REVISION.
|v1.0.0-RC5.6| Remove Zcmpe which is _not_ frozen and is causing confusion
|v1.0.0-RC5.5| Following ARC review Adjust the split so we have 224 cm.jalt and 32 cm.jt
|v1.0.0-RC5.4| Change wording for dependencies to match arch manual "Zxxx requires Zyyy" changed to "Zxxx depends on Zyyy"
|v1.0.0-RC5.3| Add dependency on Zicsr for Zcmt
|v1.0.0-RC5.2| Adjust the split so we have 240 cm.jalt and 16 cm.jt
|v1.0.0-RC5.1| Make cm.jt/cm.jalt only valid if JVT.mode=0, and allow different behaviour in the future if JVT.mode>0
|v1.0.0-RC5| Revert to cm.jt and cm.jalt encodings, to avoid toolchain and trace problems
|v1.0.0-RC4.1| Resolve typographical issues with the document only, no actual changes
|v1.0.0-RC4| Release candidate
|         | Remove Zcmb as benefit is low. Remove cm.jalt, read LSB of jump table entry to determine whether to link
|v0.70.5  | Resolve https://github.com/riscv/riscv-code-size-reduction/issues/163 - jvt.base is WARL and fewer bits than the max can be implemented
|v0.70.4  | Clarified https://github.com/riscv/riscv-code-size-reduction/issues/159 - Need Zbb and Zba for RV64 and M/ZMmul to get _all_ of Zcb
|         | Resolved https://github.com/riscv/riscv-code-size-reduction/issues/161
|         | Resolved https://github.com/riscv/riscv-code-size-reduction/issues/160 - Allocated Smstateen bit 2 and added the relevant text
|v0.70.3  | Added rule that Zcf and Zcmt imply Zca (this text was missing, this is not a spec change: https://github.com/riscv/riscv-code-size-reduction/pull/151)
|         | Added that Zcf is illegal for RV64, as it contains no instructions (clarification: https://github.com/riscv/riscv-code-size-reduction/issues/149)
|         | Added push/pop examples in the push/pop section
|v0.70.2  | Stylistic changes only, removing redundant text. 
|         | Corrected field names on JVT CSR diagram, and fixed synopsis for cm.mvsa01
|====================================================================================

=== Zc* Overview

This document is in the Frozen state. Change is extremely unlikely. A high threshold will be used, and a change will only occur because of some truly critical issue being identified during the public review cycle. Any other desired or needed changes can be the subject of a follow-on new extension. See https://riscv.org/spec-state

Zc* is a group of extensions which define subsets of the existing C extension (Zca, Zcd, Zcf) and new extensions which only contain 16-bit encodings.

Zcm* all reuse the encodings for _c.fld_, _c.fsd_, _c.fldsp_, _c.fsdsp_.

.Zc* extension overview
[width="100%",options=header,cols="3,1,1,1,1,1,1"]
|====================================================================================
|Instruction    |Zca     |Zcf     |Zcd     |Zcb     |Zcmp    |Zcmt
7+|*The Zca extension is added as way to refer to instructions in the C extension that do not include the floating-point loads and stores*
|C excl. c.f*   |yes     |        |        |        |        |         
7+|*The Zcf extension is added as a way to refer to compressed single-precision floating-point load/stores*
|c.flw          |        |yes     |        |        |        |       
|c.flwsp        |        |yes     |        |        |        |       
|c.fsw          |        |yes     |        |        |        |       
|c.fswsp        |        |yes     |        |        |        |       
7+|*The Zcd extension is added as a way to refer to compressed double-precision floating-point load/stores*
|c.fld          |        |        |yes     |        |        |       
|c.fldsp        |        |        |yes     |        |        |       
|c.fsd          |        |        |yes     |        |        |       
|c.fsdsp        |        |        |yes     |        |        |       
7+|*Simple operations for use on all architectures*
|c.lbu          |        |        |        |yes     |        |    
|c.lh           |        |        |        |yes     |        |    
|c.lhu          |        |        |        |yes     |        |    
|c.sb           |        |        |        |yes     |        |    
|c.sh           |        |        |        |yes     |        |    
|c.zext.b       |        |        |        |yes     |        |    
|c.sext.b       |        |        |        |yes     |        |    
|c.zext.h       |        |        |        |yes     |        |    
|c.sext.h       |        |        |        |yes     |        |    
|c.zext.w       |        |        |        |yes     |        |    
|c.mul          |        |        |        |yes     |        |    
|c.not          |        |        |        |yes     |        |    
7+|*PUSH/POP and double move which overlap with _c.fsdsp_*
|cm.push        |        |        |        |        |yes     |
|cm.pop         |        |        |        |        |yes     |
|cm.popret      |        |        |        |        |yes     |
|cm.popretz     |        |        |        |        |yes     |
|cm.mva01s      |        |        |        |        |yes     |
|cm.mvsa01      |        |        |        |        |yes     |
7+|*Table jump*              
|cm.jt          |        |        |        |        |        |yes     
|cm.jalt        |        |        |        |        |        |yes     
|====================================================================================

[#Zca]
=== Zca

The Zca extension is added as way to refer to instructions in the C extension that do not include the floating-point loads and stores.

Therefore it _excluded_ all 16-bit floating point loads and stores: _c.flw_, _c.flwsp_, _c.fsw_, _c.fswsp_, _c.fld_, _c.fldsp_, _c.fsd_, _c.fsdsp_.

NOTE: the the C extension only includes F/D instructions when D and F are also specified

[#Zcf]
=== Zcf (RV32 only)

Zcf is the existing set of compressed single precision floating point loads and stores: _c.flw_, _c.flwsp_, _c.fsw_, _c.fswsp_.

Zcf is only relevant to RV32, it cannot be specified for RV64.

The Zcf extension depends on the <<Zca>> extension.

[#Zcd]
=== Zcd 

Zcd is the existing set of compressed double precision floating point loads and stores: _c.fld_, _c.fldsp_, _c.fsd_, _c.fsdsp_.

The Zcd extension depends on the <<Zca>> extension.

[#Zcb]
=== Zcb

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.

The _c.mul_ encoding uses the CR register format along with other instructions such as _c.sub_, _c.xor_ etc. 

[NOTE]

  _c.sext.w_ is a pseudo-instruction for _c.addiw rd, 0_ (RV64)

[%header,cols="^1,^1,4,8"]
|===
|RV32
|RV64
|Mnemonic
|Instruction

|yes     
|yes     
|c.lbu _rd'_, uimm(_rs1'_)
|<<#insns-c_lbu>>

|yes     
|yes     
|c.lhu _rd'_, uimm(_rs1'_)
|<<#insns-c_lhu>>

|yes     
|yes     
|c.lh _rd'_, uimm(_rs1'_)
|<<#insns-c_lh>>

|yes     
|yes     
|c.sb _rs2'_, uimm(_rs1'_)
|<<#insns-c_sb>>

|yes     
|yes     
|c.sh _rs2'_, uimm(_rs1'_)
|<<#insns-c_sh>>

|yes     
|yes     
|c.zext.b _rsd'_
|<<#insns-c_zext_b>> 

|yes     
|yes     
|c.sext.b _rsd'_
|<<#insns-c_sext_b>> 

|yes     
|yes     
|c.zext.h _rsd'_
|<<#insns-c_zext_h>> 

|yes     
|yes     
|c.sext.h _rsd'_
|<<#insns-c_sext_h>> 

|
|yes     
|c.zext.w _rsd'_
|<<#insns-c_zext_w>> 

|yes     
|yes     
|c.not _rsd'_
|<<#insns-c_not>> 

|yes     
|yes     
|c.mul _rsd'_, _rs2'_
|<<#insns-c_mul>> 

|===

<<< 

[#Zcmp]
=== Zcmp

The Zcmp 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 <<Zcd>>,
 which is included when C and D extensions are both present. 

The Zcmp extension depends on the <<Zca>> extension.

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     
|cm.push _{reg_list}, -stack_adj_
|<<#insns-cm_push>> 

|yes     
|yes     
|cm.pop _{reg_list}, stack_adj_
|<<#insns-cm_pop>> 

|yes     
|yes     
|cm.popret _{reg_list}, stack_adj_
|<<#insns-cm_popret>> 

|yes     
|yes     
|cm.popretz _{reg_list}, stack_adj_
|<<#insns-cm_popretz>> 

|yes     
|yes     
|cm.mva01s _sreg1, sreg2_
|<<#insns-cm_mva01s>> 

|yes     
|yes     
|cm.mvsa01 _sreg1, sreg2_
|<<#insns-cm_mvsa01>> 

|===

<<<

[#Zcmt]
=== Zcmt

Zcmt adds the table jump instructions and also adds the JVT CSR. The JVT CSR requires a 
state enable if Smstateen is implemented. See <<csrs-jvt>> for details.

This extension reuses some encodings from _c.fsdsp_.  Therefore it is _incompatible_ with <<Zcd>>,
 which is included when C and D extensions are both present. 

The Zcmt extension depends on the <<Zca>> and Zicsr extensions.

[%header,cols="^1,^1,4,8"]
|===
|RV32
|RV64
|Mnemonic
|Instruction

|yes     
|yes     
|cm.jt _index_
|<<#insns-cm_jt>> 

|yes     
|yes     
|cm.jalt _index_
|<<#insns-cm_jalt>> 

|===

include::c_lbu.adoc[]
include::c_lhu.adoc[]
include::c_lh.adoc[]
include::c_sb.adoc[]
include::c_sh.adoc[]

include::c_zext_b.adoc[]
include::c_sext_b.adoc[]
include::c_zext_h.adoc[]
include::c_sext_h.adoc[]
include::c_zext_w.adoc[]
include::c_not.adoc[]
include::c_mul.adoc[]

include::pushpop.adoc[]
include::cm_push.adoc[]
include::cm_pop.adoc[]
include::cm_popretz.adoc[]
include::cm_popret.adoc[]
include::cm_mvsa01.adoc[]
include::cm_mva01s.adoc[]

include::tablejump.adoc[]
include::jvt_csr.adoc[]
include::cm_jt.adoc[]
include::cm_jalt.adoc[]

