Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 17 additions & 18 deletions Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q15(
q15x8_t vecSrcC, vecSrcD;
q15x8_t vecDst;

/* Scale inputs so the saturating multiply cannot clip before the 3.13 conversion. */
blkCnt = (numSamples >> 3);
blkCnt -= 1;
if (blkCnt > 0)
{
/* should give more freedom to generate stall free code */
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vecSrcA = vshrq(vld1q(pSrcA), 1);
vecSrcB = vshrq(vld1q(pSrcB), 1);
pSrcA += 8;
pSrcB += 8;

Expand All @@ -79,26 +80,26 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q15(

/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
vecDst = vqdmlsdhq(vuninitializedq_s16(), vecSrcA, vecSrcB);
vecSrcC = vld1q(pSrcA);
vecSrcC = vshrq(vld1q(pSrcA), 1);
pSrcA += 8;

/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
vecDst = vqdmladhxq(vecDst, vecSrcA, vecSrcB);
vecSrcD = vld1q(pSrcB);
vecSrcD = vshrq(vld1q(pSrcB), 1);
pSrcB += 8;

vstrhq_s16(pDst, vshrq(vecDst, 2));
vstrhq_s16(pDst, vecDst);
pDst += 8;

vecDst = vqdmlsdhq(vuninitializedq_s16(), vecSrcC, vecSrcD);
vecSrcA = vld1q(pSrcA);
vecSrcA = vshrq(vld1q(pSrcA), 1);
pSrcA += 8;

vecDst = vqdmladhxq(vecDst, vecSrcC, vecSrcD);
vecSrcB = vld1q(pSrcB);
vecSrcB = vshrq(vld1q(pSrcB), 1);
pSrcB += 8;

vstrhq_s16(pDst, vshrq(vecDst, 2));
vstrhq_s16(pDst, vecDst);
pDst += 8;

/*
Expand All @@ -109,18 +110,18 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q15(

/* process last elements out of the loop avoid the armclang breaking the SW pipeline */
vecDst = vqdmlsdhq(vuninitializedq_s16(), vecSrcA, vecSrcB);
vecSrcC = vld1q(pSrcA);
vecSrcC = vshrq(vld1q(pSrcA), 1);

vecDst = vqdmladhxq(vecDst, vecSrcA, vecSrcB);
vecSrcD = vld1q(pSrcB);
vecSrcD = vshrq(vld1q(pSrcB), 1);

vstrhq_s16(pDst, vshrq(vecDst, 2));
vstrhq_s16(pDst, vecDst);
pDst += 8;

vecDst = vqdmlsdhq(vuninitializedq_s16(), vecSrcC, vecSrcD);
vecDst = vqdmladhxq(vecDst, vecSrcC, vecSrcD);

vstrhq_s16(pDst, vshrq(vecDst, 2));
vstrhq_s16(pDst, vecDst);
pDst += 8;

/*
Expand All @@ -134,13 +135,12 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q15(
pSrcA += 8;
pSrcB += 8;

vecSrcA = vldrhq_z_s16(pSrcA, p);
vecSrcB = vldrhq_z_s16(pSrcB, p);
vecSrcA = vshrq(vldrhq_z_s16(pSrcA, p), 1);
vecSrcB = vshrq(vldrhq_z_s16(pSrcB, p), 1);

vecDst = vqdmlsdhq_m(vuninitializedq_s16(), vecSrcA, vecSrcB, p);
vecDst = vqdmladhxq_m(vecDst, vecSrcA, vecSrcB, p);

vecDst = vshrq_m(vuninitializedq_s16(), vecDst, 2, p);
vstrhq_p_s16(pDst, vecDst, p);
pDst += 8;

Expand All @@ -154,13 +154,12 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q15(
while (blkCnt > 0) {
mve_pred16_t p = vctp16q(blkCnt);

vecSrcA = vldrhq_z_s16(pSrcA, p);
vecSrcB = vldrhq_z_s16(pSrcB, p);
vecSrcA = vshrq(vldrhq_z_s16(pSrcA, p), 1);
vecSrcB = vshrq(vldrhq_z_s16(pSrcB, p), 1);

vecDst = vqdmlsdhq_m(vuninitializedq_s16(), vecSrcA, vecSrcB, p);
vecDst = vqdmladhxq_m(vecDst, vecSrcA, vecSrcB, p);

vecDst = vshrq_m(vuninitializedq_s16(), vecDst, 2, p);
vstrhq_p_s16(pDst, vecDst, p);

pDst += 8;
Expand Down
35 changes: 17 additions & 18 deletions Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,39 +64,40 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q31(
q31x4_t vecSrcC, vecSrcD;
q31x4_t vecDst;

/* Scale inputs so the saturating multiply cannot clip before the 3.29 conversion. */
blkCnt = numSamples >> 2;
blkCnt -= 1;
if (blkCnt > 0) {
/* should give more freedom to generate stall free code */
vecSrcA = vld1q(pSrcA);
vecSrcB = vld1q(pSrcB);
vecSrcA = vshrq(vld1q(pSrcA), 1);
vecSrcB = vshrq(vld1q(pSrcB), 1);
pSrcA += 4;
pSrcB += 4;

while (blkCnt > 0) {

/* C[2 * i] = A[2 * i] * B[2 * i] - A[2 * i + 1] * B[2 * i + 1]. */
vecDst = vqdmlsdhq(vuninitializedq_s32(), vecSrcA, vecSrcB);
vecSrcC = vld1q(pSrcA);
vecSrcC = vshrq(vld1q(pSrcA), 1);
pSrcA += 4;

/* C[2 * i + 1] = A[2 * i] * B[2 * i + 1] + A[2 * i + 1] * B[2 * i]. */
vecDst = vqdmladhxq(vecDst, vecSrcA, vecSrcB);
vecSrcD = vld1q(pSrcB);
vecSrcD = vshrq(vld1q(pSrcB), 1);
pSrcB += 4;

vst1q(pDst, vshrq(vecDst, 2));
vst1q(pDst, vecDst);
pDst += 4;

vecDst = vqdmlsdhq(vuninitializedq_s32(), vecSrcC, vecSrcD);
vecSrcA = vld1q(pSrcA);
vecSrcA = vshrq(vld1q(pSrcA), 1);
pSrcA += 4;

vecDst = vqdmladhxq(vecDst, vecSrcC, vecSrcD);
vecSrcB = vld1q(pSrcB);
vecSrcB = vshrq(vld1q(pSrcB), 1);
pSrcB += 4;

vst1q(pDst, vshrq(vecDst, 2));
vst1q(pDst, vecDst);
pDst += 4;

/*
Expand All @@ -107,18 +108,18 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q31(

/* process last elements out of the loop avoid the armclang breaking the SW pipeline */
vecDst = vqdmlsdhq(vuninitializedq_s32(), vecSrcA, vecSrcB);
vecSrcC = vld1q(pSrcA);
vecSrcC = vshrq(vld1q(pSrcA), 1);

vecDst = vqdmladhxq(vecDst, vecSrcA, vecSrcB);
vecSrcD = vld1q(pSrcB);
vecSrcD = vshrq(vld1q(pSrcB), 1);

vst1q(pDst, vshrq(vecDst, 2));
vst1q(pDst, vecDst);
pDst += 4;

vecDst = vqdmlsdhq(vuninitializedq_s32(), vecSrcC, vecSrcD);
vecDst = vqdmladhxq(vecDst, vecSrcC, vecSrcD);

vst1q(pDst, vshrq(vecDst, 2));
vst1q(pDst, vecDst);
pDst += 4;

/*
Expand All @@ -131,13 +132,12 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q31(
pSrcA += 4;
pSrcB += 4;

vecSrcA = vldrwq_z_s32(pSrcA, p);
vecSrcB = vldrwq_z_s32(pSrcB, p);
vecSrcA = vshrq(vldrwq_z_s32(pSrcA, p), 1);
vecSrcB = vshrq(vldrwq_z_s32(pSrcB, p), 1);

vecDst = vqdmlsdhq_m(vuninitializedq_s32(), vecSrcA, vecSrcB, p);
vecDst = vqdmladhxq_m(vecDst, vecSrcA, vecSrcB, p);

vecDst = vshrq_m(vuninitializedq_s32(), vecDst, 2, p);
vstrwq_p_s32(pDst, vecDst, p);
pDst += 4;

Expand All @@ -149,13 +149,12 @@ ARM_DSP_ATTRIBUTE void arm_cmplx_mult_cmplx_q31(
while (blkCnt > 0) {
mve_pred16_t p = vctp32q(blkCnt);

vecSrcA = vldrwq_z_s32(pSrcA, p);
vecSrcB = vldrwq_z_s32(pSrcB, p);
vecSrcA = vshrq(vldrwq_z_s32(pSrcA, p), 1);
vecSrcB = vshrq(vldrwq_z_s32(pSrcB, p), 1);

vecDst = vqdmlsdhq_m(vuninitializedq_s32(), vecSrcA, vecSrcB, p);
vecDst = vqdmladhxq_m(vecDst, vecSrcA, vecSrcB, p);

vecDst = vshrq_m(vuninitializedq_s32(), vecDst, 2, p);
vstrwq_p_s32(pDst, vecDst, p);

pDst += 4;
Expand Down
34 changes: 32 additions & 2 deletions Testing/PatternGeneration/ComplexMaths.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@


# Those patterns are used for tests and benchmarks.
# For tests, there is the need to add tests for saturation

def randComplex(nb):
data = np.random.randn(2*nb)
Expand All @@ -17,6 +16,30 @@ def asReal(a):
#return(a.view(dtype=np.float64))
return(a.reshape(np.size(a)).view(dtype=np.float64))

def saturationComplex():
data1 = np.array([
1 + 1j,
1 + 1j,
1 - 1j,
1 - 1j,
-1 + 1j,
-1 + 1j,
-1 - 1j,
-1 - 1j,
])
data2 = np.array([
1 + 1j,
1 - 1j,
1 + 1j,
-1 - 1j,
1 + 1j,
-1 + 1j,
1 + 1j,
-1 - 1j,
])

return(np.resize(data1, 17), np.resize(data2, 17))

def writeTests(config,format):
NBSAMPLES=256

Expand Down Expand Up @@ -99,6 +122,14 @@ def writeTests(config,format):
config.writeReferenceQ31(9, asReal(ref))
else:
config.writeReference(9, asReal(ref))

if format == 31 or format == 15:
saturation1, saturation2 = saturationComplex()
config.writeInput(4, asReal(saturation1))
config.writeInput(5, asReal(saturation2))

ref = saturation1 * saturation2 / 4
config.writeReference(10, asReal(ref))

def generatePatterns():
PATTERNDIR = os.path.join("Patterns","DSP","ComplexMaths","ComplexMaths")
Expand All @@ -124,4 +155,3 @@ def generatePatterns():
if __name__ == '__main__':
generatePatterns()


70 changes: 70 additions & 0 deletions Testing/Patterns/DSP/ComplexMaths/ComplexMathsQ15/Input4_q15.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
H
34
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// -1.00000000000000000
0x8000
// 1.00000000000000000
0x7FFF
// 1.00000000000000000
0x7FFF
Loading