[#Zc]
== Zc* v0.70.5

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

.Change history
[width="100%",options=header]
|====================================================================================
|Version | change
|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 Stable state. Assume anything could still change, but limited change should be expected. For more information see:
https://riscv.org/spec-state

Zc* is a group of extensions which define subsets of the existing C extension (Zca, 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]
|====================================================================================
|Instruction    |Zca|Zcf|Zcb|Zcmb|Zcmp|Zcmpe|Zcmt
8+|*Define a subset of C with the floating point load/stores removed*
|C excl. c.f*   |&#10003;|   |   |    |    |     |     
8+|*The single precision floating point load/stores become a separate extension*
|c.flw          |   |&#10003;|   |    |    |     |     
|c.flwsp        |   |&#10003;|   |    |    |     |     
|c.fsw          |   |&#10003;|   |    |    |     |     
|c.fswsp        |   |&#10003;|   |    |    |     |     
8+|*Simple operations for use on all architectures*
|c.lbu          |   |   |&#10003;|    |    |     |     
|c.lh           |   |   |&#10003;|    |    |     |     
|c.lhu          |   |   |&#10003;|    |    |     |     
|c.sb           |   |   |&#10003;|    |    |     |     
|c.sh           |   |   |&#10003;|    |    |     |     
|c.zext.b       |   |   |&#10003;|    |    |     |     
|c.sext.b       |   |   |&#10003;|    |    |     |     
|c.zext.h       |   |   |&#10003;|    |    |     |     
|c.sext.h       |   |   |&#10003;|    |    |     |     
|c.zext.w       |   |   |&#10003;|    |    |     |     
|c.mul          |   |   |&#10003;|    |    |     |     
|c.not          |   |   |&#10003;|    |    |     |     
8+|*Load/store byte/half which overlap with _c.fld_, _c.fldsp_, _c.fsd_*
|cm.lb          |   |   |   |&#10003; |    |     |     
|cm.lbu         |   |   |   |&#10003; |    |     |     
|cm.lh          |   |   |   |&#10003; |    |     |     
|cm.lhu         |   |   |   |&#10003; |    |     |     
|cm.sb          |   |   |   |&#10003; |    |     |     
|cm.sh          |   |   |   |&#10003; |    |     |     
8+|*PUSH/POP and double move which overlap with _c.fsdsp_*
|cm.push        |   |   |   |    |&#10003; | &#10003; |     
|cm.pop         |   |   |   |    |&#10003; | &#10003; |     
|cm.popret      |   |   |   |    |&#10003; | &#10003; |     
|cm.popretz     |   |   |   |    |&#10003; | &#10003; |     
|cm.mva01s      |   |   |   |    |&#10003; |     |     
|cm.mvsa01      |   |   |   |    |&#10003; |     |     
8+|*Reserved for EABI versions of PUSH/POP and double move which overlap with _c.fsdsp_*
|cm.push.e      |   |   |   |    |    | &#10003; |     
|cm.pop.e       |   |   |   |    |    | &#10003; |     
|cm.popret.e    |   |   |   |    |    | &#10003; |     
|cm.popretz.e   |   |   |   |    |    | &#10003; |     
|cm.mva01s.e    |   |   |   |    |    | &#10003; |     
|cm.mvsa01.e    |   |   |   |    |    | &#10003; |     
8+|*Table jump*
|cm.jt          |   |   |   |    |    |     |&#10003;  
|cm.jalt        |   |   |   |    |    |     |&#10003;  
|====================================================================================

[#Zca]
=== Zca

Zca is all of the existing C extension, _excluding_ all 16-bit floating point loads and stores: _c.flw_, _c.flwsp_, _c.fsw_, _c.fswsp_, _c.fld_, _c.fldsp_, _c.fsd_, _c.fsdsp_.

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

Zcf is the existing set of 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.

Zcf requires the <<Zca>> extension.

<<<

[#Zcb]
=== Zcb

All proposed encodings are currently reserved for all architectures, and have no conflicts with any existing extensions.

Zcb requires 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

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

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

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

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

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

|&#10003;
|&#10003;
|c.zext.b _rsd'_
|<<#insns-c_zext_b>> 

|&#10003;
|&#10003;
|c.sext.b _rsd'_
|<<#insns-c_sext_b>> 

|&#10003;
|&#10003;
|c.zext.h _rsd'_
|<<#insns-c_zext_h>> 

|&#10003;
|&#10003;
|c.sext.h _rsd'_
|<<#insns-c_sext_h>> 

|
|&#10003;
|c.zext.w _rsd'_
|<<#insns-c_zext_w>> 

|&#10003;
|&#10003;
|c.not _rsd'_
|<<#insns-c_not>> 

|&#10003;
|&#10003;
|c.mul _rsd'_, _rs2'_
|<<#insns-c_mul>> 

|===

<<< 

[#Zcmb]
=== Zcmb

This extension reuses some encodings from _c.fld_, _c.fldsp_, and _c.fsd_.  Therefore it is _incompatible_ with the full C-extension. 
It is compatible with F, D with Zdinx.

Zcmb requires the <<Zcb>> extension, which in turn requires the <<Zca>> extension.

The instructions are all 16-bit versions of existing 32-bit load/store instructions.

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

|&#10003;
|&#10003;
|cm.lbu _rd'_, uimm(_rs1'_)
|<<#insns-cm_lbu>>

|&#10003;
|&#10003;
|cm.lhu _rd'_, uimm(_rs1'_)
|<<#insns-cm_lhu>>

|&#10003;
|&#10003;
|cm.lb _rd'_, uimm(_rs1'_)
|<<#insns-cm_lb>>

|&#10003;
|&#10003;
|cm.lh _rd'_, uimm(_rs1'_)
|<<#insns-cm_lh>>

