Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2014 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. .macro loadregoffsh2  group, index, base, offgroup, offindex
  25.        .altmacro
  26.        loadregoffsh2_ \group, %(\index), \base, \offgroup, %(\offindex)
  27.        .noaltmacro
  28. .endm
  29.  
  30. .macro loadregoffsh2_ group, index, base, offgroup, offindex
  31.         ldr     \group\index, [\base, \offgroup\offindex, lsl #2]
  32. .endm
  33.  
  34. .macro eorlslreg  check, data, group, index
  35.         .altmacro
  36.         eorlslreg_ \check, \data, \group, %(\index)
  37.         .noaltmacro
  38. .endm
  39.  
  40. .macro eorlslreg_ check, data, group, index
  41.         eor     \check, \check, \data, lsl \group\index
  42. .endm
  43.  
  44. .macro decr_modulo var, by, modulus
  45.  .set \var, \var - \by
  46.  .if \var == 0
  47.   .set \var, \modulus
  48.  .endif
  49. .endm
  50.  
  51.  .macro load_group1  size, channels, r0, r1, r2, r3, pointer_dead=0
  52.   .if \size == 2
  53.         ldrd    \r0, \r1, [IN], #(\size + 8 - \channels) * 4
  54.   .else // size == 4
  55.    .if IDX1 > 4 || \channels==8
  56.         ldm     IN!, {\r0, \r1, \r2, \r3}
  57.    .else
  58.         ldm     IN, {\r0, \r1, \r2, \r3}
  59.     .if !\pointer_dead
  60.         add     IN, IN, #(4 + 8 - \channels) * 4
  61.      .endif
  62.    .endif
  63.   .endif
  64.         decr_modulo IDX1, \size, \channels
  65.  .endm
  66.  
  67.  .macro load_group2  size, channels, r0, r1, r2, r3, pointer_dead=0
  68.   .if \size == 2
  69.    .if IDX1 > 2
  70.         ldm     IN!, {\r2, \r3}
  71.    .else
  72. //A   .ifc \r2, ip
  73. //A    .if \pointer_dead
  74. //A       ldm     IN, {\r2, \r3}
  75. //A    .else
  76. //A       ldr     \r2, [IN], #4
  77. //A       ldr     \r3, [IN], #(\size - 1 + 8 - \channels) * 4
  78. //A    .endif
  79. //A   .else
  80.         ldrd    \r2, \r3, [IN], #(\size + 8 - \channels) * 4
  81. //A   .endif
  82.    .endif
  83.   .endif
  84.         decr_modulo IDX1, \size, \channels
  85.  .endm
  86.  
  87. .macro implement_pack  inorder, channels, shift
  88. .if \inorder
  89. .ifc \shift, mixed
  90.  
  91. CHECK   .req    a1
  92. COUNT   .req    a2
  93. IN      .req    a3
  94. OUT     .req    a4
  95. DAT0    .req    v1
  96. DAT1    .req    v2
  97. DAT2    .req    v3
  98. DAT3    .req    v4
  99. SHIFT0  .req    v5
  100. SHIFT1  .req    v6
  101. SHIFT2  .req    sl
  102. SHIFT3  .req    fp
  103. SHIFT4  .req    ip
  104. SHIFT5  .req    lr
  105.  
  106.  .macro output4words
  107.   .set SIZE_GROUP1, IDX1
  108.   .if SIZE_GROUP1 > 4
  109.    .set SIZE_GROUP1, 4
  110.   .endif
  111.   .set SIZE_GROUP2, 4 - SIZE_GROUP1
  112.         load_group1  SIZE_GROUP1, \channels, DAT0, DAT1, DAT2, DAT3
  113.         load_group2  SIZE_GROUP2, \channels, DAT0, DAT1, DAT2, DAT3
  114.    .if \channels == 2
  115.         lsl     DAT0, SHIFT0
  116.         lsl     DAT1, SHIFT1
  117.         lsl     DAT2, SHIFT0
  118.         lsl     DAT3, SHIFT1
  119.    .elseif \channels == 6
  120.     .if IDX2 == 6
  121.         lsl     DAT0, SHIFT0
  122.         lsl     DAT1, SHIFT1
  123.         lsl     DAT2, SHIFT2
  124.         lsl     DAT3, SHIFT3
  125.     .elseif IDX2 == 2
  126.         lsl     DAT0, SHIFT4
  127.         lsl     DAT1, SHIFT5
  128.         lsl     DAT2, SHIFT0
  129.         lsl     DAT3, SHIFT1
  130.     .else // IDX2 == 4
  131.         lsl     DAT0, SHIFT2
  132.         lsl     DAT1, SHIFT3
  133.         lsl     DAT2, SHIFT4
  134.         lsl     DAT3, SHIFT5
  135.     .endif
  136.    .elseif \channels == 8
  137.     .if IDX2 == 8
  138.         uxtb    SHIFT0, SHIFT4, ror #0
  139.         uxtb    SHIFT1, SHIFT4, ror #8
  140.         uxtb    SHIFT2, SHIFT4, ror #16
  141.         uxtb    SHIFT3, SHIFT4, ror #24
  142.     .else
  143.         uxtb    SHIFT0, SHIFT5, ror #0
  144.         uxtb    SHIFT1, SHIFT5, ror #8
  145.         uxtb    SHIFT2, SHIFT5, ror #16
  146.         uxtb    SHIFT3, SHIFT5, ror #24
  147.     .endif
  148.         lsl     DAT0, SHIFT0
  149.         lsl     DAT1, SHIFT1
  150.         lsl     DAT2, SHIFT2
  151.         lsl     DAT3, SHIFT3
  152.    .endif
  153.         eor     CHECK, CHECK, DAT0, lsr #8 - (\channels - IDX2)
  154.         eor     CHECK, CHECK, DAT1, lsr #7 - (\channels - IDX2)
  155.    decr_modulo IDX2, 2, \channels
  156.         eor     CHECK, CHECK, DAT2, lsr #8 - (\channels - IDX2)
  157.         eor     CHECK, CHECK, DAT3, lsr #7 - (\channels - IDX2)
  158.    decr_modulo IDX2, 2, \channels
  159.         stm     OUT!, {DAT0 - DAT3}
  160.  .endm
  161.  
  162.  .set WORDS_PER_LOOP, \channels  // calculate LCM (channels, 4)
  163.  .if (WORDS_PER_LOOP % 2) == 0
  164.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  165.  .endif
  166.  .if (WORDS_PER_LOOP % 2) == 0
  167.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  168.  .endif
  169.  .set WORDS_PER_LOOP, WORDS_PER_LOOP * 4
  170.  .set SAMPLES_PER_LOOP, WORDS_PER_LOOP / \channels
  171.  
  172. function ff_mlp_pack_output_inorder_\channels\()ch_mixedshift_armv6, export=1
  173.  .if SAMPLES_PER_LOOP > 1
  174.         tst     COUNT, #SAMPLES_PER_LOOP - 1  // always seems to be in practice
  175.         it      ne
  176.         bne     X(ff_mlp_pack_output)         // but just in case, branch to C implementation if not
  177.  .endif
  178.         teq     COUNT, #0
  179.         it      eq
  180.         bxeq    lr
  181.         push    {v1-v6,sl,fp,lr}
  182.         ldr     SHIFT0, [sp, #(9+1)*4]  // get output_shift from stack
  183.         ldr     SHIFT1, =0x08080808
  184.         ldr     SHIFT4, [SHIFT0]
  185.  .if \channels == 2
  186.         uadd8   SHIFT4, SHIFT4, SHIFT1 // increase all shifts by 8
  187.         uxtb    SHIFT0, SHIFT4, ror #0
  188.         uxtb    SHIFT1, SHIFT4, ror #8
  189.  .else
  190.         ldr     SHIFT5, [SHIFT0, #4]
  191.         uadd8   SHIFT4, SHIFT4, SHIFT1 // increase all shifts by 8
  192.         uadd8   SHIFT5, SHIFT5, SHIFT1
  193.   .if \channels == 6
  194.         uxtb    SHIFT0, SHIFT4, ror #0
  195.         uxtb    SHIFT1, SHIFT4, ror #8
  196.         uxtb    SHIFT2, SHIFT4, ror #16
  197.         uxtb    SHIFT3, SHIFT4, ror #24
  198.         uxtb    SHIFT4, SHIFT5, ror #0
  199.         uxtb    SHIFT5, SHIFT5, ror #8
  200.   .endif
  201.  .endif
  202.  .set IDX1, \channels
  203.  .set IDX2, \channels
  204. 0:
  205.  .rept WORDS_PER_LOOP / 4
  206.         output4words
  207.  .endr
  208.         subs    COUNT, COUNT, #SAMPLES_PER_LOOP
  209.         bne     0b
  210.         pop     {v1-v6,sl,fp,pc}
  211.         .ltorg
  212. endfunc
  213.  .purgem output4words
  214.  
  215.         .unreq  CHECK
  216.         .unreq  COUNT
  217.         .unreq  IN
  218.         .unreq  OUT
  219.         .unreq  DAT0
  220.         .unreq  DAT1
  221.         .unreq  DAT2
  222.         .unreq  DAT3
  223.         .unreq  SHIFT0
  224.         .unreq  SHIFT1
  225.         .unreq  SHIFT2
  226.         .unreq  SHIFT3
  227.         .unreq  SHIFT4
  228.         .unreq  SHIFT5
  229.  
  230. .else // not mixed
  231.  
  232. CHECK   .req    a1
  233. COUNT   .req    a2
  234. IN      .req    a3
  235. OUT     .req    a4
  236. DAT0    .req    v1
  237. DAT1    .req    v2
  238. DAT2    .req    v3
  239. DAT3    .req    v4
  240. DAT4    .req    v5
  241. DAT5    .req    v6
  242. DAT6    .req    sl // use these rather than the otherwise unused
  243. DAT7    .req    fp // ip and lr so that we can load them usinf LDRD
  244.  
  245.  .macro output4words  tail, head, r0, r1, r2, r3, r4, r5, r6, r7, pointer_dead=0
  246.   .if \head
  247.    .set SIZE_GROUP1, IDX1
  248.    .if SIZE_GROUP1 > 4
  249.     .set SIZE_GROUP1, 4
  250.    .endif
  251.    .set SIZE_GROUP2, 4 - SIZE_GROUP1
  252.         load_group1  SIZE_GROUP1, \channels, \r0, \r1, \r2, \r3, \pointer_dead
  253.   .endif
  254.   .if \tail
  255.         eor     CHECK, CHECK, \r4, lsr #8 - (\channels - IDX2)
  256.         eor     CHECK, CHECK, \r5, lsr #7 - (\channels - IDX2)
  257.    decr_modulo IDX2, 2, \channels
  258.   .endif
  259.   .if \head
  260.         load_group2  SIZE_GROUP2, \channels, \r0, \r1, \r2, \r3, \pointer_dead
  261.   .endif
  262.   .if \tail
  263.         eor     CHECK, CHECK, \r6, lsr #8 - (\channels - IDX2)
  264.         eor     CHECK, CHECK, \r7, lsr #7 - (\channels - IDX2)
  265.    decr_modulo IDX2, 2, \channels
  266.         stm     OUT!, {\r4, \r5, \r6, \r7}
  267.   .endif
  268.   .if \head
  269.         lsl     \r0, #8 + \shift
  270.         lsl     \r1, #8 + \shift
  271.         lsl     \r2, #8 + \shift
  272.         lsl     \r3, #8 + \shift
  273.   .endif
  274.  .endm
  275.  
  276.  .set WORDS_PER_LOOP, \channels  // calculate LCM (channels, 8)
  277.  .if (WORDS_PER_LOOP % 2) == 0
  278.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  279.  .endif
  280.  .if (WORDS_PER_LOOP % 2) == 0
  281.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  282.  .endif
  283.  .if (WORDS_PER_LOOP % 2) == 0
  284.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  285.  .endif
  286.  .set WORDS_PER_LOOP, WORDS_PER_LOOP * 8
  287.  .set SAMPLES_PER_LOOP, WORDS_PER_LOOP / \channels
  288.  
  289. function ff_mlp_pack_output_inorder_\channels\()ch_\shift\()shift_armv6, export=1
  290.  .if SAMPLES_PER_LOOP > 1
  291.         tst     COUNT, #SAMPLES_PER_LOOP - 1  // always seems to be in practice
  292.         it      ne
  293.         bne     X(ff_mlp_pack_output)         // but just in case, branch to C implementation if not
  294.  .endif
  295.         subs    COUNT, COUNT, #SAMPLES_PER_LOOP
  296.         it      lo
  297.         bxlo    lr
  298.         push    {v1-v6,sl,fp,lr}
  299.  .set IDX1, \channels
  300.  .set IDX2, \channels
  301.         output4words  0, 1, DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7
  302. 0:      beq     1f
  303.  .rept WORDS_PER_LOOP / 8
  304.         output4words  1, 1, DAT4, DAT5, DAT6, DAT7, DAT0, DAT1, DAT2, DAT3
  305.         output4words  1, 1, DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7
  306.  .endr
  307.         subs    COUNT, COUNT, #SAMPLES_PER_LOOP
  308.         bne     0b
  309. 1:
  310.  .rept WORDS_PER_LOOP / 8 - 1
  311.         output4words  1, 1, DAT4, DAT5, DAT6, DAT7, DAT0, DAT1, DAT2, DAT3
  312.         output4words  1, 1, DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7
  313.  .endr
  314.         output4words  1, 1, DAT4, DAT5, DAT6, DAT7, DAT0, DAT1, DAT2, DAT3, pointer_dead=1
  315.         output4words  1, 0, DAT0, DAT1, DAT2, DAT3, DAT4, DAT5, DAT6, DAT7
  316.         pop     {v1-v6,sl,fp,pc}
  317. endfunc
  318.  .purgem output4words
  319.  
  320.         .unreq  CHECK
  321.         .unreq  COUNT
  322.         .unreq  IN
  323.         .unreq  OUT
  324.         .unreq  DAT0
  325.         .unreq  DAT1
  326.         .unreq  DAT2
  327.         .unreq  DAT3
  328.         .unreq  DAT4
  329.         .unreq  DAT5
  330.         .unreq  DAT6
  331.         .unreq  DAT7
  332.  
  333. .endif // mixed
  334. .else // not inorder
  335. .ifc \shift, mixed
  336.  
  337. // This case not currently handled
  338.  
  339. .else // not mixed
  340.  
  341. #if !CONFIG_THUMB
  342.  
  343. CHECK   .req    a1
  344. COUNT   .req    a2
  345. IN      .req    a3
  346. OUT     .req    a4
  347. DAT0    .req    v1
  348. DAT1    .req    v2
  349. DAT2    .req    v3
  350. DAT3    .req    v4
  351. CHAN0   .req    v5
  352. CHAN1   .req    v6
  353. CHAN2   .req    sl
  354. CHAN3   .req    fp
  355. CHAN4   .req    ip
  356. CHAN5   .req    lr
  357.  
  358.  .macro output4words
  359.   .if \channels == 8
  360.    .if IDX1 == 8
  361.         uxtb    CHAN0, CHAN4, ror #0
  362.         uxtb    CHAN1, CHAN4, ror #8
  363.         uxtb    CHAN2, CHAN4, ror #16
  364.         uxtb    CHAN3, CHAN4, ror #24
  365.    .else
  366.         uxtb    CHAN0, CHAN5, ror #0
  367.         uxtb    CHAN1, CHAN5, ror #8
  368.         uxtb    CHAN2, CHAN5, ror #16
  369.         uxtb    CHAN3, CHAN5, ror #24
  370.    .endif
  371.         ldr     DAT0, [IN, CHAN0, lsl #2]
  372.         ldr     DAT1, [IN, CHAN1, lsl #2]
  373.         ldr     DAT2, [IN, CHAN2, lsl #2]
  374.         ldr     DAT3, [IN, CHAN3, lsl #2]
  375.    .if IDX1 == 4
  376.         add     IN, IN, #8*4
  377.    .endif
  378.         decr_modulo IDX1, 4, \channels
  379.   .else
  380.    .set SIZE_GROUP1, IDX1
  381.    .if SIZE_GROUP1 > 4
  382.     .set SIZE_GROUP1, 4
  383.    .endif
  384.    .set SIZE_GROUP2, 4 - SIZE_GROUP1
  385.    .if SIZE_GROUP1 == 2
  386.         loadregoffsh2  DAT, 0, IN, CHAN, 0 + (\channels - IDX1)
  387.         loadregoffsh2  DAT, 1, IN, CHAN, 1 + (\channels - IDX1)
  388.         add     IN, IN, #8*4
  389.    .else // SIZE_GROUP1 == 4
  390.         loadregoffsh2  DAT, 0, IN, CHAN, 0 + (\channels - IDX1)
  391.         loadregoffsh2  DAT, 1, IN, CHAN, 1 + (\channels - IDX1)
  392.         loadregoffsh2  DAT, 2, IN, CHAN, 2 + (\channels - IDX1)
  393.         loadregoffsh2  DAT, 3, IN, CHAN, 3 + (\channels - IDX1)
  394.     .if IDX1 == 4
  395.         add     IN, IN, #8*4
  396.     .endif
  397.    .endif
  398.         decr_modulo IDX1, SIZE_GROUP1, \channels
  399.    .if SIZE_GROUP2 == 2
  400.         loadregoffsh2  DAT, 2, IN, CHAN, 0 + (\channels - IDX1)
  401.         loadregoffsh2  DAT, 3, IN, CHAN, 1 + (\channels - IDX1)
  402.     .if IDX1 == 2
  403.         add     IN, IN, #8*4
  404.     .endif
  405.    .endif
  406.         decr_modulo IDX1, SIZE_GROUP2, \channels
  407.   .endif
  408.   .if \channels == 8 // in this case we can corrupt CHAN0-3
  409.         rsb     CHAN0, CHAN0, #8
  410.         rsb     CHAN1, CHAN1, #8
  411.         rsb     CHAN2, CHAN2, #8
  412.         rsb     CHAN3, CHAN3, #8
  413.         lsl     DAT0, #8 + \shift
  414.         lsl     DAT1, #8 + \shift
  415.         lsl     DAT2, #8 + \shift
  416.         lsl     DAT3, #8 + \shift
  417.         eor     CHECK, CHECK, DAT0, lsr CHAN0
  418.         eor     CHECK, CHECK, DAT1, lsr CHAN1
  419.         eor     CHECK, CHECK, DAT2, lsr CHAN2
  420.         eor     CHECK, CHECK, DAT3, lsr CHAN3
  421.   .else
  422.    .if \shift != 0
  423.         lsl     DAT0, #\shift
  424.         lsl     DAT1, #\shift
  425.         lsl     DAT2, #\shift
  426.         lsl     DAT3, #\shift
  427.    .endif
  428.         bic     DAT0, DAT0, #0xff000000
  429.         bic     DAT1, DAT1, #0xff000000
  430.         bic     DAT2, DAT2, #0xff000000
  431.         bic     DAT3, DAT3, #0xff000000
  432.         eorlslreg CHECK, DAT0, CHAN, 0 + (\channels - IDX2)
  433.         eorlslreg CHECK, DAT1, CHAN, 1 + (\channels - IDX2)
  434.    decr_modulo IDX2, 2, \channels
  435.         eorlslreg CHECK, DAT2, CHAN, 0 + (\channels - IDX2)
  436.         eorlslreg CHECK, DAT3, CHAN, 1 + (\channels - IDX2)
  437.    decr_modulo IDX2, 2, \channels
  438.         lsl     DAT0, #8
  439.         lsl     DAT1, #8
  440.         lsl     DAT2, #8
  441.         lsl     DAT3, #8
  442.   .endif
  443.         stm     OUT!, {DAT0 - DAT3}
  444.  .endm
  445.  
  446.  .set WORDS_PER_LOOP, \channels  // calculate LCM (channels, 4)
  447.  .if (WORDS_PER_LOOP % 2) == 0
  448.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  449.  .endif
  450.  .if (WORDS_PER_LOOP % 2) == 0
  451.   .set WORDS_PER_LOOP, WORDS_PER_LOOP / 2
  452.  .endif
  453.  .set WORDS_PER_LOOP, WORDS_PER_LOOP * 4
  454.  .set SAMPLES_PER_LOOP, WORDS_PER_LOOP / \channels
  455.  
  456. function ff_mlp_pack_output_outoforder_\channels\()ch_\shift\()shift_armv6, export=1
  457.  .if SAMPLES_PER_LOOP > 1
  458.         tst     COUNT, #SAMPLES_PER_LOOP - 1  // always seems to be in practice
  459.         it      ne
  460.         bne     X(ff_mlp_pack_output)         // but just in case, branch to C implementation if not
  461.  .endif
  462.         teq     COUNT, #0
  463.         it      eq
  464.         bxeq    lr
  465.         push    {v1-v6,sl,fp,lr}
  466.         ldr     CHAN0, [sp, #(9+0)*4]  // get ch_assign from stack
  467.         ldr     CHAN4, [CHAN0]
  468.  .if \channels == 2
  469.         uxtb    CHAN0, CHAN4, ror #0
  470.         uxtb    CHAN1, CHAN4, ror #8
  471.  .else
  472.         ldr     CHAN5, [CHAN0, #4]
  473.   .if \channels == 6
  474.         uxtb    CHAN0, CHAN4, ror #0
  475.         uxtb    CHAN1, CHAN4, ror #8
  476.         uxtb    CHAN2, CHAN4, ror #16
  477.         uxtb    CHAN3, CHAN4, ror #24
  478.         uxtb    CHAN4, CHAN5, ror #0
  479.         uxtb    CHAN5, CHAN5, ror #8
  480.   .endif
  481.  .endif
  482.  .set IDX1, \channels
  483.  .set IDX2, \channels
  484. 0:
  485.  .rept WORDS_PER_LOOP / 4
  486.         output4words
  487.  .endr
  488.         subs    COUNT, COUNT, #SAMPLES_PER_LOOP
  489.         bne     0b
  490.         pop     {v1-v6,sl,fp,pc}
  491.         .ltorg
  492. endfunc
  493.  .purgem output4words
  494.  
  495.         .unreq  CHECK
  496.         .unreq  COUNT
  497.         .unreq  IN
  498.         .unreq  OUT
  499.         .unreq  DAT0
  500.         .unreq  DAT1
  501.         .unreq  DAT2
  502.         .unreq  DAT3
  503.         .unreq  CHAN0
  504.         .unreq  CHAN1
  505.         .unreq  CHAN2
  506.         .unreq  CHAN3
  507.         .unreq  CHAN4
  508.         .unreq  CHAN5
  509.  
  510. #endif // !CONFIG_THUMB
  511.  
  512. .endif // mixed
  513. .endif // inorder
  514. .endm // implement_pack
  515.  
  516. .macro pack_channels  inorder, channels
  517.         implement_pack  \inorder, \channels, 0
  518.         implement_pack  \inorder, \channels, 1
  519.         implement_pack  \inorder, \channels, 2
  520.         implement_pack  \inorder, \channels, 3
  521.         implement_pack  \inorder, \channels, 4
  522.         implement_pack  \inorder, \channels, 5
  523.         implement_pack  \inorder, \channels, mixed
  524. .endm
  525.  
  526. .macro pack_order  inorder
  527.         pack_channels  \inorder, 2
  528.         pack_channels  \inorder, 6
  529.         pack_channels  \inorder, 8
  530. .endm
  531.  
  532.         pack_order  0
  533.         pack_order  1
  534.