41b1e6919e7e04d50c407d4f77ef0a6e83ca67f6
[pcsx_rearmed.git] / frontend / cspace_arm.S
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2013
3  *
4  * This work is licensed under the terms of GNU GPL version 2 or later.
5  * See the COPYING file in the top-level directory.
6  */
7
8 #include "arm_features.h"
9
10 .text
11 .align 2
12
13 @ lr=0x001f001f
14 @ trashes r11, r12
15 .macro bgr555_to_rgb565_one rn
16     and      r11, lr, \rn
17     and      r12, lr, \rn, lsr #5
18     and      \rn, lr, \rn, lsr #10
19     orr      r12, r11, lsl #5
20     orr      \rn, r12, lsl #6
21 .endm
22
23 .macro bgr555_to_rgb565_one_i rn1 rn2
24     and      r12, lr, \rn1, lsr #5
25     and      \rn1,lr, \rn1, lsr #10
26     orr      r12, r11, lsl #5
27     and      r11, lr, \rn2
28     orr      \rn1,r12, lsl #6
29 .endm
30
31 .macro pld_ reg offs=#0
32 #ifdef HAVE_ARMV6
33     pld      [\reg, \offs]
34 #endif
35 .endm
36
37 FUNCTION(bgr555_to_rgb565): @ void *dst, const void *src, int bytes
38     push     {r4-r11,lr}
39     mov      lr, #0x001f
40     subs     r2, #4*8
41     orr      lr, lr, lsl #16
42     blt      1f
43
44     @ src can be unaligned, but that's very rare, so just force it.
45     @ The manual says unaligned ldm should fault, and it does on
46     @ cortex-a78's 32bit mode, but curiously on cortex-a8 it just
47     @ works and loads the data correctly.
48     bic      r1, r1, #3
49
50 0:
51     ldmia    r1!, {r3-r10}
52     subs     r2, #4*8
53     bic      r12, r1, #0x1f
54     pld_     r12, #32*1
55     and      r11, lr, r3
56     bgr555_to_rgb565_one_i r3 r4
57     bgr555_to_rgb565_one_i r4 r5
58     bgr555_to_rgb565_one_i r5 r6
59     bgr555_to_rgb565_one_i r6 r7
60     bgr555_to_rgb565_one_i r7 r8
61     bgr555_to_rgb565_one_i r8 r9
62     bgr555_to_rgb565_one_i r9 r10
63     bgr555_to_rgb565_one_i r10 r10
64     stmia    r0!, {r3-r10}
65     bge      0b
66
67 1:
68     adds     r2, #4*8
69     popeq    {r4-r11,pc}
70
71 2:
72     ldr      r3, [r1], #4
73     subs     r2, #4
74     bgr555_to_rgb565_one r3
75     str      r3, [r0], #4
76     bgt      2b
77
78     pop      {r4-r11,pc}
79
80
81 #ifdef HAVE_ARMV6 /* v6-only due to potential misaligned reads */
82
83 # r1b0g0r0 g2r2b1g1 b3g3r3b2
84 FUNCTION(bgr888_to_rgb565):
85     pld      [r1]
86     push     {r4-r10,lr}
87
88     mov      r10, #0x001f          @ b mask
89     mov      r12, #0x07e0          @ g mask
90     mov      lr,  #0xf800          @ r mask
91
92 0:
93     ldr      r3, [r1], #4          @ may be unaligned
94     ldr      r4, [r1], #4
95     ldr      r5, [r1], #4
96     pld      [r1, #32*1]
97     and      r6, r10,r3, lsr #16+3 @ b0
98     and      r7, r12,r3, lsr #5    @ g0
99     and      r8, lr, r3, lsl #8    @ r0
100     and      r9, lr, r3, lsr #16   @ r1
101     orr      r6, r6, r7
102     orr      r6, r6, r8            @ r0g0b0
103
104     and      r7, r12,r4, lsl #3    @ g1
105     and      r8, r10,r4, lsr #11   @ b1
106     orr      r9, r9, r7
107     orr      r9, r9, r8            @ r1g1b1
108     and      r7, lr, r4, lsr #8    @ r2
109     and      r8, r12,r4, lsr #21   @ g2
110     pkhbt    r9, r6, r9, lsl #16
111     str      r9, [r0], #4
112
113     and      r6, r10,r5, lsr #3    @ b2
114     orr      r7, r7, r8
115     orr      r6, r6, r7            @ r2g2b2
116     and      r7, lr, r5            @ r3
117     and      r8, r12,r5, lsr #13   @ g3
118     orr      r7, r7, r5, lsr #27   @ r3b3
119     orr      r7, r7, r8            @ r3g3b3
120     pkhbt    r7, r6, r7, lsl #16
121     str      r7, [r0], #4
122     subs     r2, r2, #12
123     bgt      0b
124
125     pop      {r4-r10,pc}
126
127 #endif /* HAVE_ARMV6 */