Non-SIMD Q31 saturation ALU Instructions

__STATIC_FORCEINLINE unsigned long __RV_KABSW(signed long a)
__STATIC_FORCEINLINE long __RV_KADDW(int a, int b)
__STATIC_FORCEINLINE long __RV_KDMBB(unsigned int a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KDMBT(unsigned int a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KDMTT(unsigned int a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KDMABB(long t, unsigned int a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KDMABT(long t, unsigned int a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KDMATT(long t, unsigned int a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KSLLW(long a, unsigned int b)
__STATIC_FORCEINLINE long __RV_KSLRAW(int a, int b)
__STATIC_FORCEINLINE long __RV_KSLRAW_U(int a, int b)
__STATIC_FORCEINLINE long __RV_KSUBW(int a, int b)
__STATIC_FORCEINLINE unsigned long __RV_UKADDW(unsigned int a, unsigned int b)
__STATIC_FORCEINLINE unsigned long __RV_UKSUBW(unsigned int a, unsigned int b)
__RV_KSLLIW(a, b)
group NMSIS_Core_DSP_Intrinsic_NON_SIMD_Q31_SAT_ALU

Non-SIMD Q31 saturation ALU Instructions.

there are Non-SIMD Q31 saturation ALU Instructions

Defines

__RV_KSLLIW(a, b)

KSLLIW (Saturating Shift Left Logical Immediate for Word)

Type: DSP

Syntax:

KSLLIW Rd, Rs1, imm5u

Purpose:

Do logical left shift operation with saturation on a 32-bit word. The shift amount is an immediate value.

Description:

The first word data in Rs1 is left-shifted logically. The shifted out bits are filled with zero and the shift amount is specified by the imm5u constant. Any shifted value greater than 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated to -2^31. And the saturated result is sign-extended and written to Rd. If any saturation is performed, set OV bit to 1.

Operations:

sa = imm5u;
res[(31+sa):0] = Rs1.W[0] << sa;
if (res > (2^31)-1) {
  res = 0x7fffffff; OV = 1;
} else if (res < -2^31) {
  res = 0x80000000; OV = 1;
}
Rd[31:0] = res[31:0]; // RV32
Rd[63:0] = SE(res[31:0]); // RV64

Return

value stored in long type

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

  • [in] b: unsigned int type of value stored in b

Functions

__STATIC_FORCEINLINE unsigned long __RV_KABSW(signed long a)

KABSW (Scalar 32-bit Absolute Value with Saturation)

Type: DSP

Syntax:

KABSW Rd, Rs1

Purpose:

Get the absolute value of a signed 32-bit integer in a general register.

Description:

This instruction calculates the absolute value of a signed 32-bit integer stored in Rs1. The result is sign-extended (for RV64) and written to Rd. This instruction with the minimum negative integer input of 0x80000000 will produce a saturated output of maximum positive integer of 0x7fffffff and the OV flag will be set to 1.

Operations:

if (Rs1.W[0] >= 0) {
  res = Rs1.W[0];
} else {
  If (Rs1.W[0] == 0x80000000) {
    res = 0x7fffffff;
    OV = 1;
  } else {
    res = -Rs1.W[0];
  }
}
Rd = SE32(res);

Return

value stored in unsigned long type

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

__STATIC_FORCEINLINE long __RV_KADDW(int a, int b)

KADDW (Signed Addition with Q31 Saturation)

Type: DSP

Syntax:

KADDW Rd, Rs1, Rs2

Purpose:

Add the lower 32-bit signed content of two registers with Q31 saturation.

Description:

The lower 32-bit signed content of Rs1 is added with the lower 32-bit signed content of Rs2. And the result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1] and then sign- extended and written to Rd. If saturation happens, this instruction sets the OV flag.

Operations:

tmp = Rs1.W[0] + Rs2.W[0];
if (tmp > (2^31)-1) {
  res = (2^31)-1;
  OV = 1;
} else if (tmp < -2^31) {
  res = -2^31;
  OV = 1
} else {
  res = tmp;
}
Rd = res[31:0]; // RV32
Rd = SE(res[31:0]) // RV64

Return

value stored in long type

Parameters
  • [in] a: int type of value stored in a

  • [in] b: int type of value stored in b

__STATIC_FORCEINLINE long __RV_KDMBB(unsigned int a, unsigned int b)

KDMBB (Signed Saturating Double Multiply B16 x B16)

Type: DSP

Syntax:

KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT)

Purpose:

Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is written into the destination register for RV32 or sign-extended to 64-bits and written into the destination register for RV64. If saturation happens, an overflow flag OV will be set.

Description:

Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF and the overflow flag OV will be set.

Operations:

aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB
aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT
aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT
If (0x8000 != aop | 0x8000 != bop) {
  Mresult = aop * bop;
  resQ31 = Mresult << 1;
  Rd = resQ31; // RV32
  Rd = SE(resQ31); // RV64
} else {
  resQ31 = 0x7FFFFFFF;
  Rd = resQ31; // RV32
  Rd = SE(resQ31); // RV64
  OV = 1;
}

Return

value stored in long type

Parameters
  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KDMBT(unsigned int a, unsigned int b)

KDMBT (Signed Saturating Double Multiply B16 x T16)

Type: DSP

Syntax:

KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT)

Purpose:

Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is written into the destination register for RV32 or sign-extended to 64-bits and written into the destination register for RV64. If saturation happens, an overflow flag OV will be set.

Description:

Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF and the overflow flag OV will be set.

Operations:

aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB
aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT
aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT
If (0x8000 != aop | 0x8000 != bop) {
  Mresult = aop * bop;
  resQ31 = Mresult << 1;
  Rd = resQ31; // RV32
  Rd = SE(resQ31); // RV64
} else {
  resQ31 = 0x7FFFFFFF;
  Rd = resQ31; // RV32
  Rd = SE(resQ31); // RV64
  OV = 1;
}

Return

value stored in long type

Parameters
  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KDMTT(unsigned int a, unsigned int b)

KDMTT (Signed Saturating Double Multiply T16 x T16)

Type: DSP

Syntax:

KDMxy Rd, Rs1, Rs2 (xy = BB, BT, TT)

Purpose:

Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion of the lower 32-bit chunk in registers and then double and saturate the Q31 result. The result is written into the destination register for RV32 or sign-extended to 64-bits and written into the destination register for RV64. If saturation happens, an overflow flag OV will be set.

Description:

Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then doubled and saturated into a Q31 value. The Q31 value is then written into Rd (sign-extended in RV64). When both the two Q15 inputs are 0x8000, saturation will happen. The result will be saturated to 0x7FFFFFFF and the overflow flag OV will be set.

Operations:

aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMBB
aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMBT
aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMTT
If (0x8000 != aop | 0x8000 != bop) {
  Mresult = aop * bop;
  resQ31 = Mresult << 1;
  Rd = resQ31; // RV32
  Rd = SE(resQ31); // RV64
} else {
  resQ31 = 0x7FFFFFFF;
  Rd = resQ31; // RV32
  Rd = SE(resQ31); // RV64
  OV = 1;
}

Return

value stored in long type

Parameters
  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KDMABB(long t, unsigned int a, unsigned int b)

KDMABB (Signed Saturating Double Multiply Addition B16 x B16)

Type: DSP

Syntax:

KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT)

Purpose:

Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result with the sign-extended lower 32-bit chunk destination register and write the saturated addition result into the destination register. If saturation happens, an overflow flag OV will be set.

Description:

Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then doubled and saturated into a Q31 value. The Q31 value is then added with the content 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 flag is set to 1. The result after saturation is written to Rd. When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be set.

Operations:

aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB
aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT
aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT
If (0x8000 != aop | 0x8000 != bop) {
  Mresult = aop * bop;
  resQ31 = Mresult << 1;
} else {
  resQ31 = 0x7FFFFFFF;
  OV = 1;
}
resadd = Rd + resQ31; // RV32
resadd = Rd.W[0] + resQ31; // RV64
if (resadd > (2^31)-1) {
  resadd = (2^31)-1;
  OV = 1;
} else if (resadd < -2^31) {
  resadd = -2^31;
  OV = 1;
}
Rd = resadd; // RV32
Rd = SE(resadd); // RV64

Return

value stored in long type

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

  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KDMABT(long t, unsigned int a, unsigned int b)

KDMABT (Signed Saturating Double Multiply Addition B16 x T16)

Type: DSP

Syntax:

KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT)

Purpose:

Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result with the sign-extended lower 32-bit chunk destination register and write the saturated addition result into the destination register. If saturation happens, an overflow flag OV will be set.

Description:

Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then doubled and saturated into a Q31 value. The Q31 value is then added with the content 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 flag is set to 1. The result after saturation is written to Rd. When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be set.

Operations:

aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB
aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT
aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT
If (0x8000 != aop | 0x8000 != bop) {
  Mresult = aop * bop;
  resQ31 = Mresult << 1;
} else {
  resQ31 = 0x7FFFFFFF;
  OV = 1;
}
resadd = Rd + resQ31; // RV32
resadd = Rd.W[0] + resQ31; // RV64
if (resadd > (2^31)-1) {
  resadd = (2^31)-1;
  OV = 1;
} else if (resadd < -2^31) {
  resadd = -2^31;
  OV = 1;
}
Rd = resadd; // RV32
Rd = SE(resadd); // RV64

Return

value stored in long type

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

  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KDMATT(long t, unsigned int a, unsigned int b)

KDMATT (Signed Saturating Double Multiply Addition T16 x T16)

Type: DSP

Syntax:

KDMAxy Rd, Rs1, Rs2 (xy = BB, BT, TT)

Purpose:

Multiply the signed Q15 integer contents of two 16-bit data in the corresponding portion of the lower 32-bit chunk in registers and then double and saturate the Q31 result, add the result with the sign-extended lower 32-bit chunk destination register and write the saturated addition result into the destination register. If saturation happens, an overflow flag OV will be set.

Description:

Multiply the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs1 with the top or bottom 16-bit Q15 content of the lower 32-bit portion in Rs2. The Q30 result is then doubled and saturated into a Q31 value. The Q31 value is then added with the content 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 flag is set to 1. The result after saturation is written to Rd. When both the two Q15 inputs are 0x8000, saturation will happen and the overflow flag OV will be set.

Operations:

aop = Rs1.H[0]; bop = Rs2.H[0]; // KDMABB
aop = Rs1.H[0]; bop = Rs2.H[1]; // KDMABT
aop = Rs1.H[1]; bop = Rs2.H[1]; // KDMATT
If (0x8000 != aop | 0x8000 != bop) {
  Mresult = aop * bop;
  resQ31 = Mresult << 1;
} else {
  resQ31 = 0x7FFFFFFF;
  OV = 1;
}
resadd = Rd + resQ31; // RV32
resadd = Rd.W[0] + resQ31; // RV64
if (resadd > (2^31)-1) {
  resadd = (2^31)-1;
  OV = 1;
} else if (resadd < -2^31) {
  resadd = -2^31;
  OV = 1;
}
Rd = resadd; // RV32
Rd = SE(resadd); // RV64

Return

value stored in long type

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

  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KSLLW(long a, unsigned int b)

KSLLW (Saturating Shift Left Logical for Word)

Type: DSP

Syntax:

KSLLW Rd, Rs1, Rs2

Purpose:

Do logical left shift operation with saturation on a 32-bit word. The shift amount is a variable from a GPR.

Description:

The first word data in Rs1 is left-shifted logically. The shifted out bits are filled with zero and the shift amount is specified by the low-order 5-bits of the value in the Rs2 register. Any shifted value greater than 2^31-1 is saturated to 2^31-1. Any shifted value smaller than -2^31 is saturated to -2^31. And the saturated result is sign-extended and written to Rd. If any saturation is performed, set OV bit to 1.

Operations:

sa = Rs2[4:0];
res[(31+sa):0] = Rs1.W[0] << sa;
if (res > (2^31)-1) {
  res = 0x7fffffff; OV = 1;
} else if (res < -2^31) {
  res = 0x80000000; OV = 1;
}
Rd[31:0] = res[31:0]; // RV32
Rd[63:0] = SE(res[31:0]); // RV64

Return

value stored in long type

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

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE long __RV_KSLRAW(int a, int b)

KSLRAW (Shift Left Logical with Q31 Saturation or Shift Right Arithmetic)

Type: DSP

Syntax:

KSLRAW Rd, Rs1, Rs2

Purpose:

Perform a logical left (positive) or arithmetic right (negative) shift operation with Q31 saturation for the left shift on a 32-bit data.

Description:

The lower 32-bit content of Rs1 is left-shifted logically or right-shifted arithmetically based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the absolute value of Rs2[5:0] clamped to the actual shift range of [0, 31]. The left-shifted result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. After the shift operation, the final result is bit-31 sign-extended and written to Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affected the operation of this instruction.

Operations:

if (Rs2[5:0] < 0) {
  sa = -Rs2[5:0];
  sa = (sa == 32)? 31 : sa;
  res[31:0] = Rs1.W[0] >>(arith) sa;
} else {
  sa = Rs2[5:0];
  tmp = Rs1.W[0] <<(logic) sa;
  if (tmp > (2^31)-1) {
    res[31:0] = (2^31)-1;
    OV = 1;
  } else if (tmp < -2^31) {
    res[31:0] = -2^31;
    OV = 1
  } else {
    res[31:0] = tmp[31:0];
  }
}
Rd = res[31:0]; // RV32
Rd = SE64(res[31:0]); // RV64

Return

value stored in long type

Parameters
  • [in] a: int type of value stored in a

  • [in] b: int type of value stored in b

__STATIC_FORCEINLINE long __RV_KSLRAW_U(int a, int b)

KSLRAW.u (Shift Left Logical with Q31 Saturation or Rounding Shift Right Arithmetic)

Type: DSP

Syntax:

KSLRAW.u Rd, Rs1, Rs2

Purpose:

Perform a logical left (positive) or arithmetic right (negative) shift operation with Q31 saturation for the left shift and a rounding up operation for the right shift on a 32-bit data.

Description:

The lower 32-bit content of Rs1 is left-shifted logically or right-shifted arithmetically based on the value of Rs2[5:0]. Rs2[5:0] is in the signed range of [-25, 25-1]. A positive Rs2[5:0] means logical left shift and a negative Rs2[5:0] means arithmetic right shift. The shift amount is the absolute value of Rs2[5:0] clamped to the actual shift range of [0, 31]. The left-shifted result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1]. The right-shifted result is added a 1 to the most significant discarded bit position for rounding effect. After the shift, saturation, or rounding, the final result is bit-31 sign-extended and written to Rd. If any saturation happens, this instruction sets the OV flag. The value of Rs2[31:6] will not affect the operation of this instruction.

