summaryrefslogtreecommitdiffstats
path: root/apps/dsp_arm_v6.S
blob: 39949498eae9c6b142e2ec331d8f8e9402fc1f6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2010 Michael Sevakis
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

/****************************************************************************
 *  void sample_output_mono(int count, struct dsp_data *data,
 *                          const int32_t *src[], int16_t *dst)
 */
    .section .text, "ax", %progbits
    .align  2
    .global sample_output_mono
    .type   sample_output_mono, %function
sample_output_mono:
    @ input: r0 = count, r1 = data, r2 = src, r3 = dst
    stmfd   sp!, { r4, lr }            @
                                       @
    ldr     r1, [r1]                   @ r1 = data->output_scale
    ldr     r2, [r2]                   @ r2 = src[0]
                                       @
    mov     r4, #1                     @ r4 = 1 << (scale - 1)
    mov     r4, r4, lsl r1             @
    subs    r0, r0, #1                 @ odd: end at 0; even: end at -1
    mov     r4, r4, lsr #1             @
    beq     2f                         @ Zero? Only one sample!
                                       @
1:                                     @
    ldmia   r2!, { r12, r14 }          @ load Mi0, Mi1
    qadd    r12, r12, r4               @ round, scale, saturate and
    qadd    r14, r14, r4               @ pack Mi0 to So0, Mi1 to So1
    mov     r12, r12, asr r1           @
    mov     r14, r14, asr r1           @
    ssat    r12, #16, r12              @
    ssat    r14, #16, r14              @
    pkhbt   r12, r12, r12, asl #16     @
    pkhbt   r14, r14, r14, asl #16     @
    subs    r0, r0, #2                 @
    stmia   r3!, { r12, r14 }          @ store So0, So1
    bgt     1b                         @
                                       @
    ldmltfd sp!, { r4, pc }            @ if count was even, we're done
                                       @
2:                                     @
    ldr     r12, [r2]                  @ round, scale, saturate
    qadd    r12, r12, r4               @ and pack Mi to So
    mov     r12, r12, asr r1           @
    ssat    r12, #16, r12              @
    pkhbt   r12, r12, r12, asl #16     @
    str     r12, [r3]                  @ store So
                                       @       
    ldmfd   sp!, { r4, pc }            @
    .size   sample_output_mono, .-sample_output_mono

/****************************************************************************
 * void sample_output_stereo(int count, struct dsp_data *data,
 *                           const int32_t *src[], int16_t *dst)
 */
    .section .text, "ax", %progbits
    .align  2
    .global sample_output_stereo
    .type   sample_output_stereo, %function
sample_output_stereo:
    @ input: r0 = count, r1 = data, r2 = src, r3 = dst
    stmfd   sp!, { r4-r7, lr }         @
                                       @
    ldr     r1, [r1]                   @ r1 = data->output_scale    
    ldmia   r2, { r2, r4 }             @ r2 = src[0], r4 = src[1]
                                       @
    mov     r5, #1                     @ r5 = 1 << (scale - 1)
    mov     r5, r5, lsl r1             @
    subs    r0, r0, #1                 @ odd: end at 0; even: end at -1
    mov     r5, r5, lsr #1             @
    beq     2f                         @ Zero? Only one sample!
                                       @
1:                                     @
    ldmia   r2!, { r6, r7 }            @ r6, r7 = Li0, Li1
    ldmia   r4!, { r12, r14 }          @ r12, r14 = Ri0, Ri1
    qadd    r6, r6, r5                 @ round, scale, saturate and pack
    qadd    r7, r7, r5                 @ Li0+Ri0 to So0, Li1+Ri1 to So1
    qadd    r12, r12, r5               @
    qadd    r14, r14, r5               @
    mov     r6, r6, asr r1             @ 
    mov     r7, r7, asr r1             @
    mov     r12, r12, asr r1           @
    mov     r14, r14, asr r1           @
    ssat    r6, #16, r6                @
    ssat    r12, #16, r12              @
    ssat    r7, #16, r7                @
    ssat    r14, #16, r14              @
    pkhbt   r6, r6, r12, asl #16       @
    pkhbt   r7, r7, r14, asl #16       @
    subs    r0, r0, #2                 @
    stmia   r3!, { r6, r7 }            @ store So0, So1
    bgt     1b                         @
                                       @
    ldmltfd sp!, { r4-r7, pc }         @ if count was even, we're done
                                       @
2:                                     @
    ldr     r6, [r2]                   @ r6 = Li
    ldr     r12, [r4]                  @ r12 = Ri
    qadd    r6, r6, r5                 @ round, scale, saturate
    qadd    r12, r12, r5               @ and pack Li+Ri to So
    mov     r6, r6, asr r1             @
    mov     r12, r12, asr r1           @
    ssat    r6, #16, r6                @
    ssat    r12, #16, r12              @
    pkhbt   r6, r6, r12, asl #16       @
    str     r6, [r3]                   @ store So
                                       @
    ldmfd   sp!, { r4-r7, pc }         @
    .size   sample_output_stereo, .-sample_output_stereo