Skip to content

Latest commit

 

History

History
629 lines (588 loc) · 67.4 KB

File metadata and controls

629 lines (588 loc) · 67.4 KB

# CORE-V Extensions According to Manual

## All Extension Subsets

### Postmod Load and Store

Matches PULP_POSTMOD and PULP_INDREGREG

Mnemonic Description
Register-Immediate Loads with Post-Increment  
cv.lb rD, Imm(rs1!)

rD = Sext(Mem8(rs1))

rs1 += Imm[11:0]

cv.lbu rD, Imm(rs1!)

rD = Zext(Mem8(rs1))

rs1 += Imm[11:0]

cv.lh rD, Imm(rs1!)

rD = Sext(Mem16(rs1))

rs1 += Imm[11:0]

cv.lhu rD, Imm(rs1!)

rD = Zext(Mem16(rs1))

rs1 += Imm[11:0]

cv.lw rD, Imm(rs1!)

rD = Mem32(rs1)

rs1 += Imm[11:0]

Register-Register Loads with Post-Increment  
cv.lb rD, rs2(rs1!)

rD = Sext(Mem8(rs1))

rs1 += rs2

cv.lbu rD, rs2(rs1!)

rD = Zext(Mem8(rs1))

rs1 += rs2

cv.lh rD, rs2(rs1!)

rD = Sext(Mem16(rs1))

rs1 += rs2

cv.lhu rD, rs2(rs1!)

rD = Zext(Mem16(rs1))

rs1 += rs2

cv.lw rD, rs2(rs1!)

rD = Mem32(rs1)

rs1 += rs2

Register-Register Loads  
cv.lb rD, rs2(rs1) rD = Sext(Mem8(rs1 + rs2))
cv.lbu rD, rs2(rs1) rD = Zext(Mem8(rs1 + rs2))
cv.lh rD, rs2(rs1) rD = Sext(Mem16(rs1 + rs2))
cv.lhu rD, rs2(rs1) rD = Zext(Mem16(rs1 + rs2))
cv.lw rD, rs2(rs1) rD = Mem32(rs1 + rs2)
Mnemonic Description
Register-Immediate Stores with Post-Increment  
cv.sb rs2, Imm(rs1!)

Mem8(rs1) = rs2

rs1 += Imm[11:0]

cv.sh rs2, Imm(rs1!)

Mem16(rs1) = rs2

rs1 += Imm[11:0]

cv.sw rs2, Imm(rs1!)

Mem32(rs1) = rs2

rs1 += Imm[11:0]

Register-Register Stores with Post-Increment  
cv.sb rs2, rs3(rs1!)

Mem8(rs1) = rs2

rs1 += rs3

cv.sh rs2, rs3(rs1!)

Mem16(rs1) = rs2

rs1 += rs3

cv.sw rs2, rs3(rs1!)

Mem32(rs1) = rs2

rs1 += rs3

Register-Register Stores  
cv.sb rs2, rs3(rs1) Mem8(rs1 + rs3) = rs2
cv.sh rs2 rs3(rs1) Mem16(rs1 + rs3) = rs2
cv.sw rs2, rs3(rs1) Mem32(rs1 + rs3) = rs2

### Event Load Instructions Matches PULP_ELW

Mnemonic Description
Event Load  
cv.elw rD, Imm(rs1) rD = Mem32(Sext(Imm)+rs1)

### Hardware Loops

Matches PULP_HWLOO

Long Hardware Loop Setup instructions

Mnemonic Description  
cv.starti L, uimmL lpstart[L] = PC + (uimmL << 1)
cv.endi L, uimmL lpend[L] = PC + (uimmL << 1)
cv.count L, rs1 lpcount[L] = rs1
cv.counti L, uimmL lpcount[L] = uimmL

Short Hardware Loop Setup Instructions

Mnemonic Description  
cv.setup L, rs1, uimmL

lpstart[L] = pc + 4

lpend[L] = pc + (uimmL << 1)

lpcount[L] = rs1

cv.setupi L, uimmL, uimmS

lpstart[L] = pc + 4

lpend[L] = pc + (uimmS << 1)

lpcount[L] = uimmL

### Bit Manipulation

