00001
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "preprocessor.h"
00048
00049 #if !defined(FORCE_ALL_GENERICS) && \
00050 !defined(FORCE_GENERIC_VECT16_NEG) && \
00051 defined(TARGET_SPECIFIC_VECT16_NEG)
00052
00053 #if __GNUC__
00054 # define DSP16_NEG_END_KERNEL_X_FCT(x_num, data) __attribute__((__naked__)) DSP16_NEG_END_KERNEL_X_FCT__(x_num, data)
00055 #elif __ICCAVR32__
00056 # define DSP16_NEG_END_KERNEL_X_FCT(x_num, data) DSP16_NEG_END_KERNEL_X_FCT__(x_num, data)
00057 #endif
00058
00059
00060 #if __GNUC__
00061 # define ASM_INSTRUCT_COMPACKED(str) str
00062 # define ASM_INSTRUCT_EXTENDED(str) str
00063 #elif __ICCAVR32__
00064 # define ASM_INSTRUCT_COMPACKED(str) str":C"
00065 # define ASM_INSTRUCT_EXTENDED(str) str":E"
00066 #endif
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 #define DSP16_NEGATE_0(r_vect1, r_vect2)
00082
00083 #define DSP16_NEGATE_1(r_vect1, r_vect2) \
00084 "ld.sh r2, "ASTRINGZ(r_vect2)"[0x0]\n\t" \
00085 \
00086 "neg r2\n\t" \
00087 "st.h "ASTRINGZ(r_vect1)"[0x0], r2\n\t"
00088
00089 #define DSP16_NEGATE_2(r_vect1, r_vect2) \
00090 "ld.w r2, "ASTRINGZ(r_vect2)"[0x0]\n\t" \
00091 "mov r3, 0\n\t" \
00092 \
00093 "subhh.w r1, r3:b, r2:b\n\t" \
00094 "subhh.w r0, r3:b, r2:t\n\t" \
00095 "sthh.w "ASTRINGZ(r_vect1)"[0x0], r0:b, r1:b\n\t"
00096
00097 #define DSP16_NEGATE_3(r_vect1, r_vect2) \
00098 "ld.w r2, "ASTRINGZ(r_vect2)"[0x0]\n\t" \
00099 "mov r3, 0\n\t" \
00100 \
00101 "subhh.w r1, r3:b, r2:b\n\t" \
00102 "subhh.w r0, r3:b, r2:t\n\t" \
00103 "sthh.w "ASTRINGZ(r_vect1)"[0x0], r0:b, r1:b\n\t" \
00104 \
00105 "ld.sh r2, "ASTRINGZ(r_vect2)"[0x4]\n\t" \
00106 \
00107 "neg r2\n\t" \
00108 "st.h "ASTRINGZ(r_vect1)"[0x4], r2\n\t"
00109
00110
00111
00112
00113
00114
00115 #define DSP16_NEG_END_KERNEL_X_FCT__(x_num, data) \
00116 static void TPASTE2(dsp16_vect_neg_end_kernel_x, x_num)(dsp16_t *vect1, dsp16_t *vect2) \
00117 { \
00118 __asm__ __volatile__ ( \
00119 "pushm r0-r3, lr\n\t" \
00120 TPASTE2(DSP16_NEGATE_, x_num)(r12, r11) \
00121 "popm r0-r3, pc\n\t" \
00122 ); \
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00139 #if __GNUC__
00140 __attribute__((__naked__))
00141 __attribute__((__noinline__))
00142 #elif __ICCAVR32__
00143 # pragma shadow_registers=full
00144 # pragma optimize=none no_inline
00145 #endif
00146 static int dsp16_vect_neg_kernel_ext(dsp16_t *vect1, dsp16_t *vect2, int size)
00147 {
00148 __asm__ __volatile__ (
00149 "pushm r0-r7, lr\n\t"
00150
00151 "mov lr, 0\n\t"
00152 "sub r10, 3\n\t"
00153 "mov r9, 0\n\t"
00154
00155 "cp.h lr, r10\n\t"
00156 ASM_INSTRUCT_COMPACKED("brge __dsp16_neg_ext_end_loop")"\n"
00157
00158 "__dsp16_neg_ext_loop:\n\t"
00159
00160 "ld.d r0, r11[lr << 1]\n\t"
00161
00162 "subhh.w r4, r9:b, r1:b\n\t"
00163 "subhh.w r5, r9:b, r1:t\n\t"
00164 "sthh.w r12[lr << 1], r5:b, r4:b\n\t"
00165
00166 "sub lr, -2\n\t"
00167 "subhh.w r4, r9:b, r0:b\n\t"
00168 "subhh.w r5, r9:b, r0:t\n\t"
00169 "sthh.w r12[lr << 1], r5:b, r4:b\n\t"
00170
00171 "sub lr, -2\n\t"
00172
00173 "cp.h lr, r10\n\t"
00174 ASM_INSTRUCT_COMPACKED("brlt __dsp16_neg_ext_loop")"\n"
00175
00176 "__dsp16_neg_ext_end_loop:\n\t"
00177
00178 "mov r12, lr\n\t"
00179 "popm r0-r7, pc\n\t"
00180 );
00181
00182 return 0;
00183 }
00184
00185
00186 DSP16_NEG_END_KERNEL_X_FCT(0, "")
00187 DSP16_NEG_END_KERNEL_X_FCT(1, "")
00188 DSP16_NEG_END_KERNEL_X_FCT(2, "")
00189 DSP16_NEG_END_KERNEL_X_FCT(3, "")
00190
00191 void dsp16_vect_neg(dsp16_t *vect1, dsp16_t *vect2, int size)
00192 {
00193 typedef void (*neg_end_kernel_opti_t)(dsp16_t *, dsp16_t *);
00194 static const neg_end_kernel_opti_t neg_end_kernel_opti[4] = {
00195 dsp16_vect_neg_end_kernel_x0,
00196 dsp16_vect_neg_end_kernel_x1,
00197 dsp16_vect_neg_end_kernel_x2,
00198 dsp16_vect_neg_end_kernel_x3
00199 };
00200 int n;
00201
00202 n = dsp16_vect_neg_kernel_ext(vect1, vect2, size);
00203
00204
00205 neg_end_kernel_opti[size&0x3](&vect1[n], &vect2[n]);
00206 }
00207
00208 #endif