|&#10003;
|&#10003;
|cm.sb _rs2'_, uimm(_rs1'_)
|<<#insns-cm_sb>>

|&#10003;
|&#10003;
|cm.sh _rs2'_, uimm(_rs1'_)
|<<#insns-cm_sh>>

|===

<<<

[#Zcmp]
=== Zcmp

Zcmp is the set of sequenced instuctions for code-size reduction.

This extension reuses some encodings from _c.fsdsp_.  Therefore it is _incompatible_ with the full C-extension. 
It is compatible with F, D with Zdinx.

Zcmp requires 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

|&#10003;
|&#10003;
|cm.push _{reg_list}, -stack_adj_
|<<#insns-cm_push>> 

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

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

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

|&#10003;
|&#10003;
|cm.mva01s _sreg1, sreg2_
|<<#insns-cm_mva01s>> 

|&#10003;
|&#10003;
|cm.mvsa01 _sreg1, sreg2_
|<<#insns-cm_mvsa01>> 

|===

<<<

[#Zcmpe]
=== Zcmpe

This extension reuses some encodings from _c.fsdsp_.  Therefore it is _incompatible_ with the full C-extension. 
It is compatible with F, D with Zdinx.

Zcmpe requires the <<Zca>> extension.

Zcmpe offers EABI support for register mappings from <<Zcmp>> where the _x_ register mapping is different to the UABI. 

[NOTE]

  The EABI specification is not frozen so these instructions cannot yet be accurately specified.

[#Zcmt]
=== Zcmt

This extension reuses some encodings from _c.fsdsp_.  Therefore it is _incompatible_ with the full C-extension. 
It is compatible with F, D with Zdinx.

Zcmt is the set of table jump instuctions for code-size reduction, and also adds the JVT CSR. The JVT CSR requires a 
state enable if Smstateen is implemented. See <<csrs-jvt>> for details.

Zcmt requires the <<Zca>> extension.

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

|&#10003;
|&#10003;
|cm.jt _index_
|<<#insns-cm_jt>> 

|&#10003;
|&#10003;
|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::cm_lbu.adoc[]
include::cm_lhu.adoc[]
include::cm_lb.adoc[]
include::cm_lh.adoc[]
include::cm_sb.adoc[]
include::cm_sh.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[]