Matches PULP_BITOP`and `PULP_BITREV but PULP_BITOP also has p.exths/p.exthz and p.extbs/p.extbz

Mnemonic   Description
cv.extract rD, rs1, Is3, Is2 rD = Sext(rs1[min(Is3+Is2,31):Is2])
cv.extractu rD, rs1, Is3, Is2 rD = Zext(rs1[min(Is3+Is2,31):Is2])
cv.extractr rD, rs1, rs2 rD = Sext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]])
cv.extractur rD, rs1, rs2 rD = Zext(rs1[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]])
cv.insert rD, rs1, Is3, Is2 rD[min(Is3+Is2,31):Is2] = rs1[Is3:max(Is3+Is2,31)-31] the rest of the bits of rD are passed through and are not modified
cv.insertr rD, rs1, rs2 rD[min(rs2[9:5]+rs2[4:0],31):rs2[4:0]] = rs1[rs2[9:5]:max(rs2[9:5]+rs2[4:0],31)-31] the rest of the bits of rD are passed through and are not modified
cv.bclr rD, rs1, Is3, Is2 rD = (rs1 & ~(((1<<Is3)-1)<<Is2))
cv.bclrr rD, rs1, rs2 rD = (rs1 & ~(((1<<rs2[9:5])-1)<<rs2[4:0]))
cv.bset rD, rs1, Is3, Is2 rD = (rs1 | (((1<<Is3)-1)<<Is2))
cv.bsetr rD, rs1, rs2 rD = (rs1 | (((1<<rs2[9:5])-1)<<rs2[4:0]))
cv.ff1 rD, rs1 rD = bit position of the first bit set in rs1, starting from LSB. If bit 0 is set, rD will be 0. If only bit 31 is set, rD will be 31. If rs1 is 0, rD will be 32.
cv.fl1 rD, rs1 rD = bit position of the last bit set in rs1, starting from MSB. If bit 31 is set, rD will be 31. If only bit 0 is set, rD will be 0. If rs1 is 0, rD will be 32.
cv.clb rD, rs1 rD = count leading bits of rs1 Note: This is the number of consecutive 1’s or 0’s from MSB. Note: If rs1 is 0, rD will be 0.
cv.cnt rD, rs1 rD = Population count of rs1, i.e. number of bits set in rs1
cv.ror rD, rs1, rs2 rD = RotateRight(rs1, rs2)
cv.bitrev rD, rs1, Is3, Is2

Given an input rs1 it returns a bit reversed representation assuming

FFT on 2^Is2 points in Radix 2^(Is3+1)

Note: Is3 can be either 0 (radix-2), 1 (radix-4) or 2 (radix-8)

### General ALU Operations

Matches PULP_ABS, PULP_SLET, PULP_MINMAX, parts of PULP_BITOP, PULP_CLIP and PULP_ADDSUBRN

Mnemonic   Description
cv.abs rD, rs1 rD = rs1 < 0 ? –rs1 : rs1
cv.slet rD, rs1, rs2 rD = rs1 <= rs2 ? 1 : 0 Note: Comparison is signed
cv.sletu rD, rs1, rs2 rD = rs1 <= rs2 ? 1 : 0 Note: Comparison is unsigned
cv.min rD, rs1, rs2 rD = rs1 < rs2 ? rs1 : rs2 Note: Comparison is signed
cv.minu rD, rs1, rs2 rD = rs1 < rs2 ? rs1 : rs2 Note: Comparison is unsigned
cv.max rD, rs1, rs2 rD = rs1 < rs2 ? rs2 : rs1 Note: Comparison is signed
cv.maxu rD, rs1, rs2 rD = rs1 < rs2 ? rs2 : rs1 Note: Comparison is unsigned
cv.exths rD, rs1 rD = Sext(rs1[15:0])
cv.exthz rD, rs1 rD = Zext(rs1[15:0])
cv.extbs rD, rs1 rD = Sext(rs1[7:0])
cv.extbz rD, rs1 rD = Zext(rs1[7:0])
cv.clip rD, rs1, Is2

if rs1 <= -2^(Is2-1), rD = -2^(Is2-1),

