# Signed MSW 32x32 Multiply and Add Instructions¶

`__STATIC_FORCEINLINE long __RV_KMMAC(long t, long a, long b)`
`__STATIC_FORCEINLINE long __RV_KMMAC_U(long t, long a, long b)`
`__STATIC_FORCEINLINE long __RV_KMMSB(long t, long a, long b)`
`__STATIC_FORCEINLINE long __RV_KMMSB_U(long t, long a, long b)`
`__STATIC_FORCEINLINE long __RV_KWMMUL(long a, long b)`
`__STATIC_FORCEINLINE long __RV_KWMMUL_U(long a, long b)`
`__STATIC_FORCEINLINE long __RV_SMMUL(long a, long b)`
`__STATIC_FORCEINLINE long __RV_SMMUL_U(long a, long b)`
group `NMSIS_Core_DSP_Intrinsic_SIGNED_MSW_32X32_MAC`

Signed MSW 32x32 Multiply and Add Instructions.

there are 8 Signed MSW 32x32 Multiply and Add Instructions

Functions

`__STATIC_FORCEINLINE long __RV_KMMAC(long t, long a, long b)`

KMMAC (SIMD Saturating MSW Signed Multiply Word and Add)

Type: SIMD

Syntax:

```KMMAC Rd, Rs1, Rs2
KMMAC.u Rd, Rs1, Rs2
```

Purpose:

Multiply the signed 32-bit integer elements of two registers and add the most significant 32-bit results with the signed 32-bit integer elements of a third register. The addition results are saturated first and then written back to the third register. The

`.u` form performs an additional rounding up operation on the multiplication results before adding the most significant 32-bit part of the results.

Description:

This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The

`.u` form of the instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results.

Operations:

```Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][32:0] = Mres[x][63:31] + 1;
res[x] = Rd.W[x] + Round[x][32:1];
} else {
res[x] = Rd.W[x] + Mres[x][63:32];
}
if (res[x] > (2^31)-1) {
res[x] = (2^31)-1;
OV = 1;
} else if (res[x] < -2^31) {
res[x] = -2^31;
OV = 1;
}
Rd.W[x] = res[x];
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] t`: long type of value stored in t

• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_KMMAC_U(long t, long a, long b)`

KMMAC.u (SIMD Saturating MSW Signed Multiply Word and Add with Rounding)

Type: SIMD

Syntax:

```KMMAC Rd, Rs1, Rs2
KMMAC.u Rd, Rs1, Rs2
```

Purpose:

Multiply the signed 32-bit integer elements of two registers and add the most significant 32-bit results with the signed 32-bit integer elements of a third register. The addition results are saturated first and then written back to the third register. The

`.u` form performs an additional rounding up operation on the multiplication results before adding the most significant 32-bit part of the results.

Description:

This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 and adds the most significant 32-bit multiplication results with the signed 32-bit elements of Rd. If the addition result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The

`.u` form of the instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results.

Operations:

```Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][32:0] = Mres[x][63:31] + 1;
res[x] = Rd.W[x] + Round[x][32:1];
} else {
res[x] = Rd.W[x] + Mres[x][63:32];
}
if (res[x] > (2^31)-1) {
res[x] = (2^31)-1;
OV = 1;
} else if (res[x] < -2^31) {
res[x] = -2^31;
OV = 1;
}
Rd.W[x] = res[x];
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] t`: long type of value stored in t

• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_KMMSB(long t, long a, long b)`

KMMSB (SIMD Saturating MSW Signed Multiply Word and Subtract)

Type: SIMD

Syntax:

```KMMSB Rd, Rs1, Rs2
KMMSB.u Rd, Rs1, Rs2
```

Purpose:

Multiply the signed 32-bit integer elements of two registers and subtract the most significant 32-bit results from the signed 32-bit elements of a third register. The subtraction results are written to the third register. The

`.u` form performs an additional rounding up operation on the multiplication results before subtracting the most significant 32-bit part of the results.

Description:

This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The

`.u` form of the instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results.

Operations:

```Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][32:0] = Mres[x][63:31] + 1;
res[x] = Rd.W[x] - Round[x][32:1];
} else {
res[x] = Rd.W[x] - Mres[x][63:32];
}
if (res[x] > (2^31)-1) {
res[x] = (2^31)-1;
OV = 1;
} else if (res[x] < -2^31) {
res[x] = -2^31;
OV = 1;
}
Rd.W[x] = res[x];
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] t`: long type of value stored in t

• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_KMMSB_U(long t, long a, long b)`

KMMSB.u (SIMD Saturating MSW Signed Multiply Word and Subtraction with Rounding)

Type: SIMD

Syntax:

```KMMSB Rd, Rs1, Rs2
KMMSB.u Rd, Rs1, Rs2
```

Purpose:

Multiply the signed 32-bit integer elements of two registers and subtract the most significant 32-bit results from the signed 32-bit elements of a third register. The subtraction results are written to the third register. The

`.u` form performs an additional rounding up operation on the multiplication results before subtracting the most significant 32-bit part of the results.

Description:

This instruction multiplies the signed 32-bit elements of Rs1 with the signed 32-bit elements of Rs2 and subtracts the most significant 32-bit multiplication results from the signed 32-bit elements of Rd. If the subtraction result is beyond the Q31 number range (-2^31 <= Q31 <= 2^31-1), it is saturated to the range and the OV bit is set to 1. The results after saturation are written to Rd. The

`.u` form of the instruction additionally rounds up the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results.

Operations:

```Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][32:0] = Mres[x][63:31] + 1;
res[x] = Rd.W[x] - Round[x][32:1];
} else {
res[x] = Rd.W[x] - Mres[x][63:32];
}
if (res[x] > (2^31)-1) {
res[x] = (2^31)-1;
OV = 1;
} else if (res[x] < -2^31) {
res[x] = -2^31;
OV = 1;
}
Rd.W[x] = res[x];
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] t`: long type of value stored in t

• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_KWMMUL(long a, long b)`

