ycbcr422pl_to_rgb565_h.asm
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:31k
源码类别:

DSP编程

开发平台:

C/C++

  1. ;
  2. ;  Copyright 2003 by Texas Instruments Incorporated.
  3. ;  All rights reserved. Property of Texas Instruments Incorporated.
  4. ;  Restricted rights to use, duplicate or disclose this code are
  5. ;  granted through contract.
  6. ;  
  7. ;
  8. ; "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)"
  9. * ========================================================================= *
  10. *                                                                           *
  11. *   USAGE                                                                   *
  12. *       This function is C callable, and is called according to this        *
  13. *       C prototype:                                                        *
  14. *                                                                           *
  15. *       void ycbcr422pl_to_rgb565                                           *
  16. *       (                                                                   *
  17. *           const short         coeff[5],  -- Matrix coefficients.          *
  18. *           const unsigned char *y_data,   -- Luminence data  (Y')          *
  19. *           const unsigned char *cb_data,  -- Blue color-diff (B'-Y')       *
  20. *           const unsigned char *cr_data,  -- Red color-diff  (R'-Y')       *
  21. *           unsigned short      *rgb_data, -- RGB 5:6:5 packed pixel out.   *
  22. *           unsigned            num_pixels -- # of luma pixels to process.  *
  23. *       )                                                                   *
  24. *                                                                           *
  25. *       The 'coeff[]' array contains the color-space-conversion matrix      *
  26. *       coefficients.  The 'y_data', 'cb_data' and 'cr_data' pointers       *
  27. *       point to the separate input image planes.  The 'rgb_data' pointer   *
  28. *       points to the output image buffer, and must be word aligned.        *
  29. *                                                                           *
  30. *       The kernel is designed to process arbitrary amounts of 4:2:2        *
  31. *       image data, although 4:2:0 image data may be processed as well.     *
  32. *       For 4:2:2 input data, the 'y_data', 'cb_data' and 'cr_data'         *
  33. *       arrays may hold an arbitrary amount of image data.  For 4:2:0       *
  34. *       input data, only a single scan-line (or portion thereof) may be     *
  35. *       processed at a time.                                                *
  36. *                                                                           *
  37. *       The coefficients in the coeff array must be in signed Q13 form.     *
  38. *       These coefficients correspond to the following matrix equation:     *
  39. *                                                                           *
  40. *           [ Y' -  16 ]   [ coeff[0] 0.0000   coeff[1] ]     [ R']         *
  41. *           [ Cb - 128 ] * [ coeff[0] coeff[2] coeff[3] ]  =  [ G']         *
  42. *           [ Cr - 128 ]   [ coeff[0] coeff[4] 0.0000   ]     [ B']         *
  43. *                                                                           *
  44. *   DESCRIPTION                                                             *
  45. *       This function runs for 46 + (num_pixels * 3) cycles, including      *
  46. *       6 cycles of function-call overhead.  Interrupts are masked for      *
  47. *       37 + (num_pixels * 3) cycles.  Code size is 512 bytes.              *
  48. *                                                                           *
  49. *       This kernel performs Y'CbCr to RGB conversion.  From the Color      *
  50. *       FAQ, http://home.inforamp.net/~poynton/ColorFAQ.html :              *
  51. *                                                                           *
  52. *           Various scale factors are applied to (B'-Y') and (R'-Y')        *
  53. *           for different applications.  The Y'PbPr scale factors are       *
  54. *           optimized for component analog video.  The Y'CbCr scaling       *
  55. *           is appropriate for component digital video, JPEG and MPEG.      *
  56. *           Kodak's PhotoYCC(tm) uses scale factors optimized for the       *
  57. *           gamut of film colors.  Y'UV scaling is appropriate as an        *
  58. *           intermediate step in the formation of composite NTSC or PAL     *
  59. *           video signals, but is not appropriate when the components       *
  60. *           are keps separate.  Y'UV nomenclature is now used rather        *
  61. *           loosely, and it sometimes denotes any scaling of (B'-Y')        *
  62. *           and (R'-Y').  Y'IQ coding is obsolete.                          *
  63. *                                                                           *
  64. *       This code can perform various flavors of Y'CbCr to RGB conversion   *
  65. *       as long as the offsets on Y, Cb, and Cr are -16, -128, and -128,    *
  66. *       respectively, and the coefficients match the pattern shown.         *
  67. *                                                                           *
  68. *       The kernel implements the following matrix form, which involves 5   *
  69. *       unique coefficients:                                                *
  70. *                                                                           *
  71. *           [ Y' -  16 ]   [ coeff[0] 0.0000   coeff[1] ]     [ R']         *
  72. *           [ Cb - 128 ] * [ coeff[0] coeff[2] coeff[3] ]  =  [ G']         *
  73. *           [ Cr - 128 ]   [ coeff[0] coeff[4] 0.0000   ]     [ B']         *
  74. *                                                                           *
  75. *                                                                           *
  76. *       Below are some common coefficient sets, along with the matrix       *
  77. *       equation that they correspond to.   Coefficients are in signed      *
  78. *       Q13 notation, which gives a suitable balance between precision      *
  79. *       and range.                                                          *
  80. *                                                                           *
  81. *       1.  Y'CbCr -> RGB conversion with RGB levels that correspond to     *
  82. *           the 219-level range of Y'.  Expected ranges are [16..235] for   *
  83. *           Y' and [16..240] for Cb and Cr.                                 *
  84. *                                                                           *
  85. *           coeff[] = { 0x2000, 0x2BDD, -0x0AC5, -0x1658, 0x3770 };         *
  86. *                                                                           *
  87. *           [ Y' -  16 ]   [ 1.0000    0.0000    1.3707 ]     [ R']         *
  88. *           [ Cb - 128 ] * [ 1.0000   -0.3365   -0.6982 ]  =  [ G']         *
  89. *           [ Cr - 128 ]   [ 1.0000    1.7324    0.0000 ]     [ B']         *
  90. *                                                                           *
  91. *       2.  Y'CbCr -> RGB conversion with the 219-level range of Y'         *
  92. *           expanded to fill the full RGB dynamic range.  (The matrix has   *
  93. *           been scaled by 255/219.)  Expected ranges are [16..235] for Y'  *
  94. *           and [16..240] for Cb and Cr.                                    *
  95. *                                                                           *
  96. *           coeff[] = { 0x2543, 0x3313, -0x0C8A, -0x1A04, 0x408D };         *
  97. *                                                                           *
  98. *           [ Y' -  16 ]   [ 1.1644    0.0000    1.5960 ]     [ R']         *
  99. *           [ Cb - 128 ] * [ 1.1644   -0.3918   -0.8130 ]  =  [ G']         *
  100. *           [ Cr - 128 ]   [ 1.1644    2.0172    0.0000 ]     [ B']         *
  101. *                                                                           *
  102. *       Other scalings of the color differences (B'-Y') and (R'-Y')         *
  103. *       (sometimes incorrectly referred to as U and V) are supported, as    *
  104. *       long as the color differences are unsigned values centered around   *
  105. *       128 rather than signed values centered around 0, as noted above.    *
  106. *                                                                           *
  107. *       In addition to performing plain color-space conversion, color       *
  108. *       saturation can be adjusted by scaling coeff[1] through coeff[4].    *
  109. *       Similarly, brightness can be adjusted by scaling coeff[0].          *
  110. *       General hue adjustment can not be performed, however, due to the    *
  111. *       two zeros hard-coded in the matrix.                                 *
  112. *                                                                           *
  113. *   TECHNIQUES                                                              *
  114. *       Pixel replication is performed implicitly on chroma data to         *
  115. *       reduce the total number of multiplies required.  The chroma         *
  116. *       portion of the matrix is calculated once for each Cb, Cr pair,      *
  117. *       and the result is added to both Y' samples.                         *
  118. *                                                                           *
  119. *       Luma is biased downwards to produce R, G, and B values that are     *
  120. *       signed quantities centered around zero, rather than unsigned qtys.  *
  121. *       This allows us to use SSHL to perform saturation, followed by a     *
  122. *       quick XOR to correct the sign bits in the final packed pixels.      *
  123. *       The required downward bias is 128 shifted left by the Q-point, 13.  *
  124. *                                                                           *
  125. *       To save two instructions, I transformed "(y0-16)*luma - (128<<13)"  *
  126. *       to the slightly more cryptic "y0*luma - (16*luma + (128<<13))".     *
  127. *       This gives me the non-obvious but effective y_bias value            *
  128. *       -((128 << 13) + 16*luma).  The transformation allows me to fit in   *
  129. *       a 6 cycle loop.                                                     *
  130. *                                                                           *
  131. *       Twin pointers are used for the stack and coeff[] arrays for speed.  *
  132. *                                                                           *
  133. *       Because the loop accesses four different arrays at three different  *
  134. *       strides, no memory accesses are allowed to parallelize in the       *
  135. *       loop.  No bank conflicts occur, as a result.                        *
  136. *                                                                           *
  137. *       Creatively constructed multiplies are used to avoid a bottleneck    *
  138. *       on shifts in the loop.  In particular, the 5-bit mask 0xF8000000    *
  139. *       doubles as a right-shift constant that happens to negate while      *
  140. *       shifting.  This negation is reversed by merging the bits with a     *
  141. *       SUB instead of an ADD or OR.                                        *
  142. *                                                                           *
  143. *       Prolog and epilog collapsing have been performed, with only a       *
  144. *       partial stage of prolog and epilog left uncollapsed.  The partial   *
  145. *       stages are interscheduled with the rest of the code for speed.      *
  146. *                                                                           *
  147. *       The stack pointer is saved in IRP to allow all 32 registers to      *
  148. *       be used in the loop.  This enabled prolog collapsing by freeing     *
  149. *       up a predicate register.  The prolog collapse counter is            *
  150. *       implemented as a MPY which shifts a constant left by 3 bits each    *
  151. *       iteration.  The counter is initialized from one of the other        *
  152. *       constant registers, thereby reducing the S-unit bottleneck in the   *
  153. *       setup code.                                                         *
  154. *                                                                           *
  155. *       Instructions have been scheduled to minimize fetch-packet padding   *
  156. *       NOPs.  Only 3 padding NOPs and 1 explicit NOP remain.               *
  157. *                                                                           *
  158. *   ASSUMPTIONS                                                             *
  159. *       An even number of luma samples needs to be processed.               *
  160. *                                                                           *
  161. *       The output image must be word aligned.                              *
  162. *                                                                           *
  163. *   NOTES                                                                   *
  164. *       No bank conflicts occur.                                            *
  165. *                                                                           *
  166. *       Codesize is 512 bytes.                                              *
  167. *                                                                           *
  168. *       On average, one bank per cycle is accessed on a C6201 in the loop,  *
  169. *       with 1 cycle of 6 accessing no banks, and 1 cycle accessing two.    *
  170. *                                                                           *
  171. *       The kernel requires 14 words of stack space.                        *
  172. *                                                                           *
  173. *   SOURCE                                                                  *
  174. *       Poynton, Charles et al.  "The Color FAQ,"  1999.                    *
  175. *           http://home.inforamp.net/~poynton/ColorFAQ.html                 *
  176. *                                                                           *
  177. * ------------------------------------------------------------------------- *
  178. *             Copyright (c) 1999 Texas Instruments, Incorporated.           *
  179. *                            All Rights Reserved.                           *
  180. * ========================================================================= *
  181.                 .sect ".data:copyright_h"
  182. _Copyright:     .string "Copyright (C) 1999 Texas Instruments Incorporated. "
  183.                 .string "All Rights Reserved.",0
  184.                 .sect ".text:hand"
  185.                 .global _yc2rgb16
  186. _yc2rgb16:
  187. ; =============== SYMBOLIC REGISTER ASSIGNMENTS: ARGUMENTS ================ ;
  188.         .asg            A4,         A_coef      ; Coefficients table
  189.         .asg            B4,         B_y_data    ; Pointer to luma
  190.         .asg            A6,         A_cb_data   ; Pointer to B-Y
  191.         .asg            B6,         B_cr_data   ; Pointer to R-Y
  192.         .asg            A8,         A_rgb_data  ; Pointer to RGB output
  193.         .asg            B8,         B_num_pix   ; # of pixels to process
  194. ; ================= SYMBOLIC REGISTER ASSIGNMENTS: SETUP ================== ;
  195.         .asg            B15,        B_SP        ; Stack pointer, B datapath
  196.         .asg            A3,         A_SP        ; Stack pointer, A datapath
  197.         .asg            B0,         B_csr       ; CSR's value
  198.         .asg            B1,         B_noGIE     ; CSR w/ GIE bit cleared
  199.         .asg            B2,         B_irp       ; IRP's value
  200.         .asg            A0,         A_csr       ; Copy of CSR's value
  201.         .asg            B3,         B_ret       ; Return address
  202.         .asg            B7,         B_coef      ; Twin coefficients ptr.
  203.         .asg            A13,        A_rcr       ; Cr's contribution to Red
  204.         .asg            B14,        B_bcb       ; Cb's contribution to Blu
  205.         .asg            A5,         A_gcr_      ; Cr's contribution to Grn
  206.         .asg            A5,         A_gcr       ; A_gcr_ << 16
  207.         .asg            B5,         B_gcb_      ; Cb's contribution to Grn
  208.         .asg            B5,         B_gcb       ; B_gcb_ << 16
  209.         .asg            A1,         A_lneg      ; luma coeff[0] < 0
  210. ; ================= SYMBOLIC REGISTER ASSIGNMENTS: KERNEL ================= ;
  211.         .asg            B0,         B_p         ; Prolog collapse counter
  212.         .asg            A2,         A_i         ; Loop trip counter
  213.         .asg            A10,        A_y_ptr     ; Luma data pointer
  214.         .asg            B15,        B_cb_ptr    ; B-Y data pointer
  215.         .asg            B6,         B_cr_ptr    ; R-Y data pointer
  216.         .asg            B11,        B_rgb_ptr   ; RGB output data pointer
  217.         .asg            B12,        B_k32_k128  ; Constant 0x00200080
  218.         .asg            A11,        A_k32_k128  ; Constant 0x00200080
  219.         .asg            A12,        A_one_lum   ; Constant 1 packed w/coeff[0]
  220.         .asg            A13,        A_gcr_rcr   ; coeff[3], coeff[1] packed
  221.         .asg            B14,        B_gcb_bcb   ; coeff[2], coeff[4] packed
  222.         .asg            B10,        B_y_bias    ; -((128<<13) + 16*coeff[0])
  223.         .asg            B13,        B_ms5       ; Mask:  upper 5 bits
  224.         .asg            A14,        A_ms6       ; Mask:  upper 6 bits
  225.         .asg            A15,        A_sflip     ; Sign-flip const 0x84108410
  226.         .asg            A0,         A_y0        ; y0 value from y_data[]
  227.         .asg            B4,         B_y1        ; y1 value from y_data[]
  228.         .asg            B1,         B_cb_       ; cb value prior to level shift
  229.         .asg            A3,         A_cr_       ; cr value prior to level shift
  230.         .asg            B3,         B_cb        ; level-shifted cb value.
  231.         .asg            A4,         A_cr        ; level-shifted cr value
  232.         .asg            B5,         B_y1t_      ; scaled y1, before level shift
  233.         .asg            A3,         A_y0t_      ; scaled y0, before level shift
  234.         .asg            B9,         B_y1t       ; scaled, level-shifted y1
  235.         .asg            A5,         A_y0t       ; scaled, level-shifted y0
  236.         .asg            B3,         B_bt        ; Scaled blue color-diff
  237.         .asg            B1,         B_gt_       ; Scaled green color-diff (a)
  238.         .asg            A8,         A_gt_       ; Scaled green color-diff (b)
  239.         .asg            A6,         A_gt        ; Scaled green color-diff
  240.         .asg            A9,         A_rt        ; Scaled red color-diff
  241.         .asg            B1,         B_r1        ; Pixel 1 red  (16Q16)
  242.         .asg            B3,         B_g1        ; Pixel 1 grn  (17Q15)
  243.         .asg            B4,         B_b1        ; Pixel 1 blu  (16Q16)
  244.         .asg            A3,         A_r0        ; Pixel 0 red  (16Q16)
  245.         .asg            A5,         A_g0        ; Pixel 0 grn  (17Q15)
  246.         .asg            A0,         A_b0        ; Pixel 0 blu  (16Q16)
  247.         .asg            B5,         B_r1s       ; Saturated pixel 1 red (5Q27)
  248.         .asg            B4,         B_g1s       ; Saturated pixel 1 grn (6Q26)
  249.         .asg            B5,         B_b1s       ; Saturated pixel 1 blu (5Q27)
  250.         .asg            A1,         A_r0s       ; Saturated pixel 0 red (5Q27)
  251.         .asg            A4,         A_g0s       ; Saturated pixel 0 grn (6Q26)
  252.         .asg            A4,         A_b0s       ; Saturated pixel 0 blu (5Q27)
  253.         .asg            B8,         B_r1t       ; Truncated pixel 1 red
  254.         .asg            B7,         B_g1t       ; Truncated pixel 1 grn
  255.         .asg            B2,         B_b1t       ; Truncated pixel 1 blu
  256.         .asg            A7,         A_r0t       ; Truncated pixel 0 red
  257.         .asg            A4,         A_g0t       ; Truncated pixel 0 grn
  258.         .asg            A5,         A_b0t       ; Truncated pixel 0 blu
  259.         .asg            B2,         B_g1f       ; Pixel 1 grn in final position
  260.         .asg            B1,         B_b1f       ; Pixel 1 blu in final position
  261.         .asg            B8,         B_r_b1      ; Pixel 1 red, blue merged
  262.         .asg            B4,         B_rgb1      ; Pixel 1 red, grn, blu merged
  263.         .asg            A3,         A_g0f       ; Pixel 0 grn in final position
  264.         .asg            A6,         A_b0f       ; Pixel 0 blu in final position
  265.         .asg            A7,         A_r_b0      ; Pixel 0 red, blue merged
  266.         .asg            A9,         A_rgb0_     ; Pixel 0 red, grn, blu merged
  267.         .asg            A6,         A_rgb0      ; Pixel 0 in low half word
  268.         .asg            B5,         B_rgb_      ; Combined pixels pre-sign-fix
  269.         .asg            B7,         B_rgb       ; Combined pixels w/ sign-fix
  270. ; ========================================================================= ;
  271.         ; Stack frame.  14 words:  A10..A15, B10..B14, B3, CSR, IRP
  272. ;-
  273.         STW     .D2T1   A15,        *B_SP--[14]         ; Save A15, get stack
  274. ||      MVC     .S2     CSR,        B_csr               ; Capture CSR's state
  275. ||      MV      .L2X    A_coef,     B_coef              ; Twin coef pointer
  276. ||      MVK     .S1     0xFFFF8410, A_sflip             ; Sign-flip cst, low
  277.         MV      .S1X    B_SP,       A_SP                ; Twin Stack Pointer
  278. ||      AND     .L2     B_csr,      -2,         B_noGIE ; Clear GIE
  279. ||      LDHU    .D1T2   *A_coef[2], B_gcb_              ; gcb = coeff[2]
  280. ||      LDHU    .D2T1   *B_coef[3], A_gcr_              ; gcb = coeff[3]
  281. ;-
  282.         STW     .D1T1   A14,        *+A_SP[12]          ; Save A14
  283. ||      STW     .D2T2   B14,        *+B_SP[11]          ; Save B14
  284. ||      MVC     .S2     B_noGIE,    CSR                 ; Disable interrupts
  285. ||      ZERO    .L1     A_ms6                           ; Mask 6, low
  286. ; ===== Interrupts masked here =====
  287.         STW     .D1T1   A13,        *+A_SP[10]          ; Save A13
  288. ||      STW     .D2T2   B13,        *+B_SP[ 9]          ; Save B13
  289. ||      MVC     .S2     IRP,        B_irp               ; Capture IRP's state
  290. ||      ZERO    .L2     B_ms5                           ; Mask 5, low
  291. ;-
  292.         STW     .D1T1   A12,        *+A_SP[ 8]          ; Save A12
  293. ||      STW     .D2T2   B12,        *+B_SP[ 7]          ; Save B12
  294. ||      MVC     .S2     B_SP,       IRP                 ; Save SP in IRP
  295. ||      MVKLH   .S1     0xFC00,     A_ms6               ; Mask 6, high
  296.         LDH     .D1T1   *A_coef[0], A_one_lum           ; lum = coeff[0]
  297. ||      MV      .L1X    B_csr,      A_csr               ; Partitioning MV
  298.         STW     .D1T1   A11,        *+A_SP[ 6]          ; Save A11
  299. ||      STW     .D2T2   B11,        *+B_SP[ 5]          ; Save B11
  300. ;-
  301.         LDHU    .D2T1   *B_coef[1], A_rcr               ; rcr = coeff[1]
  302. ||      LDHU    .D1T2   *A_coef[4], B_bcb               ; rcr = coeff[2]
  303.         STW     .D1T1   A10,        *+A_SP[ 4]          ; Save A10
  304. ||      STW     .D2T2   B10,        *+B_SP[ 3]          ; Save B10
  305. ||      MV      .L1X    B_y_data,   A_y_ptr             ; Partitioning MV
  306.         STW     .D1T1   A_csr,      *+A_SP[ 2]          ; Save CSR
  307. ||      STW     .D2T2   B_ret,      *+B_SP[ 1]          ; Save return address
  308. ||      MVK     .S2     128,        B_k32_k128          ; Constant: 128
  309. ;-
  310. ; =========================== PIPE LOOP PROLOG ============================ ;
  311.         LDBU    .D2T1   *B_cr_ptr++,            A_cr_   ;[ 1,1] cr = *cr_ptr++
  312. ||      AND     .L1X    B_num_pix,  -2,         A_i     ; Make num_pix even
  313. ||      MV      .L2X    A_cb_data,  B_cb_ptr            ; Partitioning MV
  314. ||      MVKLH   .S1     1,          A_one_lum           ; Constant: 1
  315. ||      MVKLH   .S2     32,         B_k32_k128          ; Constant: 32
  316. ||      MPY     .M2     B_k32_k128, 1,          B_p     ; Prolog collapse count
  317. ||      MPYH    .M1     A_one_lum,  A_one_lum,  A_lneg  ; lneg = coeff[0] < 0
  318. ;-
  319.         LDBU    .D1T1   *A_y_ptr++[2],          A_y0    ;[ 2,1] y0 = *y_ptr++
  320. ||      SHL     .S2X    A_one_lum,  4,          B_y_bias; ((128<<13)+16*luma)
  321. ||      MVKH    .S1     0x84108410, A_sflip             ; Sign-flip cst, high
  322.         LDBU    .D2T2   *B_cb_ptr++,            B_cb_   ;[ 3,1] cb = *cb_ptr++
  323. ||      ADD     .D1     A_i,        2,          A_i     ; Adjust for para iter
  324. ||      SHL     .S1     A_lneg,     20,         A_lneg  ; Handle luma < 0
  325. ||      MV      .L1X    B_k32_k128, A_k32_k128          ; Twin constant reg.
  326. ||      MV      .L2X    A_rgb_data, B_rgb_ptr           ; Partitioning MV
  327. ;-
  328.         LDBU    .D1T2   *-A_y_ptr[1],           B_y1    ;[ 4,1] y1 = *y_ptr++
  329. ||      SHL     .S1     A_gcr_,     16,         A_gcr   ; Put gcr in high half
  330. ||      SHL     .S2     B_gcb_,     16,         B_gcb   ; Put gcb in high half
  331. ||      SUB     .L2X    B_y_bias,   A_lneg,     B_y_bias; Sign bit, coeff[0]<0
  332.         STW     .D1T2   B_irp,      *+A_SP[13]          ; Save IRP
  333. ||      ADD     .L1     A_gcr,      A_rcr,      A_gcr_rcr ; Merge gcr, rcr
  334. ||      ADD     .L2     B_gcb,      B_bcb,      B_gcb_bcb ; Merge gcb, rcb
  335. ||      MVKLH   .S2     0xF800,     B_ms5               ; Mask 5, high
  336. ;-
  337. ; =========================== PIPE LOOP KERNEL ============================ ;
  338. conv_loop:
  339.   [ A_i]B       .S1     conv_loop                       ;[24,1] while (i)
  340. ||      ADD     .L2X    B_rgb1,     A_rgb0,     B_rgb_  ;[24,1] merge pix 0, 1
  341. ||      MPYHUS  .M1X    A_g0t,      B_ms5,      A_g0f   ;[18,2] >> 5 and negate
  342. ||      SSHL    .S2     B_g1,       11,         B_g1s   ;[18,2] g1s = sat(g1)
  343. ||      ADD     .D1     A_y0t,      A_rt,       A_r0    ;[12,3] r0  = y0t + rt
  344. ||      SUB     .D2     B_y1t_,     B_y_bias,   B_y1t   ;[12,3] y1t-= y_bias
  345. ||      SUB     .L1     A_cr_,      A_k32_k128, A_cr    ;[ 6,4] cr -= 128
  346. ||      MPYUS   .M2     B_p,        8,          B_p     ; prolog collapse count
  347. ;-
  348.         ADD     .D1     A_r0t,      A_b0f,      A_r_b0  ;[19,2] Merge r0, b0
  349. ||      MPYHU   .M2     B_b1t,      B_k32_k128, B_b1f   ;[19,2] >> 11
  350. ||      AND     .S2X    B_g1s,      A_ms6,      B_g1t   ;[19,2] g1t = g1s & ms6
  351. ||      SSHL    .S1     A_r0,       11,         A_r0s   ;[13,3] r0s = sat(r0)
  352. ||      ADD     .L2     B_y1t,      B_bt,       B_b1    ;[13,3] b1  = y1t + bt
  353. ||      ADD     .L1X    B_gt_,      A_gt_,      A_gt    ;[13,3]gt=gcr*cr+gcb*cb
  354. ||      MPYLH   .M1     A_cr,       A_gcr_rcr,  A_gt_   ;[ 7,4] gcr *c r
  355. ||      LDBU    .D2T1   *B_cr_ptr++,            A_cr_   ;[ 1,5] cr  = *cr_ptr++
  356. ;-
  357.         XOR     .L2X    B_rgb_,     A_sflip,    B_rgb   ;[26,1] Fix sign bits
  358. ||      MPYHUS  .M2     B_g1t,      B_ms5,      B_g1f   ;[20,2] >> 5 and negate
  359. ||      SSHL    .S2     B_b1,       11,         B_b1s   ;[14,3] b1s = sat(b1)
  360. ||      ADD     .L1X    A_y0t,      B_bt,       A_b0    ;[14,3] b0  = y0t + bt
  361. ||      ADD     .S1     A_y0t,      A_gt,       A_g0    ;[14,3] g0  = y0t + gt
  362. ||      MPY     .M1     A_y0,       A_one_lum,  A_y0t_  ;[ 8,4] y0t = y0 * luma
  363. ||      SUB     .D2     B_cb_,      B_k32_k128, B_cb    ;[ 8,4] cb -= 128
  364. ||      LDBU    .D1T1   *A_y_ptr++[2],          A_y0    ;[ 2,5] y0  = *y_ptr++
  365. ;-
  366.         SUB     .D1     A_r_b0,     A_g0f,      A_rgb0_ ;[21,2] merge r0,g0,b0
  367. ||      ADD     .L2     B_r1t,      B_b1f,      B_r_b1  ;[21,2] merge r1, b1
  368. ||      AND     .L1X    A_r0s,      B_ms5,      A_r0t   ;[15,3] r0s = r0t & ms5
  369. ||      SSHL    .S1     A_b0,       11,         A_b0s   ;[15,3] b0s = sat(b0)
  370. ||      ADD     .S2X    B_y1t,      A_rt,       B_r1    ;[15,3] r1  = y1t + rt
  371. ||      MPY     .M1     A_cr,       A_gcr_rcr,  A_rt    ;[ 9,4] rt  = rcr * cr
  372. ||      MPYLH   .M2     B_cb,       B_gcb_bcb,  B_gt_   ;[ 9,4] gcb * cb
  373. ||      LDBU    .D2T2   *B_cb_ptr++,            B_cb_   ;[ 3,5] cb  = *cb_ptr++
  374. ;-
  375.         MPYHU   .M1     A_rgb0_,    A_one_lum,  A_rgb0  ;[22,2] rgb0 in lo half
  376. ||      SUB     .D2     B_r_b1,     B_g1f,      B_rgb1  ;[22,2] merge r1,g1,b1
  377. ||      AND     .L1X    A_b0s,      B_ms5,      A_b0t   ;[16,3] b0t = b0s & ms5
  378. ||      AND     .L2     B_b1s,      B_ms5,      B_b1t   ;[16,3] b1t = b1s & ms5
  379. ||      SSHL    .S1     A_g0,       11,         A_g0s   ;[16,3] g0s = sat(g0)
  380. ||      SSHL    .S2     B_r1,       11,         B_r1s   ;[16,3] r1s = sat(r1)
  381. ||      MPY     .M2X    B_y1,       A_one_lum,  B_y1t_  ;[10,4] y1t = y1 * luma
  382. ||      LDBU    .D1T2   *-A_y_ptr[1],           B_y1    ;[ 4,5] y1  = *y_ptr++
  383. ;-
  384.   [!B_p]STW     .D2T2   B_rgb,      *B_rgb_ptr++        ;[29,1] *rgb_ptr++=rgb
  385. ||      SUB     .D1     A_i,        2,          A_i     ;[23,2] i -= 2
  386. ||      MPYHU   .M1     A_b0t,      A_k32_k128, A_b0f   ;[17,3] >> 11
  387. ||      AND     .L1     A_g0s,      A_ms6,      A_g0t   ;[17,3] g0t = g0s & ms6
  388. ||      AND     .L2     B_r1s,      B_ms5,      B_r1t   ;[17,3] r1t = r1s & ms5
  389. ||      ADD     .S2X    B_y1t,      A_gt,       B_g1    ;[17,3] g1  = y1t + gt
  390. ||      MPY     .M2     B_cb,       B_gcb_bcb,  B_bt    ;[11,4] bt  = bcb * cb
  391. ||      SUB     .S1X    A_y0t_,     B_y_bias,   A_y0t   ;[11,4] y0t-= y_bias
  392. ; =========================== PIPE LOOP EPILOG ============================ ;
  393. ; ================ SYMBOLIC REGISTER ASSIGNMENTS: CLEANUP ================= ;
  394.         .asg            B15,        B_SP                ; Stack ptr, B side
  395.         .asg            A3,         A_SP                ; Stack ptr, A side
  396.         .asg            A0,         A_csr               ; CSR value
  397.         .asg            B0,         B_irp               ; IRP value
  398.         .asg            B3,         B_ret               ; Return address
  399. ; ========================================================================= ;
  400. ;-
  401.         MVC     .S2     IRP,        B_SP                ; Restore stack ptr
  402. ||      ADD     .L2X    B_rgb1,     A_rgb0,     B_rgb_  ;[24,5] merge pix 0, 1
  403.         MV      .L1X    B_SP,       A_SP                ; Twin Stack Pointer
  404. ||      LDW     .D2T2   *+B_SP[13], B_irp               ; Get IRP's value
  405.         LDW     .D1T2   *+A_SP[ 1], B_ret               ; Get return address
  406. ||      LDW     .D2T1   *+B_SP[ 2], A_csr               ; Get CSR's value
  407.         LDW     .D1T2   *+A_SP[ 3], B10                 ; Restore B10
  408. ||      LDW     .D2T1   *+B_SP[ 4], A10                 ; Restore A10
  409. ;-
  410.         LDW     .D1T2   *+A_SP[11], B14                 ; Restore B14
  411. ||      LDW     .D2T1   *+B_SP[12], A14                 ; Restore A14
  412. ||      XOR     .L2X    B_rgb_,     A_sflip,    B_rgb   ;[26,5] fix sign bits
  413.         LDW     .D1T2   *+A_SP[ 7], B12                 ; Restore B12
  414. ||      LDW     .D2T1   *+B_SP[ 8], A12                 ; Restore A12
  415.         LDW     .D1T2   *+A_SP[ 9], B13                 ; Restore B13
  416. ||      LDW     .D2T1   *+B_SP[10], A13                 ; Restore A13
  417. ||      MVC     .S2     B_irp,      IRP                 ; Restore IRP
  418. ;-
  419.         LDW     .D1T2   *+A_SP[ 5], B11                 ; Restore B11
  420. ||      LDW     .D2T1   *+B_SP[ 6], A11                 ; Restore A11
  421. ||      B       .S2     B_ret                           ; Return to caller
  422.         MVC     .S2X    A_csr,      CSR                 ; Restore CSR
  423. ||      LDW     .D2T1   *++B_SP[14],A15                 ; Restore A15
  424. ; ===== Interruptibility state (GIE) restored here =====
  425.         STW     .D2T2   B_rgb,      *B_rgb_ptr          ;[29,5] *rgb_ptr++=rgb
  426.         NOP             3
  427. ; ===== Branch occurs =====
  428. ; ===== Interrupts may occur here =====
  429. * ========================================================================= *
  430. *   End of file:  ycbcr422pl_to_rgb565_h.asm                                *
  431. * ------------------------------------------------------------------------- *
  432. *             Copyright (c) 1999 Texas Instruments, Incorporated.           *
  433. *                            All Rights Reserved.                           *
  434. * ========================================================================= *