else if rs1 >= 2^(Is2-1)–1, rD = 2^(Is2-1)-1,

else rD = rs1

Note: If ls2 is equal to 0, -2^(Is2-1)= -1 while (2^(Is2-1)-1)=0;

cv.clipr rD, rs1, rs2

if rs1 <= -(rs2+1), rD = -(rs2+1),

else if rs1 >=rs2, rD = rs2,

else rD = rs1

cv.clipu rD, rs1, Is2

if rs1 <= 0, rD = 0,

else if rs1 >= 2^(Is2–1)-1, rD = 2^(Is2-1)-1,

else rD = rs1

Note: If ls2 is equal to 0, (2^(Is2-1)-1)=0;

cv.clipur rD, rs1, rs2

if rs1 <= 0, rD = 0,

else if rs1 >= rs2, rD = rs2,

else rD = rs1

cv.addN rD, rs1, rs2, Is3 rD = (rs1 + rs2) >>> Is3 Note: Arithmetic shift right. Setting Is3 to 2 replaces former p.avg
cv.adduN rD, rs1, rs2, Is3 rD = (rs1 + rs2) >> Is3 Note: Logical shift right. Setting Is3 to 2 replaces former p.avg
cv.addRN rD, rs1, rs2, Is3 rD = (rs1 + rs2 + 2^(Is3-1)) >>> Is3 Note: Arithmetic shift right.
cv.adduRN rD, rs1, rs2, Is3 rD = (rs1 + rs2 + 2^(Is3-1))) >> Is3 Note: Logical shift right.
cv.addNr rD, rs1, rs2 rD = (rD + rs1) >>> rs2[4:0] Note: Arithmetic shift right.
cv.adduNr rD, rs1, rs2 rD = (rD + rs1) >> rs2[4:0] Note: Logical shift right.
cv.addRNr rD, rs1, rs2 rD = (rD + rs1 + 2^(rs2[4:0]-1)) >>> rs2[4:0] Note: Arithmetic shift right.
cv.adduRNr rD, rs1, rs2 rD = (rD + rs1 + 2^(rs2[4:0]-1))) >> rs2[4:0] Note: Logical shift right.
cv.subN rD, rs1, rs2, Is3 rD = (rs1 - rs2) >>> Is3 Note: Arithmetic shift right.
cv.subuN rD, rs1, rs2, Is3 rD = (rs1 - rs2) >> Is3 Note: Logical shift right.
cv.subRN rD, rs1, rs2, Is3 rD = (rs1 - rs2 + 2^(Is3-1)) >>> Is3 Note: Arithmetic shift right.
cv.subuRN rD, rs1, rs2, Is3 rD = (rs1 - rs2 + 2^(Is3-1))) >> Is3 Note: Logical shift right.
cv.subNr rD, rs1, rs2 rD = (rD – rs1) >>> rs2[4:0] Note: Arithmetic shift right.
cv.subuNr rD, rs1, rs2 rD = (rD – rs1) >> rs2[4:0] Note: Logical shift right.
cv.subRNr rD, rs1, rs2 rD = (rD – rs1+ 2^(rs2[4:0]-1)) >>> rs2[4:0] Note: Arithmetic shift right.
cv.subuRNr rD, rs1, rs2 rD = (rD – rs1+ 2^(rs2[4:0]-1))) >> rs2[4:0] Note: Logical shift right.

### Immediate Branching Instructions

Matches PULP_BR +---------------------------------+------------------------------------------------------------------------+ | Mnemonic | Description | +=================================+========================================================================+ | cv.beqimm rs1, Imm5, Imm12 | Branch to PC + (Imm12 << 1) if rs1 is equal to Imm5. Imm5 is signed. | +---------------------------------+------------------------------------------------------------------------+ | cv.bneimm rs1, Imm5, Imm12 | Branch to PC + (Imm12 << 1) if rs1 is not equal to Imm5. | | | Imm5 is signed. | +---------------------------------+------------------------------------------------------------------------+

### MAC Instructions Matches PULP_MAC_SI, PULP_MULRN_HI and PULP_MACRN_HI. Note that PULP_PARTMAC is not supported by the the cv32e40p.