KWMMUL (SIMD Saturating MSW Signed Multiply Word & Double)

Type: SIMD

Syntax:

```KWMMUL Rd, Rs1, Rs2
KWMMUL.u Rd, Rs1, Rs2
```

Purpose:

Multiply the signed 32-bit integer elements of two registers, shift the results left 1-bit, saturate, and write the most significant 32-bit results to a register. The

`.u` form additionally rounds up the multiplication results from the most signification discarded bit.

Description:

This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts the multiplication results one bit to the left and takes the most significant 32-bit results. If the shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The

`.u` form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit 30 before the shift and saturation operations.

Operations:

```if ((0x80000000 != Rs1.W[x]) | (0x80000000 != Rs2.W[x])) {
Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][33:0] = Mres[x][63:30] + 1;
Rd.W[x] = Round[x][32:1];
} else {
Rd.W[x] = Mres[x][62:31];
}
} else {
Rd.W[x] = 0x7fffffff;
OV = 1;
}
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_KWMMUL_U(long a, long b)`

KWMMUL.u (SIMD Saturating MSW Signed Multiply Word & Double with Rounding)

Type: SIMD

Syntax:

```KWMMUL Rd, Rs1, Rs2
KWMMUL.u Rd, Rs1, Rs2
```

Purpose:

Multiply the signed 32-bit integer elements of two registers, shift the results left 1-bit, saturate, and write the most significant 32-bit results to a register. The

`.u` form additionally rounds up the multiplication results from the most signification discarded bit.

Description:

This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2. It then shifts the multiplication results one bit to the left and takes the most significant 32-bit results. If the shifted result is greater than 2^31-1, it is saturated to 2^31-1 and the OV flag is set to 1. The final element result is written to Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The

`.u` form of the instruction additionally rounds up the 64-bit multiplication results by adding a 1 to bit 30 before the shift and saturation operations.

Operations:

```if ((0x80000000 != Rs1.W[x]) | (0x80000000 != Rs2.W[x])) {
Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][33:0] = Mres[x][63:30] + 1;
Rd.W[x] = Round[x][32:1];
} else {
Rd.W[x] = Mres[x][62:31];
}
} else {
Rd.W[x] = 0x7fffffff;
OV = 1;
}
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_SMMUL(long a, long b)`

SMMUL (SIMD MSW Signed Multiply Word)

Type: SIMD

Syntax:

```SMMUL Rd, Rs1, Rs2
SMMUL.u Rd, Rs1, Rs2
```

Purpose:

Multiply the 32-bit signed integer elements of two registers and write the most significant 32-bit results to the corresponding 32-bit elements of a register. The

`.u` form performs an additional rounding up operation on the multiplication results before taking the most significant 32-bit part of the results.

Description:

This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The

`.u` form of the instruction rounds up the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results.
• For `smmul/RV32` instruction, it is an alias to `mulh/RV32` instruction.

Operations:

```Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][32:0] = Mres[x][63:31] + 1;
Rd.W[x] = Round[x][32:1];
} else {
Rd.W[x] = Mres[x][63:32];
}
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b

`__STATIC_FORCEINLINE long __RV_SMMUL_U(long a, long b)`

SMMUL.u (SIMD MSW Signed Multiply Word with Rounding)

Type: SIMD

Syntax:

```SMMUL Rd, Rs1, Rs2
SMMUL.u Rd, Rs1, Rs2
```

Purpose:

Multiply the 32-bit signed integer elements of two registers and write the most significant 32-bit results to the corresponding 32-bit elements of a register. The

`.u` form performs an additional rounding up operation on the multiplication results before taking the most significant 32-bit part of the results.

Description:

This instruction multiplies the 32-bit elements of Rs1 with the 32-bit elements of Rs2 and writes the most significant 32-bit multiplication results to the corresponding 32-bit elements of Rd. The 32-bit elements of Rs1 and Rs2 are treated as signed integers. The

`.u` form of the instruction rounds up the most significant 32-bit of the 64-bit multiplication results by adding a 1 to bit 31 of the results.
• For `smmul/RV32` instruction, it is an alias to `mulh/RV32` instruction.

Operations:

```Mres[x][63:0] = Rs1.W[x] * Rs2.W[x];
if (`.u` form) {
Round[x][32:0] = Mres[x][63:31] + 1;
Rd.W[x] = Round[x][32:1];
} else {
Rd.W[x] = Mres[x][63:32];
}
for RV32: x=0
for RV64: x=1...0
```

Return

value stored in long type

Parameters
• `[in] a`: long type of value stored in a

• `[in] b`: long type of value stored in b