1606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes/*
2606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** Copyright 2015, The Android Open Source Project
3606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes**
4606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** Licensed under the Apache License, Version 2.0 (the "License");
5606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** you may not use this file except in compliance with the License.
6606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** You may obtain a copy of the License at
7606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes**
8606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes**     http://www.apache.org/licenses/LICENSE-2.0
9606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes**
10606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** Unless required by applicable law or agreed to in writing, software
11606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** distributed under the License is distributed on an "AS IS" BASIS,
12606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** See the License for the specific language governing permissions and
14606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes** limitations under the License.
15606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes*/
16606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
17606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#ifdef DEBUG
18606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#define DBG
19606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#else
20606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#define DBG #
21606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes#endif
22606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
23606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes/*
24606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes * blend one of 2 16bpp RGB pixels held in dreg selected by shift
25606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes * with the 32bpp ABGR pixel held in src and store the result in fb
26606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *
27606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes * Assumes that the dreg data is little endian and that
28606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes * the the second pixel (shift==16) will be merged into
29606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes * the fb result
30606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes *
31606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes * Uses $a4,$t2,$t3,$t8
32606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes */
33606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
34606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .macro pixel dreg src fb shift
35606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /*
36606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes     * sA = s >> 24
37606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes     * f = 0x100 - (sA + (sA>>7))
38606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes     */
39606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    srl     $t3,\src,24
40606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    srl     $t2,$t3,7
41606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    addu    $t3,$t2
42606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    li      $t2,0x100
43606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    subu    $t3,$t2,$t3
44606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
45606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* red */
46606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    ext     $t8,\dreg,\shift+6+5,5                  # dst[\shift:15..11]
47606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    mul     $t2,$t8,$t3
48606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    ext     $a4,\dreg,\shift+5,6                    # start green extraction dst[\shift:10..5]
49606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    ext     $t8,\src,3,5                            # src[7..3]
50606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    srl     $t2,8
51606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    addu    $t8,$t2
52606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes.if \shift!=0
53606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sll     $t8,\shift+11                           # dst[\shift:15..11]
54606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    or      \fb,$t8
55606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes.else
56606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sll     \fb,$t8,11
57606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes.endif
58606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
59606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* green */
60606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    mul     $t8,$a4,$t3
61606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    ext     $a4,\dreg,\shift,5                      # start blue extraction dst[\shift:4..0]
62606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    ext     $t2,\src,2+8,6                          # src[15..10]
63606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    srl     $t8,8
64606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    addu    $t8,$t2
65606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
66606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* blue */
67606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    mul     $a4,$a4,$t3
68606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sll     $t8, $t8, \shift+5                  # finish green insertion dst[\shift:10..5]
69606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    or      \fb, \fb, $t8
70606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    ext     $t2,\src,(3+8+8),5
71606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    srl     $t8,$a4,8
72606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    addu    $t8,$t2
73606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sll     $t8, $t8, \shift
74606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    or      \fb, \fb, $t8
75606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .endm
76606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
77606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .text
78606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .align
79606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
80606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .global scanline_t32cb16blend_mips64
81606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .ent    scanline_t32cb16blend_mips64
82606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesscanline_t32cb16blend_mips64:
83606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddiu  $sp, $sp, -40
84606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG li      $v0,0xffffffff
85606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG li      $v1,0
86606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* Align the destination if necessary */
87606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    and     $a4,$a0,3
88606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $a4,aligned
89606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
90606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* as long as there is at least one pixel */
91606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $a2,done
92606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
93606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $t0,($a1)
94606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddu   $a0,2
95606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddu   $a1,4
96606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $t0,1f
97606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lhu     $a7,-2($a0)
98606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    pixel   $a7,$t0,$a5,0
99606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sh      $a5,-2($a0)
100606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes1:  subu    $a2,1
101606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
102606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesaligned:
103606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* Check to see if its worth unrolling the loop */
104606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    subu    $a2,4
105606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    bltz    $a2,tail
106606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
107606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* Process 4 pixels at a time */
108606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesfourpixels:
109606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* 1st pair of pixels */
110606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $t0,0($a1)
111606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $t1,4($a1)
112606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddu   $a0,8
113606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddu   $a1,16
114606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
115606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* both are zero, skip this pair */
116606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    or      $a7,$t0,$t1
117606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $a7,1f
118606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
119606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* load the destination */
120606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $a7,-8($a0)
121606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
122606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    pixel   $a7,$t0,$a5,0
123606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    andi    $a5, 0xFFFF
124606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    pixel   $a7,$t1,$a5,16
125606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sw      $a5,-8($a0)
126606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
127606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes1:
128606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* 2nd pair of pixels */
129606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $t0,-8($a1)
130606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $t1,-4($a1)
131606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
132606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* both are zero, skip this pair */
133606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    or      $a7,$t0,$t1
134606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $a7,1f
135606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
136606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* load the destination */
137606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $a7,-4($a0)
138606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
139606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    pixel   $a7,$t0,$a5,0
140606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    andi    $a5, 0xFFFF
141606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    pixel   $a7,$t1,$a5,16
142606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sw      $a5,-4($a0)
143606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
144606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes1:  subu    $a2,4
145606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    bgtz    $a2,fourpixels
146606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
147606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughestail:
148606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* the pixel count underran, restore it now */
149606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    addu    $a2,4
150606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes
151606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    /* handle the last 0..3 pixels */
152606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $a2,done
153606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesonepixel:
154606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lw      $t0,($a1)
155606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddu   $a0,2
156606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddu   $a1,4
157606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    beqz    $t0,1f
158606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    lhu     $a7,-2($a0)
159606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    pixel   $a7,$t0,$a5,0
160606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    sh      $a5,-2($a0)
161606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes1:  subu    $a2,1
162606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    bnez    $a2,onepixel
163606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughesdone:
164606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG .set    push
165606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG .set    mips32r2
166606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG rdhwr   $a0,$3
167606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG mul     $v0,$a0
168606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG mul     $v1,$a0
169606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott HughesDBG .set    pop
170606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    daddiu  $sp, $sp, 40
171606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    j       $ra
172606d4aecfb6a1e911dac207caeba617d1379c1f7Elliott Hughes    .end    scanline_t32cb16blend_mips64
173