Skip to content
This repository has been archived by the owner on Mar 21, 2024. It is now read-only.

Latest commit

 

History

History
211 lines (167 loc) · 6.18 KB

zicondops.adoc

File metadata and controls

211 lines (167 loc) · 6.18 KB

Zicond specification

The "Conditional" operations extension provides a simple solution that provides most of the benefit and all of the flexibility one would desire to support conditional arithmetic and conditional-select/move operations, while remaining true to the RISC-V design philosophy. The instructions follow the format for R-type instructions with 3 operands (i.e., 2 source operands and 1 destination operand). Using these instructions, branchless sequences can be implemented (typically in two-instruction sequences) without the need for instruction fusion, special provisions during the decoding of architectural instructions, or other microarchitectural provisions.

The following instructions comprise the Zicond extension:

RV32 RV64 Mnemonic Instruction

czero.eqz rd, rs1, rs2

Conditional zero, if condition is equal to zero

czero.nez rd, rs1, rs2

Conditional zero, if condition is nonzero

Note

Architecture Comment: defining additional comparisons, in addition to equal-to-zero and not-equal-to-zero, does not offer a benefit due to the lack of immediates or an additional register operand that the comparison takes place against.

Based on these two instructions, synthetic instructions (i.e., short instruction sequences) for the following conditional arithmetic operations are supported:

  • conditional add, if zero

  • conditional add, if non-zero

  • conditional subtract, if zero

  • conditional subtract, if non-zero

  • conditional bitwise-and, if zero

  • conditional bitwise-and, if non-zero

  • conditional bitwise-or, if zero

  • conditional bitwise-or, if non-zero

  • conditional bitwise-xor, if zero

  • conditional bitwise-xor, if non-zero

Additionally, the following conditional select instructions are supported:

  • conditional-select, if zero

  • conditional-select, if non-zero

More complex conditions, such as comparisons against immediates, registers, single-bit tests, comparisons against ranges, etc. can be realized by composing these new instructions with existing instructions.

Instructions (in alphabetical order)

czero.eqz

Synopsis

Moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd.

Mnemonic

czero.eqz rd, rs1, rs2

Encoding
{reg:[
    { bits:  7, name: 0x33, attr: ['OP'] },
    { bits:  5, name: 'rd' },
    { bits:  3, name: 0x5, attr: ['CZERO.EQZ']},
    { bits:  5, name: 'rs1', attr: ['value'] },
    { bits:  5, name: 'rs2', attr: ['condition'] },
    { bits:  7, name: 0x7, attr: ['CZERO'] },
]}
Description

If rs2 contains the value zero, this instruction writes the value zero to rd. Otherwise, this instruction copies the contents of rs1 to rd.

This instruction carries a syntactic dependency from both rs1 and rs2 to rd. Furthermore, if the Zkt extension is implemented, this instruction’s timing is independent of the data values in rs1 and rs2.

SAIL code
  let condition = X(rs2);
  result : xlenbits = if (condition == zeros()) then zeros()
                                                else X(rs1);
  X(rd) = result;

czero.nez

Synopsis

Moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd.

Mnemonic

czero.nez rd, rs1, rs2

Encoding
{reg:[
    { bits:  7, name: 0x33, attr: ['OP'] },
    { bits:  5, name: 'rd' },
    { bits:  3, name: 0x7, attr: ['CZERO.NEZ']},
    { bits:  5, name: 'rs1', attr: ['value'] },
    { bits:  5, name: 'rs2', attr: ['condition'] },
    { bits:  7, name: 0x7, attr: ['CZERO'] },
]}
Description

If rs2 contains a nonzero value, this instruction writes the value zero to rd. Otherwise, this instruction copies the contents of rs1 to rd.

This instruction carries a syntactic dependency from both rs1 and rs2 to rd. Furthermore, if the Zkt extension is implemented, this instruction’s timing is independent of the data values in rs1 and rs2.

SAIL code
  let condition = X(rs2);
  result : xlenbits = if (condition != zeros()) then zeros()
                                                else X(rs1);
  X(rd) = result;

Usage examples

The instructions from this extension can be used to construct sequences that perform conditional-arithmetic, conditional-bitwise-logical, and conditional-select operations.

Instruction sequences

Operation Instruction sequence Length

Conditional add, if zero
rd = (rc == 0) ? (rs1 + rs2) : rs1

czero.nez  rd, rs2, rc
add        rd, rs1, rd

2 insns

Conditional add, if non-zero
rd = (rc != 0) ? (rs1 + rs2) : rs1

czero.eqz  rd, rs2, rc
add        rd, rs1, rd

Conditional subtract, if zero
rd = (rc == 0) ? (rs1 - rs2) : rs1

czero.nez  rd, rs2, rc
sub        rd, rs1, rd

Conditional subtract, if non-zero
rd = (rc != 0) ? (rs1 - rs2) : rs1

czero.eqz  rd, rs2, rc
sub        rd, rs1, rd

Conditional bitwise-or, if zero
rd = (rc == 0) ? (rs1 | rs2) : rs1

czero.nez  rd, rs2, rc
or         rd, rs1, rd

Conditional bitwise-or, if non-zero
rd = (rc != 0) ? (rs1 | rs2) : rs1

czero.eqz  rd, rs2, rc
or         rd, rs1, rd

Conditional bitwise-xor, if zero
rd = (rc == 0) ? (rs1 ^ rs2) : rs1

czero.nez  rd, rs2, rc
xor        rd, rs1, rd

Conditional bitwise-xor, if non-zero
rd = (rc != 0) ? (rs1 ^ rs2) : rs1

czero.eqz  rd, rs2, rc
xor        rd, rs1, rd

Conditional bitwise-and, if zero
rd = (rc == 0) ? (rs1 & rs2) : rs1

and        rd, rs1, rs2
czero.eqz  rtmp, rs1, rc
or         rd, rd, rtmp

3 insns
(requires 1 temporary)

Conditional bitwise-and, if non-zero
rd = (rc != 0) ? (rs1 & rs2) : rs1

and        rd, rs1, rs2
czero.nez  rtmp, rs1, rc
or         rd, rd, rtmp

Conditional select, if zero
rd = (rc == 0) ? rs1 : rs2

czero.nez  rd, rs1, rc
czero.eqz  rtmp, rs2, rc
or         rd, rd, rtmp

Conditional select, if non-zero
rd = (rc != 0) ? rs1 : rs2

czero.eqz  rd, rs1, rc
czero.nez  rtmp, rs2, rc
or         rd, rd, rtmp