32-Bit x 32-Bit Multiplication Operations

Mnemonic Description  
cv.mac rD, rs1, rs2 rD = rD + rs1 * rs2
cv.msu rD, rs1, rs2 rD = rD - rs1 * rs2

16-Bit x 16-Bit Multiplication

Mnemonic Description  
cv.muls rD, rs1, rs2 rD[31:0] = Sext(rs1[15:0]) * Sext(rs2[15:0])
cv.mulhhs rD, rs1, rs2 rD[31:0] = Sext(rs1[31:16]) * Sext(rs2[31:16])
cv.mulsN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0])) >>> Is3 Note: Arithmetic shift right
cv.mulhhsN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16])) >>> Is3 Note: Arithmetic shift right
cv.mulsRN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0]) + 2^(Is3-1)) >>> Is3 Note: Arithmetic shift right
cv.mulhhsRN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16]) + 2^(Is3-1)) >>> Is3 Note: Arithmetic shift right
cv.mulu rD, rs1, rs2 rD[31:0] = Zext(rs1[15:0]) * Zext(rs2[15:0])
cv.mulhhu rD, rs1, rs2 rD[31:0] = Zext(rs1[31:16]) * Zext(rs2[31:16])
cv.muluN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0])) >> Is3 Note: Logical shift right
cv.mulhhuN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16])) >> Is3 Note: Logical shift right
cv.muluRN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0]) + 2^(Is3-1)) >> Is3 Note: Logical shift right
cv.mulhhuRN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16]) + 2^(Is3-1)) >> Is3 Note: Logical shift right

16-Bit x 16-Bit Multiply-Accumulate

Mnemonic Description  
cv.macsN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0]) + rD) >>> Is3 Note: Arithmetic shift right
cv.machhsN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16]) + rD) >>> Is3 Note: Arithmetic shift right
cv.macsRN rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[15:0]) * Sext(rs2[15:0]) + rD + 2^(Is3-1)) >>> Is3 Note: Arithmetic shift right
cv.machhsRN , rD, rs1, rs2, Is3 rD[31:0] = (Sext(rs1[31:16]) * Sext(rs2[31:16]) + rD + 2^(Is3-1)) >>> Is3 Note: Arithmetic shift right
cv.macuN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0]) + rD) >> Is3 Note: Logical shift right
cv.machhuN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16]) + rD) >> Is3 Note: Logical shift right
cv.macuRN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[15:0]) * Zext(rs2[15:0]) + rD + 2^(Is3-1)) >> Is3 Note: Logical shift right
cv.machhuRN rD, rs1, rs2, Is3 rD[31:0] = (Zext(rs1[31:16]) * Zext(rs2[31:16]) + rD + 2^(Is3-1)) >> Is3 Note: Logical shift right

### SIMD (vector)

Matches PULP_VECT and PULP_VECT_SHUFFLEPACK

SIMD ALU Operations

