svp compiler: jump fixup
[picodrive.git] / Pico / carthw / svp / stub_arm.S
1 @ vim:filetype=armasm
2
3 .if 0
4 #include "compiler.h"
5 .endif
6
7 .global tcache
8
9 .global flush_inval_caches
10 .global ssp_drc_entry
11 .global ssp_drc_next
12 .global ssp_drc_next_patch
13 .global ssp_drc_end
14 .global ssp_hle_800
15
16 @ translation cache buffer
17 .text
18 .align 12 @ 4096
19 .size tcache, TCACHE_SIZE
20 tcache:
21  .space TCACHE_SIZE
22
23
24 .text
25 .align 2
26
27
28 flush_inval_caches:
29     mov     r2, #0x0  @ must be 0
30     swi     0x9f0002
31     bx      lr
32
33
34 @       SSP_GR0, SSP_X,     SSP_Y,   SSP_A,
35 @       SSP_ST,  SSP_STACK, SSP_PC,  SSP_P,
36 @       SSP_PM0, SSP_PM1,   SSP_PM2, SSP_XST,
37 @       SSP_PM4, SSP_gr13,  SSP_PMC, SSP_AL
38
39 @ register map:
40 @ r4:  XXYY
41 @ r5:  A
42 @ r6:  STACK and emu flags: sss0 * .uu. .lll NZCV (NZCV is PSR bits from ARM)
43 @ r7:  SSP context
44 @ r8:  r0-r2 (.210)
45 @ r9:  r4-r6 (.654)
46 @ r10: P
47 @ r11: cycles
48
49
50 #define SSP_OFFS_GR         0x400
51 #define SSP_PC                  6
52 #define SSP_P                   7
53 #define SSP_PM0                 8
54 #define SSP_OFFS_EMUSTAT    0x484 // emu_status
55 #define SSP_OFFS_IRAM_DIRTY 0x494
56 #define SSP_OFFS_IRAM_CTX   0x498 // iram_context
57 #define SSP_OFFS_BLTAB      0x49c // block_table
58 #define SSP_OFFS_BLTAB_IRAM 0x4a0
59 #define SSP_OFFS_TMP0       0x4a4 // for entry PC
60 #define SSP_OFFS_TMP1       0x4a8
61 #define SSP_OFFS_TMP2       0x4ac
62 #define SSP_WAIT_PM0       0x2000
63
64
65 .macro ssp_drc_do_next patch_jump=0
66 .if \patch_jump
67     str     lr, [r7, #SSP_OFFS_TMP2]            @ jump instr. (actually call) address + 4
68 .endif
69     mov     r0, r0, lsl #16
70     mov     r0, r0, lsr #16
71     str     r0, [r7, #SSP_OFFS_TMP0]
72     cmp     r0, #0x400
73     blt     0f @ ssp_de_iram
74
75     ldr     r2, [r7, #SSP_OFFS_BLTAB]
76     ldr     r2, [r2, r0, lsl #2]
77     tst     r2, r2
78 .if \patch_jump
79     bne     ssp_drc_do_patch
80 .else
81     bxne    r2
82 .endif
83     bl      ssp_translate_block
84     mov     r2, r0
85     ldr     r0, [r7, #SSP_OFFS_TMP0]            @ entry PC
86     ldr     r1, [r7, #SSP_OFFS_BLTAB]
87     str     r2, [r1, r0, lsl #2]
88 .if \patch_jump
89     b       ssp_drc_do_patch
90 .else
91     bx      r2
92 .endif
93
94 0: @ ssp_de_iram:
95     ldr     r1, [r7, #SSP_OFFS_IRAM_DIRTY]
96     tst     r1, r1
97     ldreq   r1, [r7, #SSP_OFFS_IRAM_CTX]
98     beq     1f @ ssp_de_iram_ctx
99
100     bl      ssp_get_iram_context
101     mov     r1, #0
102     str     r1, [r7, #SSP_OFFS_IRAM_DIRTY]
103     mov     r1, r0
104     str     r1, [r7, #SSP_OFFS_IRAM_CTX]
105     ldr     r0, [r7, #SSP_OFFS_TMP0]            @ entry PC
106     
107 1: @ ssp_de_iram_ctx:
108     ldr     r2, [r7, #SSP_OFFS_BLTAB_IRAM]
109     add     r2, r2, r1, lsl #12                 @ block_tab_iram + iram_context * 0x800/2*4
110     add     r1, r2, r0, lsl #2
111     ldr     r2, [r1]
112     tst     r2, r2
113 .if \patch_jump
114     bne     ssp_drc_do_patch
115 .else
116     bxne    r2
117 .endif
118     str     r1, [r7, #SSP_OFFS_TMP1]
119     bl      ssp_translate_block
120     mov     r2, r0
121     ldr     r0, [r7, #SSP_OFFS_TMP0]            @ entry PC
122     ldr     r1, [r7, #SSP_OFFS_TMP1]            @ &block_table_iram[iram_context][rPC]
123     str     r2, [r1]
124 .if \patch_jump
125     b       ssp_drc_do_patch
126 .else
127     bx      r2
128 .endif
129 .endm @ ssp_drc_do_next
130
131
132 ssp_drc_entry:
133     stmfd   sp!, {r4-r11, lr}
134     mov     r11, r0
135 ssp_regfile_load:
136     ldr     r7, =ssp
137     ldr     r7, [r7]
138     add     r2, r7, #0x400
139     add     r2, r2, #4
140     ldmia   r2, {r3,r4,r5,r6,r8}
141     mov     r3, r3, lsr #16
142     mov     r3, r3, lsl #16
143     orr     r4, r3, r4, lsr #16         @ XXYY
144
145     and     r8, r8, #0x0f0000
146     mov     r8, r8, lsl #13             @ sss0 *
147     and     r9, r6, #0x670000
148     tst     r6,     #0x80000000
149     orrne   r8, r8, #0x8
150     tst     r6,     #0x20000000
151     orrne   r8, r8, #0x4                @ sss0 *           NZ..
152     orr     r6, r8, r9, lsr #12         @ sss0 * .uu. .lll NZ..
153
154     ldr     r8, [r7, #0x440]            @ r0-r2
155     ldr     r9, [r7, #0x444]            @ r4-r6
156     ldr     r10,[r7, #(0x400+SSP_P*4)]  @ P
157
158     ldr     r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)]
159     mov     r0, r0, lsr #16
160
161
162 ssp_drc_next:
163     ssp_drc_do_next 0
164
165
166 ssp_drc_next_patch:
167     ssp_drc_do_next 1
168
169 ssp_drc_do_patch:
170     ldr     r1, [r7, #SSP_OFFS_TMP2]    @ jump instr. (actually call) address + 4
171     subs    r12,r2, r1
172     moveq   r3,     #0xe1000000
173     orreq   r3, r3, #0x00a00000         @ nop
174     streq   r3, [r1, #-4]
175     beq     ssp_drc_dp_end
176
177     cmp     r12,#4
178     ldreq   r3, [r1]
179     addeq   r3, r3, #1
180     streq   r3, [r1, #-4]               @ move the other cond up
181     moveq   r3,     #0xe1000000
182     orreq   r3, r3, #0x00a00000
183     streq   r3, [r1]                    @ fill it's place with nop
184     beq     ssp_drc_dp_end
185
186     ldr     r3, [r1, #-4]
187     sub     r12,r12,#4
188     mov     r3, r3, lsr #24
189     bic     r3, r3, #1                  @ L bit
190     orr     r3, r3, r12,lsl #6
191     mov     r3, r3, ror #8              @ patched branch instruction
192     str     r3, [r1, #-4]
193
194 ssp_drc_dp_end:
195     str     r2, [r7, #SSP_OFFS_TMP1]
196     sub     r0, r1, #4
197     add     r1, r1, #4
198     bl      flush_inval_caches
199     ldr     r2, [r7, #SSP_OFFS_TMP1]
200     ldr     r0, [r7, #SSP_OFFS_TMP0]
201     bx      r2
202
203
204 ssp_drc_end:
205     mov     r0, r0, lsl #16
206     str     r0, [r7, #(SSP_OFFS_GR+SSP_PC*4)]
207
208 ssp_regfile_store:
209     str     r10,[r7, #(0x400+SSP_P*4)]  @ P
210     str     r8, [r7, #0x440]            @ r0-r2
211     str     r9, [r7, #0x444]            @ r4-r6
212
213     mov     r9, r6, lsr #13
214     and     r9, r9, #(7<<16)            @ STACK
215     mov     r3, r6, lsl #28
216     msr     cpsr_flg, r3                @ to to ARM PSR
217     and     r6, r6, #0x670
218     mov     r6, r6, lsl #12
219     orrmi   r6, r6, #0x80000000         @ N
220     orreq   r6, r6, #0x20000000         @ Z
221
222     mov     r3, r4, lsl #16             @ Y
223     mov     r2, r4, lsr #16
224     mov     r2, r2, lsl #16             @ X
225     add     r8, r7, #0x400
226     add     r8, r8, #4
227     stmia   r8, {r2,r3,r5,r6,r9}
228
229     mov     r0, r11
230     ldmfd   sp!, {r4-r11, lr}
231     bx      lr
232
233
234
235 @ ld      A, PM0
236 @ andi    2
237 @ bra     z=1, gloc_0800
238 ssp_hle_800:
239     ldr     r0, [r7, #(SSP_OFFS_GR+SSP_PM0*4)]
240     ldr     r1, [r7, #SSP_OFFS_EMUSTAT]
241     tst     r0, #0x20000
242     orreq   r1, r1, #SSP_WAIT_PM0
243     subeq   r11,r11, #1024
244     streq   r1, [r7, #SSP_OFFS_EMUSTAT]
245     mov     r0,     #0x400
246     beq     ssp_drc_end
247     orrne   r0, r0, #0x004
248
249     b       ssp_drc_next
250
251