Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2013 RISC OS Open Ltd
  3.  * Author: Ben Avison <bavison@riscosopen.org>
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include "libavutil/arm/asm.S"
  23.  
  24. POUT          .req    a1
  25. PIN           .req    a2
  26. PCOEF         .req    a3
  27. DECIFACTOR    .req    a4
  28. OLDFPSCR      .req    a4
  29. COUNTER       .req    ip
  30.  
  31. SCALE32       .req    s28  @ use vector of 4 in place of 9th scalar when decifactor=32 / JMAX=8
  32. SCALE64       .req    s0   @ spare register in scalar bank when decifactor=64 / JMAX=4
  33. IN0           .req    s4
  34. IN1           .req    s5
  35. IN2           .req    s6
  36. IN3           .req    s7
  37. IN4           .req    s0
  38. IN5           .req    s1
  39. IN6           .req    s2
  40. IN7           .req    s3
  41. COEF0         .req    s8   @ coefficient elements
  42. COEF1         .req    s9
  43. COEF2         .req    s10
  44. COEF3         .req    s11
  45. COEF4         .req    s12
  46. COEF5         .req    s13
  47. COEF6         .req    s14
  48. COEF7         .req    s15
  49. ACCUM0        .req    s16  @ double-buffered multiply-accumulate results
  50. ACCUM4        .req    s20
  51. POST0         .req    s24  @ do long-latency post-multiply in this vector in parallel
  52. POST1         .req    s25
  53. POST2         .req    s26
  54. POST3         .req    s27
  55.  
  56.  
  57. .macro inner_loop  decifactor, dir, tail, head
  58.  .ifc "\dir","up"
  59.   .set X, 0
  60.   .set Y, 4
  61.  .else
  62.   .set X, 4*JMAX*4 - 4
  63.   .set Y, -4
  64.  .endif
  65.  .ifnc "\head",""
  66.         vldr    COEF0, [PCOEF, #X + (0*JMAX + 0) * Y]
  67.         vldr    COEF1, [PCOEF, #X + (1*JMAX + 0) * Y]
  68.         vldr    COEF2, [PCOEF, #X + (2*JMAX + 0) * Y]
  69.         vldr    COEF3, [PCOEF, #X + (3*JMAX + 0) * Y]
  70.  .endif
  71.  .ifnc "\tail",""
  72.         vadd.f  POST0, ACCUM0, ACCUM4   @ vector operation
  73.  .endif
  74.  .ifnc "\head",""
  75.         vmul.f  ACCUM0, COEF0, IN0      @ vector = vector * scalar
  76.         vldr    COEF4, [PCOEF, #X + (0*JMAX + 1) * Y]
  77.         vldr    COEF5, [PCOEF, #X + (1*JMAX + 1) * Y]
  78.         vldr    COEF6, [PCOEF, #X + (2*JMAX + 1) * Y]
  79.  .endif
  80.  .ifnc "\tail",""
  81.         vmul.f  POST0, POST0, SCALE\decifactor  @ vector operation (SCALE may be scalar)
  82.  .endif
  83.  .ifnc "\head",""
  84.         vldr    COEF7, [PCOEF, #X + (3*JMAX + 1) * Y]
  85.    .ifc "\tail",""
  86.         vmul.f  ACCUM4, COEF4, IN1      @ vector operation
  87.    .endif
  88.         vldr    COEF0, [PCOEF, #X + (0*JMAX + 2) * Y]
  89.         vldr    COEF1, [PCOEF, #X + (1*JMAX + 2) * Y]
  90.    .ifnc "\tail",""
  91.         vmul.f  ACCUM4, COEF4, IN1      @ vector operation
  92.    .endif
  93.         vldr    COEF2, [PCOEF, #X + (2*JMAX + 2) * Y]
  94.         vldr    COEF3, [PCOEF, #X + (3*JMAX + 2) * Y]
  95.  .endif
  96.  .ifnc "\tail",""
  97.         vstmia  POUT!, {POST0-POST3}
  98.  .endif
  99.  .ifnc "\head",""
  100.         vmla.f  ACCUM0, COEF0, IN2      @ vector = vector * scalar
  101.         vldr    COEF4, [PCOEF, #X + (0*JMAX + 3) * Y]
  102.         vldr    COEF5, [PCOEF, #X + (1*JMAX + 3) * Y]
  103.         vldr    COEF6, [PCOEF, #X + (2*JMAX + 3) * Y]
  104.         vldr    COEF7, [PCOEF, #X + (3*JMAX + 3) * Y]
  105.         vmla.f  ACCUM4, COEF4, IN3      @ vector = vector * scalar
  106.   .if \decifactor == 32
  107.         vldr    COEF0, [PCOEF, #X + (0*JMAX + 4) * Y]
  108.         vldr    COEF1, [PCOEF, #X + (1*JMAX + 4) * Y]
  109.         vldr    COEF2, [PCOEF, #X + (2*JMAX + 4) * Y]
  110.         vldr    COEF3, [PCOEF, #X + (3*JMAX + 4) * Y]
  111.         vmla.f  ACCUM0, COEF0, IN4      @ vector = vector * scalar
  112.         vldr    COEF4, [PCOEF, #X + (0*JMAX + 5) * Y]
  113.         vldr    COEF5, [PCOEF, #X + (1*JMAX + 5) * Y]
  114.         vldr    COEF6, [PCOEF, #X + (2*JMAX + 5) * Y]
  115.         vldr    COEF7, [PCOEF, #X + (3*JMAX + 5) * Y]
  116.         vmla.f  ACCUM4, COEF4, IN5      @ vector = vector * scalar
  117.         vldr    COEF0, [PCOEF, #X + (0*JMAX + 6) * Y]
  118.         vldr    COEF1, [PCOEF, #X + (1*JMAX + 6) * Y]
  119.         vldr    COEF2, [PCOEF, #X + (2*JMAX + 6) * Y]
  120.         vldr    COEF3, [PCOEF, #X + (3*JMAX + 6) * Y]
  121.         vmla.f  ACCUM0, COEF0, IN6      @ vector = vector * scalar
  122.         vldr    COEF4, [PCOEF, #X + (0*JMAX + 7) * Y]
  123.         vldr    COEF5, [PCOEF, #X + (1*JMAX + 7) * Y]
  124.         vldr    COEF6, [PCOEF, #X + (2*JMAX + 7) * Y]
  125.         vldr    COEF7, [PCOEF, #X + (3*JMAX + 7) * Y]
  126.         vmla.f  ACCUM4, COEF4, IN7      @ vector = vector * scalar
  127.   .endif
  128.  .endif
  129. .endm
  130.  
  131. .macro dca_lfe_fir  decifactor
  132.  .if \decifactor == 32
  133.   .set JMAX, 8
  134.         vpush   {s16-s31}
  135.         vmov    SCALE32, s0             @ duplicate scalar across vector
  136.         vldr    IN4, [PIN, #-4*4]
  137.         vldr    IN5, [PIN, #-5*4]
  138.         vldr    IN6, [PIN, #-6*4]
  139.         vldr    IN7, [PIN, #-7*4]
  140.  .else
  141.   .set JMAX, 4
  142.         vpush   {s16-s27}
  143.  .endif
  144.  
  145.         mov     COUNTER, #\decifactor/4 - 1
  146.         inner_loop  \decifactor, up,, head
  147. 1:      add     PCOEF, PCOEF, #4*JMAX*4
  148.         subs    COUNTER, COUNTER, #1
  149.         inner_loop  \decifactor, up, tail, head
  150.         bne     1b
  151.         inner_loop  \decifactor, up, tail
  152.  
  153.         mov     COUNTER, #\decifactor/4 - 1
  154.         inner_loop  \decifactor, down,, head
  155. 1:      sub     PCOEF, PCOEF, #4*JMAX*4
  156.         subs    COUNTER, COUNTER, #1
  157.         inner_loop  \decifactor, down, tail, head
  158.         bne     1b
  159.         inner_loop  \decifactor, down, tail
  160.  
  161.  .if \decifactor == 32
  162.         vpop    {s16-s31}
  163.  .else
  164.         vpop    {s16-s27}
  165.  .endif
  166.         fmxr    FPSCR, OLDFPSCR
  167.         bx      lr
  168. .endm
  169.  
  170.  
  171. /* void ff_dca_lfe_fir_vfp(float *out, const float *in, const float *coefs,
  172.  *                         int decifactor, float scale)
  173.  */
  174. function ff_dca_lfe_fir_vfp, export=1
  175.         teq     DECIFACTOR, #32
  176.         fmrx    OLDFPSCR, FPSCR
  177.         ldr     ip, =0x03030000         @ RunFast mode, short vectors of length 4, stride 1
  178.         fmxr    FPSCR, ip
  179. NOVFP   vldr    s0, [sp]
  180.         vldr    IN0, [PIN, #-0*4]
  181.         vldr    IN1, [PIN, #-1*4]
  182.         vldr    IN2, [PIN, #-2*4]
  183.         vldr    IN3, [PIN, #-3*4]
  184.         beq     32f
  185. 64:     dca_lfe_fir  64
  186.  .ltorg
  187. 32:     dca_lfe_fir  32
  188. endfunc
  189.  
  190.         .unreq  POUT
  191.         .unreq  PIN
  192.         .unreq  PCOEF
  193.         .unreq  DECIFACTOR
  194.         .unreq  OLDFPSCR
  195.         .unreq  COUNTER
  196.  
  197.         .unreq  SCALE32
  198.         .unreq  SCALE64
  199.         .unreq  IN0
  200.         .unreq  IN1
  201.         .unreq  IN2
  202.         .unreq  IN3
  203.         .unreq  IN4
  204.         .unreq  IN5
  205.         .unreq  IN6
  206.         .unreq  IN7
  207.         .unreq  COEF0
  208.         .unreq  COEF1
  209.         .unreq  COEF2
  210.         .unreq  COEF3
  211.         .unreq  COEF4
  212.         .unreq  COEF5
  213.         .unreq  COEF6
  214.         .unreq  COEF7
  215.         .unreq  ACCUM0
  216.         .unreq  ACCUM4
  217.         .unreq  POST0
  218.         .unreq  POST1
  219.         .unreq  POST2
  220.         .unreq  POST3
  221.  
  222.  
  223. IN      .req    a1
  224. SBACT   .req    a2
  225. OLDFPSCR .req   a3
  226. IMDCT   .req    a4
  227. WINDOW  .req    v1
  228. OUT     .req    v2
  229. BUF     .req    v3
  230. SCALEINT .req   v4 @ only used in softfp case
  231. COUNT   .req    v5
  232.  
  233. SCALE   .req    s0
  234.  
  235. /* Stack layout differs in softfp and hardfp cases:
  236.  *
  237.  * hardfp
  238.  *      fp -> 6 arg words saved by caller
  239.  *            a3,a4,v1-v3,v5,fp,lr on entry (a3 just to pad to 8 bytes)
  240.  *            s16-s23 on entry
  241.  *            align 16
  242.  *     buf -> 8*32*4 bytes buffer
  243.  *            s0 on entry
  244.  *      sp -> 3 arg words for callee
  245.  *
  246.  * softfp
  247.  *      fp -> 7 arg words saved by caller
  248.  *            a4,v1-v5,fp,lr on entry
  249.  *            s16-s23 on entry
  250.  *            align 16
  251.  *     buf -> 8*32*4 bytes buffer
  252.  *      sp -> 4 arg words for callee
  253.  */
  254.  
  255. /* void ff_dca_qmf_32_subbands_vfp(float samples_in[32][8], int sb_act,
  256.  *                                 SynthFilterContext *synth, FFTContext *imdct,
  257.  *                                 float (*synth_buf_ptr)[512],
  258.  *                                 int *synth_buf_offset, float (*synth_buf2)[32],
  259.  *                                 const float (*window)[512], float *samples_out,
  260.  *                                 float (*raXin)[32], float scale);
  261.  */
  262. function ff_dca_qmf_32_subbands_vfp, export=1
  263. VFP     push    {a3-a4,v1-v3,v5,fp,lr}
  264. NOVFP   push    {a4,v1-v5,fp,lr}
  265.         add     fp, sp, #8*4
  266.         vpush   {s16-s23}
  267.         @ The buffer pointed at by raXin isn't big enough for us to do a
  268.         @ complete matrix transposition as we want to, so allocate an
  269.         @ alternative buffer from the stack. Align to 4 words for speed.
  270.         sub     BUF, sp, #8*32*4
  271.         bic     BUF, BUF, #15
  272.         mov     sp, BUF
  273.         ldr     lr, =0x03330000     @ RunFast mode, short vectors of length 4, stride 2
  274.         fmrx    OLDFPSCR, FPSCR
  275.         fmxr    FPSCR, lr
  276.         @ COUNT is used to count down 2 things at once:
  277.         @ bits 0-4 are the number of word pairs remaining in the output row
  278.         @ bits 5-31 are the number of words to copy (with possible negation)
  279.         @   from the source matrix before we start zeroing the remainder
  280.         mov     COUNT, #(-4 << 5) + 16
  281.         adds    COUNT, COUNT, SBACT, lsl #5
  282.         bmi     2f
  283. 1:
  284.         vldr    s8,  [IN, #(0*8+0)*4]
  285.         vldr    s10, [IN, #(0*8+1)*4]
  286.         vldr    s12, [IN, #(0*8+2)*4]
  287.         vldr    s14, [IN, #(0*8+3)*4]
  288.         vldr    s16, [IN, #(0*8+4)*4]
  289.         vldr    s18, [IN, #(0*8+5)*4]
  290.         vldr    s20, [IN, #(0*8+6)*4]
  291.         vldr    s22, [IN, #(0*8+7)*4]
  292.         vneg.f  s8, s8
  293.         vldr    s9,  [IN, #(1*8+0)*4]
  294.         vldr    s11, [IN, #(1*8+1)*4]
  295.         vldr    s13, [IN, #(1*8+2)*4]
  296.         vldr    s15, [IN, #(1*8+3)*4]
  297.         vneg.f  s16, s16
  298.         vldr    s17, [IN, #(1*8+4)*4]
  299.         vldr    s19, [IN, #(1*8+5)*4]
  300.         vldr    s21, [IN, #(1*8+6)*4]
  301.         vldr    s23, [IN, #(1*8+7)*4]
  302.         vstr    d4,  [BUF, #(0*32+0)*4]
  303.         vstr    d5,  [BUF, #(1*32+0)*4]
  304.         vstr    d6,  [BUF, #(2*32+0)*4]
  305.         vstr    d7,  [BUF, #(3*32+0)*4]
  306.         vstr    d8,  [BUF, #(4*32+0)*4]
  307.         vstr    d9,  [BUF, #(5*32+0)*4]
  308.         vstr    d10, [BUF, #(6*32+0)*4]
  309.         vstr    d11, [BUF, #(7*32+0)*4]
  310.         vldr    s9,  [IN, #(3*8+0)*4]
  311.         vldr    s11, [IN, #(3*8+1)*4]
  312.         vldr    s13, [IN, #(3*8+2)*4]
  313.         vldr    s15, [IN, #(3*8+3)*4]
  314.         vldr    s17, [IN, #(3*8+4)*4]
  315.         vldr    s19, [IN, #(3*8+5)*4]
  316.         vldr    s21, [IN, #(3*8+6)*4]
  317.         vldr    s23, [IN, #(3*8+7)*4]
  318.         vneg.f  s9, s9
  319.         vldr    s8,  [IN, #(2*8+0)*4]
  320.         vldr    s10, [IN, #(2*8+1)*4]
  321.         vldr    s12, [IN, #(2*8+2)*4]
  322.         vldr    s14, [IN, #(2*8+3)*4]
  323.         vneg.f  s17, s17
  324.         vldr    s16, [IN, #(2*8+4)*4]
  325.         vldr    s18, [IN, #(2*8+5)*4]
  326.         vldr    s20, [IN, #(2*8+6)*4]
  327.         vldr    s22, [IN, #(2*8+7)*4]
  328.         vstr    d4,  [BUF, #(0*32+2)*4]
  329.         vstr    d5,  [BUF, #(1*32+2)*4]
  330.         vstr    d6,  [BUF, #(2*32+2)*4]
  331.         vstr    d7,  [BUF, #(3*32+2)*4]
  332.         vstr    d8,  [BUF, #(4*32+2)*4]
  333.         vstr    d9,  [BUF, #(5*32+2)*4]
  334.         vstr    d10, [BUF, #(6*32+2)*4]
  335.         vstr    d11, [BUF, #(7*32+2)*4]
  336.         add     IN, IN, #4*8*4
  337.         add     BUF, BUF, #4*4
  338.         subs    COUNT, COUNT, #(4 << 5) + 2
  339.         bpl     1b
  340. 2:      @ Now deal with trailing < 4 samples
  341.         adds    COUNT, COUNT, #3 << 5
  342.         bmi     4f  @ sb_act was a multiple of 4
  343.         bics    lr, COUNT, #0x1F
  344.         bne     3f
  345.         @ sb_act was n*4+1
  346.         vldr    s8,  [IN, #(0*8+0)*4]
  347.         vldr    s10, [IN, #(0*8+1)*4]
  348.         vldr    s12, [IN, #(0*8+2)*4]
  349.         vldr    s14, [IN, #(0*8+3)*4]
  350.         vldr    s16, [IN, #(0*8+4)*4]
  351.         vldr    s18, [IN, #(0*8+5)*4]
  352.         vldr    s20, [IN, #(0*8+6)*4]
  353.         vldr    s22, [IN, #(0*8+7)*4]
  354.         vneg.f  s8, s8
  355.         vldr    s9,  zero
  356.         vldr    s11, zero
  357.         vldr    s13, zero
  358.         vldr    s15, zero
  359.         vneg.f  s16, s16
  360.         vldr    s17, zero
  361.         vldr    s19, zero
  362.         vldr    s21, zero
  363.         vldr    s23, zero
  364.         vstr    d4,  [BUF, #(0*32+0)*4]
  365.         vstr    d5,  [BUF, #(1*32+0)*4]
  366.         vstr    d6,  [BUF, #(2*32+0)*4]
  367.         vstr    d7,  [BUF, #(3*32+0)*4]
  368.         vstr    d8,  [BUF, #(4*32+0)*4]
  369.         vstr    d9,  [BUF, #(5*32+0)*4]
  370.         vstr    d10, [BUF, #(6*32+0)*4]
  371.         vstr    d11, [BUF, #(7*32+0)*4]
  372.         add     BUF, BUF, #2*4
  373.         sub     COUNT, COUNT, #1
  374.         b       4f
  375. 3:      @ sb_act was n*4+2 or n*4+3, so do the first 2
  376.         vldr    s8,  [IN, #(0*8+0)*4]
  377.         vldr    s10, [IN, #(0*8+1)*4]
  378.         vldr    s12, [IN, #(0*8+2)*4]
  379.         vldr    s14, [IN, #(0*8+3)*4]
  380.         vldr    s16, [IN, #(0*8+4)*4]
  381.         vldr    s18, [IN, #(0*8+5)*4]
  382.         vldr    s20, [IN, #(0*8+6)*4]
  383.         vldr    s22, [IN, #(0*8+7)*4]
  384.         vneg.f  s8, s8
  385.         vldr    s9,  [IN, #(1*8+0)*4]
  386.         vldr    s11, [IN, #(1*8+1)*4]
  387.         vldr    s13, [IN, #(1*8+2)*4]
  388.         vldr    s15, [IN, #(1*8+3)*4]
  389.         vneg.f  s16, s16
  390.         vldr    s17, [IN, #(1*8+4)*4]
  391.         vldr    s19, [IN, #(1*8+5)*4]
  392.         vldr    s21, [IN, #(1*8+6)*4]
  393.         vldr    s23, [IN, #(1*8+7)*4]
  394.         vstr    d4,  [BUF, #(0*32+0)*4]
  395.         vstr    d5,  [BUF, #(1*32+0)*4]
  396.         vstr    d6,  [BUF, #(2*32+0)*4]
  397.         vstr    d7,  [BUF, #(3*32+0)*4]
  398.         vstr    d8,  [BUF, #(4*32+0)*4]
  399.         vstr    d9,  [BUF, #(5*32+0)*4]
  400.         vstr    d10, [BUF, #(6*32+0)*4]
  401.         vstr    d11, [BUF, #(7*32+0)*4]
  402.         add     BUF, BUF, #2*4
  403.         sub     COUNT, COUNT, #(2 << 5) + 1
  404.         bics    lr, COUNT, #0x1F
  405.         bne     4f
  406.         @ sb_act was n*4+3
  407.         vldr    s8,  [IN, #(2*8+0)*4]
  408.         vldr    s10, [IN, #(2*8+1)*4]
  409.         vldr    s12, [IN, #(2*8+2)*4]
  410.         vldr    s14, [IN, #(2*8+3)*4]
  411.         vldr    s16, [IN, #(2*8+4)*4]
  412.         vldr    s18, [IN, #(2*8+5)*4]
  413.         vldr    s20, [IN, #(2*8+6)*4]
  414.         vldr    s22, [IN, #(2*8+7)*4]
  415.         vldr    s9,  zero
  416.         vldr    s11, zero
  417.         vldr    s13, zero
  418.         vldr    s15, zero
  419.         vldr    s17, zero
  420.         vldr    s19, zero
  421.         vldr    s21, zero
  422.         vldr    s23, zero
  423.         vstr    d4,  [BUF, #(0*32+0)*4]
  424.         vstr    d5,  [BUF, #(1*32+0)*4]
  425.         vstr    d6,  [BUF, #(2*32+0)*4]
  426.         vstr    d7,  [BUF, #(3*32+0)*4]
  427.         vstr    d8,  [BUF, #(4*32+0)*4]
  428.         vstr    d9,  [BUF, #(5*32+0)*4]
  429.         vstr    d10, [BUF, #(6*32+0)*4]
  430.         vstr    d11, [BUF, #(7*32+0)*4]
  431.         add     BUF, BUF, #2*4
  432.         sub     COUNT, COUNT, #1
  433. 4:      @ Now fill the remainder with 0
  434.         vldr    s8, zero
  435.         vldr    s9, zero
  436.         ands    COUNT, COUNT, #0x1F
  437.         beq     6f
  438. 5:      vstr    d4, [BUF, #(0*32+0)*4]
  439.         vstr    d4, [BUF, #(1*32+0)*4]
  440.         vstr    d4, [BUF, #(2*32+0)*4]
  441.         vstr    d4, [BUF, #(3*32+0)*4]
  442.         vstr    d4, [BUF, #(4*32+0)*4]
  443.         vstr    d4, [BUF, #(5*32+0)*4]
  444.         vstr    d4, [BUF, #(6*32+0)*4]
  445.         vstr    d4, [BUF, #(7*32+0)*4]
  446.         add     BUF, BUF, #2*4
  447.         subs    COUNT, COUNT, #1
  448.         bne     5b
  449. 6:
  450.         fmxr    FPSCR, OLDFPSCR
  451.         ldr     WINDOW, [fp, #3*4]
  452.         ldr     OUT, [fp, #4*4]
  453.         sub     BUF, BUF, #32*4
  454. NOVFP   ldr     SCALEINT, [fp, #6*4]
  455.         mov     COUNT, #8
  456. VFP     vpush   {SCALE}
  457. VFP     sub     sp, sp, #3*4
  458. NOVFP   sub     sp, sp, #4*4
  459. 7:
  460. VFP     ldr     a1, [fp, #-7*4]     @ imdct
  461. NOVFP   ldr     a1, [fp, #-8*4]
  462.         ldmia   fp, {a2-a4}
  463. VFP     stmia   sp, {WINDOW, OUT, BUF}
  464. NOVFP   stmia   sp, {WINDOW, OUT, BUF, SCALEINT}
  465. VFP     vldr    SCALE, [sp, #3*4]
  466.         bl      X(ff_synth_filter_float_vfp)
  467.         add     OUT, OUT, #32*4
  468.         add     BUF, BUF, #32*4
  469.         subs    COUNT, COUNT, #1
  470.         bne     7b
  471.  
  472. A       sub     sp, fp, #(8+8)*4
  473. T       sub     fp, fp, #(8+8)*4
  474. T       mov     sp, fp
  475.         vpop    {s16-s23}
  476. VFP     pop     {a3-a4,v1-v3,v5,fp,pc}
  477. NOVFP   pop     {a4,v1-v5,fp,pc}
  478. endfunc
  479.  
  480.         .unreq  IN
  481.         .unreq  SBACT
  482.         .unreq  OLDFPSCR
  483.         .unreq  IMDCT
  484.         .unreq  WINDOW
  485.         .unreq  OUT
  486.         .unreq  BUF
  487.         .unreq  SCALEINT
  488.         .unreq  COUNT
  489.  
  490.         .unreq  SCALE
  491.  
  492.         .align 2
  493. zero:   .word   0
  494.