summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec/dsp/dsp_arm_v6.S
blob: facd3facbd25c50146de799ac61c5c9a87d6f51a (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
128
129
130
131
132
133
/***************************************************************************
 *             __________               __   ___.
 *   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.
 *
 ****************************************************************************/
 #include "rbcodecconfig.h"

 .syntax unified
/****************************************************************************
 *  void sample_output_mono(struct sample_io_data *this,
 *                          struct dsp_buffer *src,
 *                          struct dsp_buffer *dst)
 */
    .section .text
    .global sample_output_mono
    .type   sample_output_mono, %function
sample_output_mono:
    @ input: r0 = this, r1 = src, r2 = dst
    stmfd   sp!, { r4, lr }            @
                                       @
    ldr     r0, [r0]                   @ r0 = this->outcount
    ldr     r3, [r2, #4]               @ r3 = dst->p16out
    ldr     r2, [r1, #4]               @ r2 = src->p32[0]
    ldrb    r1, [r1, #19]              @ r1 = src->format.output_scale
                                       @
    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                         @
                                       @
    ldmfdlt 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(struct sample_io_data *this,
 *                           struct dsp_buffer *src,
 *                           struct dsp_buffer *dst)
 */
    .section .text
    .global sample_output_stereo
    .type   sample_output_stereo, %function
sample_output_stereo:
    @ input: r0 = this, r1 = src, r2 = dst
    stmfd   sp!, { r4-r7, lr }         @
                                       @
    ldr     r0, [r0]                   @ r0 = this->outcount
    ldr     r3, [r2, #4]               @ r3 = dst->p16out
    ldmib   r1, { r2, r4 }             @ r2 = src->p32[0], r4 = src->p32[1]
    ldrb    r1, [r1, #19]              @ r1 = src->format.output_scale
                                       @
    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                         @
                                       @
    ldmfdlt 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