1*4bdc9457SAndroid Build Coastguard Worker// Copyright 2022 Google LLC 2*4bdc9457SAndroid Build Coastguard Worker// 3*4bdc9457SAndroid Build Coastguard Worker// This source code is licensed under the BSD-style license found in the 4*4bdc9457SAndroid Build Coastguard Worker// LICENSE file in the root directory of this source tree. 5*4bdc9457SAndroid Build Coastguard Worker 6*4bdc9457SAndroid Build Coastguard Worker$assert SAMPLE_TILE >= 1 7*4bdc9457SAndroid Build Coastguard Worker#include <assert.h> 8*4bdc9457SAndroid Build Coastguard Worker#include <stddef.h> 9*4bdc9457SAndroid Build Coastguard Worker#include <stdint.h> 10*4bdc9457SAndroid Build Coastguard Worker 11*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/math.h> 12*4bdc9457SAndroid Build Coastguard Worker#include <xnnpack/fft.h> 13*4bdc9457SAndroid Build Coastguard Worker 14*4bdc9457SAndroid Build Coastguard Worker 15*4bdc9457SAndroid Build Coastguard Workervoid xnn_cs16_fftr_ukernel__scalar_x${SAMPLE_TILE}( 16*4bdc9457SAndroid Build Coastguard Worker size_t samples, 17*4bdc9457SAndroid Build Coastguard Worker int16_t* data, 18*4bdc9457SAndroid Build Coastguard Worker const int16_t* twiddle) 19*4bdc9457SAndroid Build Coastguard Worker{ 20*4bdc9457SAndroid Build Coastguard Worker assert(samples >= 2); 21*4bdc9457SAndroid Build Coastguard Worker assert(samples % 2 == 0); 22*4bdc9457SAndroid Build Coastguard Worker assert(data != NULL); 23*4bdc9457SAndroid Build Coastguard Worker assert(data != NULL); 24*4bdc9457SAndroid Build Coastguard Worker assert(twiddle != NULL); 25*4bdc9457SAndroid Build Coastguard Worker 26*4bdc9457SAndroid Build Coastguard Worker int16_t* dl = data; 27*4bdc9457SAndroid Build Coastguard Worker int16_t* dr = data + samples * 2; 28*4bdc9457SAndroid Build Coastguard Worker int32_t vdcr = (int32_t) dl[0]; 29*4bdc9457SAndroid Build Coastguard Worker int32_t vdci = (int32_t) dl[1]; 30*4bdc9457SAndroid Build Coastguard Worker 31*4bdc9457SAndroid Build Coastguard Worker vdcr = math_asr_s32(vdcr * 16383 + 16384, 15); 32*4bdc9457SAndroid Build Coastguard Worker vdci = math_asr_s32(vdci * 16383 + 16384, 15); 33*4bdc9457SAndroid Build Coastguard Worker 34*4bdc9457SAndroid Build Coastguard Worker dl[0] = vdcr + vdci; 35*4bdc9457SAndroid Build Coastguard Worker dl[1] = 0; 36*4bdc9457SAndroid Build Coastguard Worker dl += 2; 37*4bdc9457SAndroid Build Coastguard Worker dr[0] = vdcr - vdci; 38*4bdc9457SAndroid Build Coastguard Worker dr[1] = 0; 39*4bdc9457SAndroid Build Coastguard Worker 40*4bdc9457SAndroid Build Coastguard Worker samples >>= 1; 41*4bdc9457SAndroid Build Coastguard Worker 42*4bdc9457SAndroid Build Coastguard Worker $if SAMPLE_TILE > 1: 43*4bdc9457SAndroid Build Coastguard Worker for (; samples >= ${SAMPLE_TILE}; samples -= ${SAMPLE_TILE}) { 44*4bdc9457SAndroid Build Coastguard Worker dr -= ${SAMPLE_TILE} * 2; 45*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 46*4bdc9457SAndroid Build Coastguard Worker int32_t vilr${C} = dl[${C * 2 + 0}]; 47*4bdc9457SAndroid Build Coastguard Worker int32_t vili${C} = dl[${C * 2 + 1}]; 48*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 49*4bdc9457SAndroid Build Coastguard Worker int32_t virr${C} = (int32_t) dr[${(SAMPLE_TILE - 1 - C) * 2 + 0}]; 50*4bdc9457SAndroid Build Coastguard Worker int32_t viri${C} = -(int32_t) dr[${(SAMPLE_TILE - 1 - C) * 2 + 1}]; 51*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 52*4bdc9457SAndroid Build Coastguard Worker const int32_t vtwr${C} = twiddle[${C * 2 + 0}]; 53*4bdc9457SAndroid Build Coastguard Worker const int32_t vtwi${C} = twiddle[${C * 2 + 1}]; 54*4bdc9457SAndroid Build Coastguard Worker twiddle += ${SAMPLE_TILE} * 2; 55*4bdc9457SAndroid Build Coastguard Worker 56*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 57*4bdc9457SAndroid Build Coastguard Worker vilr${C} = math_asr_s32(vilr${C} * 16383 + 16384, 15); 58*4bdc9457SAndroid Build Coastguard Worker virr${C} = math_asr_s32(virr${C} * 16383 + 16384, 15); 59*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 60*4bdc9457SAndroid Build Coastguard Worker vili${C} = math_asr_s32(vili${C} * 16383 + 16384, 15); 61*4bdc9457SAndroid Build Coastguard Worker viri${C} = math_asr_s32(viri${C} * 16383 + 16384, 15); 62*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 63*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc1r${C} = vilr${C} + virr${C}; 64*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc2r${C} = vilr${C} - virr${C}; 65*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 66*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc1i${C} = vili${C} + viri${C}; 67*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc2i${C} = vili${C} - viri${C}; 68*4bdc9457SAndroid Build Coastguard Worker 69*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 70*4bdc9457SAndroid Build Coastguard Worker const int32_t twr${C} = math_asr_s32(vacc2r${C} * vtwr${C} - vacc2i${C} * vtwi${C} + 16384, 15); 71*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 72*4bdc9457SAndroid Build Coastguard Worker const int32_t twi${C} = math_asr_s32(vacc2r${C} * vtwi${C} + vacc2i${C} * vtwr${C} + 16384, 15); 73*4bdc9457SAndroid Build Coastguard Worker 74*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 75*4bdc9457SAndroid Build Coastguard Worker dl[${C * 2 + 0}] = math_asr_s32(vacc1r${C} + twr${C}, 1); 76*4bdc9457SAndroid Build Coastguard Worker dl[${C * 2 + 1}] = math_asr_s32(vacc1i${C} + twi${C}, 1); 77*4bdc9457SAndroid Build Coastguard Worker $for C in range(SAMPLE_TILE): 78*4bdc9457SAndroid Build Coastguard Worker dr[${(SAMPLE_TILE - 1 - C) * 2 + 0}] = math_asr_s32(vacc1r${C} - twr${C}, 1); 79*4bdc9457SAndroid Build Coastguard Worker dr[${(SAMPLE_TILE - 1 - C) * 2 + 1}] = math_asr_s32(twi${C} - vacc1i${C}, 1); 80*4bdc9457SAndroid Build Coastguard Worker dl += ${SAMPLE_TILE} * 2; 81*4bdc9457SAndroid Build Coastguard Worker } 82*4bdc9457SAndroid Build Coastguard Worker 83*4bdc9457SAndroid Build Coastguard Worker if XNN_UNLIKELY(samples != 0) { 84*4bdc9457SAndroid Build Coastguard Worker do { 85*4bdc9457SAndroid Build Coastguard Worker dr -= 2; 86*4bdc9457SAndroid Build Coastguard Worker int32_t vilr = dl[0]; 87*4bdc9457SAndroid Build Coastguard Worker int32_t vili = dl[1]; 88*4bdc9457SAndroid Build Coastguard Worker int32_t virr = (int32_t) dr[0]; 89*4bdc9457SAndroid Build Coastguard Worker int32_t viri = -(int32_t) dr[1]; 90*4bdc9457SAndroid Build Coastguard Worker const int32_t vtwr = twiddle[0]; 91*4bdc9457SAndroid Build Coastguard Worker const int32_t vtwi = twiddle[1]; 92*4bdc9457SAndroid Build Coastguard Worker twiddle += 2; 93*4bdc9457SAndroid Build Coastguard Worker 94*4bdc9457SAndroid Build Coastguard Worker vilr = math_asr_s32(vilr * 16383 + 16384, 15); 95*4bdc9457SAndroid Build Coastguard Worker vili = math_asr_s32(vili * 16383 + 16384, 15); 96*4bdc9457SAndroid Build Coastguard Worker virr = math_asr_s32(virr * 16383 + 16384, 15); 97*4bdc9457SAndroid Build Coastguard Worker viri = math_asr_s32(viri * 16383 + 16384, 15); 98*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc1r = vilr + virr; 99*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc1i = vili + viri; 100*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc2r = vilr - virr; 101*4bdc9457SAndroid Build Coastguard Worker const int32_t vacc2i = vili - viri; 102*4bdc9457SAndroid Build Coastguard Worker 103*4bdc9457SAndroid Build Coastguard Worker const int32_t twr = math_asr_s32(vacc2r * vtwr - vacc2i * vtwi + 16384, 15); 104*4bdc9457SAndroid Build Coastguard Worker const int32_t twi = math_asr_s32(vacc2r * vtwi + vacc2i * vtwr + 16384, 15); 105*4bdc9457SAndroid Build Coastguard Worker 106*4bdc9457SAndroid Build Coastguard Worker dl[0] = math_asr_s32(vacc1r + twr, 1); 107*4bdc9457SAndroid Build Coastguard Worker dl[1] = math_asr_s32(vacc1i + twi, 1); 108*4bdc9457SAndroid Build Coastguard Worker dr[0] = math_asr_s32(vacc1r - twr, 1); 109*4bdc9457SAndroid Build Coastguard Worker dr[1] = math_asr_s32(twi - vacc1i, 1); 110*4bdc9457SAndroid Build Coastguard Worker dl += 2; 111*4bdc9457SAndroid Build Coastguard Worker } while (--samples != 0); 112*4bdc9457SAndroid Build Coastguard Worker } 113*4bdc9457SAndroid Build Coastguard Worker} 114