Mnemonic Description
cv.add[.sc,.sci]{.h,.b} rD[i] = (rs1[i] + op2[i]) & 0xFFFF
cv.add{.div2,.div4, .div8} rD[i] = ((rs1[i] + op2[i]) & 0xFFFF)>>{1,2,3}
cv.sub[.sc,.sci]{.h,.b} rD[i] = (rs1[i] - op2[i]) & 0xFFFF
cv.sub{.div2,.div4, .div8} rD[i] = ((rs1[i] – op2[i]) & 0xFFFF)>>{1,2,3}
cv.avg[.sc,.sci]{.h,.b} rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1 Note: Arithmetic right shift
cv.avgu[.sc,.sci]{.h,.b} rD[i] = ((rs1[i] + op2[i]) & {0xFFFF, 0xFF}) >> 1
cv.min[.sc,.sci]{.h,.b} rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i]
cv.minu[.sc,.sci]{.h,.b} rD[i] = rs1[i] < op2[i] ? rs1[i] : op2[i] Note: Immediate is zero-extended, comparison is unsigned
cv.max[.sc,.sci]{.h,.b} rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i]
cv.maxu[.sc,.sci]{.h,.b} rD[i] = rs1[i] > op2[i] ? rs1[i] : op2[i] Note: Immediate is zero-extended, comparison is unsigned
cv.srl[.sc,.sci]{.h,.b} rD[i] = rs1[i] >> op2[i] Note: Immediate is zero-extended, shift is logical
cv.sra[.sc,.sci]{.h,.b} rD[i] = rs1[i] >>> op2[i] Note: Immediate is zero-extended, shift is arithmetic
cv.sll[.sc,.sci]{.h,.b} rD[i] = rs1[i] << op2[i] Note: Immediate is zero-extended, shift is logical
cv.or[.sc,.sci]{.h,.b} rD[i] = rs1[i] | op2[i]
cv.xor[.sc,.sci]{.h,.b} rD[i] = rs1[i] ^ op2[i]
cv.and[.sc,.sci]{.h,.b} rD[i] = rs1[i] & op2[i]
cv.abs{.h,.b} rD[i] = rs1 < 0 ? –rs1 : rs1
cv.extract.h rD = Sext(rs1[((I+1)*16)-1 : I*16])
cv.extract.b rD = Sext(rs1[((I+1)*8)-1 : I*8])
cv.extractu.h rD = Zext(rs1[((I+1)*16)-1 : I*16])
cv.extractu.b rD = Zext(rs1[((I+1)*8)-1 : I*8])
cv.insert.h rD[((I+1)*16-1:I*16] = rs1[15:0] Note: The rest of the bits of rD are untouched and keep their previous value
cv.insert,b rD[((I+1)*8-1:I*8] = rs1[7:0] Note: The rest of the bits of rD are untouched and keep their previous value

Dot Product Instructions

Mnemonic Description
cv.dotup[.sc,.sci].h rD = rs1[0] * op2[0] + rs1[1] * op2[1] Note: All operations are unsigned
cv.dotup[.sc,.sci].b rD = rs1[0] * op2[0] + rs1[1] * op2[1] + rs1[2] * op2[2] + rs1[3] * op2[3] Note: All operations are unsigned
cv.dotusp[.sc,.sci].h rD = rs1[0] * op2[0] + rs1[1] * op2[1] Note: rs1 is treated as unsigned, while rs2 is treated as signed
cv.dotusp[.sc,.sci].b rD = rs1[0] * op2[0] + rs1[1] * op2[1] + rs1[2] * op2[2] + rs1[3] * op2[3] Note: rs1 is treated as unsigned, while rs2 is treated as signed
cv.dotsp[.sc,.sci].h rD = rs1[0] * op2[0] + rs1[1] * op2[1] Note: All operations are signed
cv.dotsp[.sc,.sci].b rD = rs1[0] * op2[0] + rs1[1] * op2[1] + rs1[2] * op2[2] + rs1[3] * op2[3] Note: All operations are signed
cv.sdotup[.sc,.sci].h rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] Note: All operations are unsigned
cv.sdotup[.sc,.sci].b rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] + rs1[2] * op2[2] + rs1[3] * op2[3] Note: All operations are unsigned
cv.sdotusp[.sc,.sci].h rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] Note: rs1 is treated as unsigned, while rs2 is treated as signed
cv.sdotusp[.sc,.sci].b rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] + rs1[2] * op2[2] + rs1[3] * op2[3] Note: rs1 is treated as unsigned, while rs2 is treated as signed
cv.sdotsp[.sc,.sci].h rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] Note: All operations are signed
cv.sdotsp[.sc,.sci].b rD = rD + rs1[0] * op2[0] + rs1[1] * op2[1] + rs1[2] * op2[2] + rs1[3] * op2[3] Note: All operations are signed

Shuffle and Pack Instructions