Operations:

if (Rs2[5:0] < 0) {
  sa = -Rs2[5:0];
  sa = (sa == 32)? 31 : sa;
  res[31:-1] = SE33(Rs1[31:(sa-1)]) + 1;
  rst[31:0] = res[31:0];
} else {
  sa = Rs2[5:0];
  tmp = Rs1.W[0] <<(logic) sa;
  if (tmp > (2^31)-1) {
    rst[31:0] = (2^31)-1;
    OV = 1;
  } else if (tmp < -2^31) {
    rst[31:0] = -2^31;
    OV = 1
  } else {
    rst[31:0] = tmp[31:0];
  }
}
Rd = rst[31:0]; // RV32
Rd = SE64(rst[31:0]); // RV64

Return

value stored in long type

Parameters
  • [in] a: int type of value stored in a

  • [in] b: int type of value stored in b

__STATIC_FORCEINLINE long __RV_KSUBW(int a, int b)

KSUBW (Signed Subtraction with Q31 Saturation)

Type: DSP

Syntax:

KSUBW Rd, Rs1, Rs2

Purpose:

Subtract the signed lower 32-bit content of two registers with Q31 saturation.

Description:

The signed lower 32-bit content of Rs2 is subtracted from the signed lower 32-bit content of Rs1. And the result is saturated to the 32-bit signed integer range of [-2^31, 2^31-1] and then sign-extened and written to Rd. If saturation happens, this instruction sets the OV flag.

