# 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 ] |