Mnemonic Description
cv.shuffle.h rD[31:16] = rs1[rs2[16]*16+15:rs2[16]*16] rD[15:0] = rs1[rs2[0]*16+15:rs2[0]*16]
cv.shuffle.sci.h rD[31:16] = rs1[I1*16+15:I1*16] rD[15:0] = rs1[I0*16+15:I0*16] Note: I1 and I0 represent bits 1 and 0 of the immediate
cv.shuffle.b rD[31:24] = rs1[rs2[25:24]*8+7:rs2[25:24]*8] rD[23:16] = rs1[rs2[17:16]*8+7:rs2[17:16]*8] rD[15:8] = rs1[rs2[9:8]*8+7:rs2[9:8]*8] rD[7:0] = rs1[rs2[1:0]*8+7:rs2[1:0]*8]
cv.shuffleI0.sci.b rD[31:24] = rs1[7:0] rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8] rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8] rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]
cv.shuffleI1.sci.b rD[31:24] = rs1[15:8] rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8] rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8] rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]
cv.shuffleI2.sci.b rD[31:24] = rs1[23:16] rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8] rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8] rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]
cv.shuffleI3.sci.b rD[31:24] = rs1[31:24] rD[23:16] = rs1[(I5:I4)*8+7: (I5:I4)*8] rD[15:8] = rs1[(I3:I2)*8+7: (I3:I2)*8] rD[7:0] = rs1[(I1:I0)*8+7:(I1:I0)*8]
cv.shuffle2.h rD[31:16] = ((rs2[17] == 1) ? rs1 : rD)[rs2[16]*16+15:rs2[16]*16] rD[15:0] = ((rs2[1] == 1) ? rs1 : rD)[rs2[0]*16+15:rs2[0]*16]
cv.shuffle2.b rD[31:24] = ((rs2[26] == 1) ? rs1 : rD)[rs2[25:24]*8+7:rs2[25:24]*8] rD[23:16] = ((rs2[18] == 1) ? rs1 : rD)[rs2[17:16]*8+7:rs2[17:16]*8] rD[15:8] = ((rs2[10] == 1) ? rs1 : rD)[rs2[9:8]*8+7:rs2[9:8]*8] rD[7:0] = ((rs2[2] == 1) ? rs1 : rD)[rs2[1:0]*8+7:rs2[1:0]*8]
cv.pack rD[31:16] = rs1[15:0] rD[15:0] = rs2[15:0]
cv.pack.h rD[31:16] = rs1[31:16] rD[15:0] = rs2[31:16]
cv.packhi.b rD[31:24] = rs1[7:0] rD[23:16] = rs2[7:0] Note: The rest of the bits of rD are untouched and keep their previous value
cv.packlo.b rD[15:8] = rs1[7:0] rD[7:0] = rs2[7:0] Note: The rest of the bits of rD are untouched and keep their previous value

SIMD Comparison Operations

Mnemonic   Description
cv.cmpeq[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] == op2 ? ‘1 : ‘0
cv.cmpne[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] != op2 ? ‘1 : ‘0
cv.cmpgt[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] > op2 ? ‘1 : ‘0
cv.cmpge[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] >=op2 ? ‘1 : ‘0
cv.cmplt[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] < op2 ? ‘1 : ‘0
cv.cmple[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] <= op2 ? ‘1 : ‘0
cv.cmpgtu[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] > op2 ? ‘1 : ‘0 Note: Unsigned comparison
cv.cmpgeu[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] >= op2 ? ‘1 : ‘0 Note: Unsigned comparison
cv.cmpltu[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] < op2 ? ‘1 : ‘0 Note: Unsigned comparison
cv.cmpleu[.sc,.sci]{.h,.b} rD, rs1, {rs2, Imm6} rD[i] = rs1[i] <= op2 ? ‘1 : ‘0 Note: Unsigned comparison

SIMD Complex-number Operations

Mnemonic Description
cv.subrotmj{/,div2,div4,div8}

rD[0] = ((rs1[1] – rs2[1]) & 0xFFFF)>>{0,1,2,3}

rD[1] = ((rs2[0] – rs1[0]) & 0xFFFF)>>{0,1,2,3}

cv.cplxconj

rD[0] = rs1[0]

rD[1] = -rs1[1]

cv.cplxmul.r.{/,div2,div4,div8}

rD[15:0 ] = (rs1[0]*rs2[0] – rs1[1]*rs2[1])>>{15,16,17,18}

rD[31:16] = rD[31:16]

cv.cplxmul.i.{/,div2,div4,div8}

rD[31:16] = (rs1[0]*rs2[1] + rs1[1]*rs2[0])>>{15,16,17,18}

rD[15:0 ] = rD[15:0 ]