Merge pull request #377 from pcercuei/libretro
[pcsx_rearmed.git] / deps / lightrec / lightrec-private.h
1 /*
2  * Copyright (C) 2016 Paul Cercueil <paul@crapouillou.net>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  */
14
15 #ifndef __LIGHTREC_PRIVATE_H__
16 #define __LIGHTREC_PRIVATE_H__
17
18 #include "config.h"
19 #include "disassembler.h"
20 #include "lightrec.h"
21
22 #if ENABLE_THREADED_COMPILER
23 #include <stdatomic.h>
24 #endif
25
26 #define ARRAY_SIZE(x) (sizeof(x) ? sizeof(x) / sizeof((x)[0]) : 0)
27 #define BIT(x) (1 << (x))
28
29 #ifdef __GNUC__
30 #       define likely(x)       __builtin_expect(!!(x),1)
31 #       define unlikely(x)     __builtin_expect(!!(x),0)
32 #else
33 #       define likely(x)       (x)
34 #       define unlikely(x)     (x)
35 #endif
36
37 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
38 #       define LE32TOH(x)       __builtin_bswap32(x)
39 #       define HTOLE32(x)       __builtin_bswap32(x)
40 #       define LE16TOH(x)       __builtin_bswap16(x)
41 #       define HTOLE16(x)       __builtin_bswap16(x)
42 #else
43 #       define LE32TOH(x)       (x)
44 #       define HTOLE32(x)       (x)
45 #       define LE16TOH(x)       (x)
46 #       define HTOLE16(x)       (x)
47 #endif
48
49 /* Flags for (struct block *)->flags */
50 #define BLOCK_NEVER_COMPILE     BIT(0)
51 #define BLOCK_SHOULD_RECOMPILE  BIT(1)
52 #define BLOCK_FULLY_TAGGED      BIT(2)
53
54 #define RAM_SIZE        0x200000
55 #define BIOS_SIZE       0x80000
56
57 #define CODE_LUT_SIZE   ((RAM_SIZE + BIOS_SIZE) >> 2)
58
59 /* Definition of jit_state_t (avoids inclusion of <lightning.h>) */
60 struct jit_node;
61 struct jit_state;
62 typedef struct jit_state jit_state_t;
63
64 struct blockcache;
65 struct recompiler;
66 struct regcache;
67 struct opcode;
68 struct tinymm;
69
70 struct block {
71         jit_state_t *_jit;
72         struct lightrec_state *state;
73         struct opcode *opcode_list;
74         void (*function)(void);
75         u32 pc;
76         u32 hash;
77 #if ENABLE_THREADED_COMPILER
78         atomic_flag op_list_freed;
79 #endif
80         unsigned int code_size;
81         u16 flags;
82         u16 nb_ops;
83         const struct lightrec_mem_map *map;
84         struct block *next;
85 };
86
87 struct lightrec_branch {
88         struct jit_node *branch;
89         u32 target;
90 };
91
92 struct lightrec_branch_target {
93         struct jit_node *label;
94         u32 offset;
95 };
96
97 struct lightrec_state {
98         u32 native_reg_cache[34];
99         u32 next_pc;
100         u32 current_cycle;
101         u32 target_cycle;
102         u32 exit_flags;
103         struct block *dispatcher, *rw_wrapper, *rw_generic_wrapper,
104                      *mfc_wrapper, *mtc_wrapper, *rfe_wrapper, *cp_wrapper,
105                      *syscall_wrapper, *break_wrapper;
106         void *rw_func, *rw_generic_func, *mfc_func, *mtc_func, *rfe_func,
107              *cp_func, *syscall_func, *break_func;
108         struct jit_node *branches[512];
109         struct lightrec_branch local_branches[512];
110         struct lightrec_branch_target targets[512];
111         unsigned int nb_branches;
112         unsigned int nb_local_branches;
113         unsigned int nb_targets;
114         struct tinymm *tinymm;
115         struct blockcache *block_cache;
116         struct regcache *reg_cache;
117         struct recompiler *rec;
118         void (*eob_wrapper_func)(void);
119         void (*get_next_block)(void);
120         struct lightrec_ops ops;
121         unsigned int cycles;
122         unsigned int nb_maps;
123         const struct lightrec_mem_map *maps;
124         uintptr_t offset_ram, offset_bios, offset_scratch;
125         _Bool mirrors_mapped;
126         _Bool invalidate_from_dma_only;
127         void *code_lut[];
128 };
129
130 u32 lightrec_rw(struct lightrec_state *state, union code op,
131                 u32 addr, u32 data, u16 *flags);
132
133 void lightrec_free_block(struct block *block);
134
135 void remove_from_code_lut(struct blockcache *cache, struct block *block);
136
137 static inline u32 kunseg(u32 addr)
138 {
139         if (unlikely(addr >= 0xa0000000))
140                 return addr - 0xa0000000;
141         else
142                 return addr &~ 0x80000000;
143 }
144
145 static inline u32 lut_offset(u32 pc)
146 {
147         if (pc & BIT(28))
148                 return ((pc & (BIOS_SIZE - 1)) + RAM_SIZE) >> 2; // BIOS
149         else
150                 return (pc & (RAM_SIZE - 1)) >> 2; // RAM
151 }
152
153 void lightrec_mtc(struct lightrec_state *state, union code op, u32 data);
154 u32 lightrec_mfc(struct lightrec_state *state, union code op);
155
156 union code lightrec_read_opcode(struct lightrec_state *state, u32 pc);
157
158 struct block * lightrec_get_block(struct lightrec_state *state, u32 pc);
159 int lightrec_compile_block(struct block *block);
160
161 #endif /* __LIGHTREC_PRIVATE_H__ */