Operations:

tmp = Rs1.W[0] - Rs2.W[0];
if (tmp > (2^31)-1) {
  res = (2^31)-1;
  OV = 1;
} else if (tmp < -2^31) {
res = -2^31;
  OV = 1
} else {
  res = tmp;
}
Rd = res[31:0]; // RV32
Rd = SE(res[31:0]); // RV64

Return

value stored in long type

Parameters
  • [in] a: int type of value stored in a

  • [in] b: int type of value stored in b

__STATIC_FORCEINLINE unsigned long __RV_UKADDW(unsigned int a, unsigned int b)

UKADDW (Unsigned Addition with U32 Saturation)

Type: DSP

Syntax:

UKADDW Rd, Rs1, Rs2

Purpose:

Add the unsigned lower 32-bit content of two registers with U32 saturation.

Description:

The unsigned lower 32-bit content of Rs1 is added with the unsigned lower 32-bit content of Rs2. And the result is saturated to the 32-bit unsigned integer range of [0, 2^32-1] and then sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag.

Operations:

tmp = Rs1.W[0] + Rs2.W[0];
if (tmp > (2^32)-1) {
  tmp[31:0] = (2^32)-1;
  OV = 1;
}
Rd = tmp[31:0]; // RV32
Rd = SE(tmp[31:0]); // RV64

Return

value stored in unsigned long type

Parameters
  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b

__STATIC_FORCEINLINE unsigned long __RV_UKSUBW(unsigned int a, unsigned int b)

UKSUBW (Unsigned Subtraction with U32 Saturation)

Type: DSP

Syntax:

UKSUBW Rd, Rs1, Rs2

Purpose:

Subtract the unsigned lower 32-bit content of two registers with unsigned 32-bit saturation.

Description:

The unsigned lower 32-bit content of Rs2 is subtracted from the unsigned lower 32-bit content of Rs1. And the result is saturated to the 32-bit unsigned integer range of [0, 2^32-1] and then sign-extended and written to Rd. If saturation happens, this instruction sets the OV flag.

Operations:

tmp = Rs1.W[0] - Rs2.W[0];
if (tmp < 0) {
  tmp[31:0] = 0;
  OV = 1;
}
Rd = tmp[31:0]; // RV32
Rd = SE(tmp[31:0]); // RV64

Return

value stored in unsigned long type

Parameters
  • [in] a: unsigned int type of value stored in a

  • [in] b: unsigned int type of value stored in b