1 |
/* |
2 |
* PearPC |
3 |
* jitc_debug.h |
4 |
* |
5 |
* Copyright (C) 2004 Sebastian Biallas (sb@biallas.net) |
6 |
* |
7 |
* This program is free software; you can redistribute it and/or modify |
8 |
* it under the terms of the GNU General Public License version 2 as |
9 |
* published by the Free Software Foundation. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 |
*/ |
20 |
|
21 |
#include <cstdarg> |
22 |
#include <cstdio> |
23 |
#include <cstring> |
24 |
|
25 |
#include "tools/data.h" |
26 |
#include "tools/str.h" |
27 |
|
28 |
#include "debug/x86dis.h" |
29 |
#include "debug/ppcdis.h" |
30 |
#include "tools/snprintf.h" |
31 |
#include "jitc.h" |
32 |
#include "jitc_asm.h" |
33 |
#include "jitc_debug.h" |
34 |
|
35 |
#ifdef JITC_DEBUG |
36 |
|
37 |
static FILE *gDebugLog; |
38 |
static AVLTree *symbols; |
39 |
|
40 |
static char *symbol_lookup(CPU_ADDR addr, int *symstrlen, void *context) |
41 |
{ |
42 |
/* foreach(KeyValue, kv, *symbols, { |
43 |
ht_printf("lookup %y -> %y\n", kv->mKey, kv->mValue); |
44 |
});*/ |
45 |
|
46 |
KeyValue tmp(new UInt(addr.addr32.offset), NULL); |
47 |
|
48 |
ObjHandle oh = symbols->find(&tmp); |
49 |
// return NULL; |
50 |
if (oh != InvObjHandle) { |
51 |
KeyValue *kv = (KeyValue*)symbols->get(oh); |
52 |
// ht_printf("lookup '%y'\n", kv->mValue); |
53 |
if (symstrlen) *symstrlen = ((String *)kv->mValue)->length(); |
54 |
return ((String *)kv->mValue)->contentChar(); |
55 |
} else { |
56 |
// ht_printf("lookup %08x failed\n", addr.addr32.offset); |
57 |
// if (symstrlen) *symstrlen = 1; |
58 |
return NULL; |
59 |
} |
60 |
} |
61 |
|
62 |
inline static void disasmPPC(uint32 code, uint32 ea, char *result) |
63 |
{ |
64 |
PPCDisassembler dis; |
65 |
CPU_ADDR addr; |
66 |
addr.addr32.offset = ea; |
67 |
addr_sym_func = NULL; |
68 |
strcpy(result, dis.str(dis.decode((byte*)&code, 4, addr), 0)); |
69 |
} |
70 |
|
71 |
inline static int disasmX86(const byte *code, uint32 ea, char *result) |
72 |
{ |
73 |
X86Disassembler dis(X86_OPSIZE32, X86_ADDRSIZE32); |
74 |
CPU_ADDR addr; |
75 |
addr.addr32.offset = ea; |
76 |
addr_sym_func = symbol_lookup; |
77 |
dis_insn *ret = dis.decode(code, 15, addr); |
78 |
strcpy(result, dis.str(ret, 0)); |
79 |
return dis.getSize(ret); |
80 |
} |
81 |
|
82 |
void jitcDebugLogAdd(const char *fmt, ...) |
83 |
{ |
84 |
va_list ap; |
85 |
|
86 |
va_start(ap, fmt); |
87 |
ht_vfprintf(gDebugLog, fmt, ap); |
88 |
va_end(ap); |
89 |
// fflush(gDebugLog); |
90 |
} |
91 |
|
92 |
void jitcDebugLogNewInstruction() |
93 |
{ |
94 |
char str[128]; |
95 |
disasmPPC(gJITC.current_opc, gJITC.pc, str); |
96 |
jitcDebugLogAdd("%08x %08x %s\n", gJITC.pc, gJITC.current_opc, str); |
97 |
} |
98 |
|
99 |
void jitcDebugLogEmit(const byte *insn, int size) |
100 |
{ |
101 |
char str[128]; |
102 |
int size1 = disasmX86(insn, (uint32)gJITC.currentPage->tcp, str); |
103 |
if (size != size1) jitcDebugLogAdd(" kaputt! "); |
104 |
jitcDebugLogAdd(" "); |
105 |
for (int i=0; i < 15; i++) { |
106 |
if (i < size) { |
107 |
jitcDebugLogAdd("%02x", insn[i]); |
108 |
} else { |
109 |
jitcDebugLogAdd(" "); |
110 |
} |
111 |
} |
112 |
jitcDebugLogAdd(" %s\n", str); |
113 |
} |
114 |
|
115 |
void jitcDebugInit() |
116 |
{ |
117 |
// gDebugLog = stdout; |
118 |
gDebugLog = fopen("jitc.log", "w"); |
119 |
// gDebugLog = fopen("/dev/null", "w"); |
120 |
symbols = new AVLTree(true); |
121 |
|
122 |
for (int i=0; i<32; i++) { |
123 |
String *s = new String(); |
124 |
s->assignFormat("r%d", i); |
125 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.gpr[i]), s)); |
126 |
} |
127 |
for (int i=0; i<32; i++) { |
128 |
String *s = new String(); |
129 |
s->assignFormat("fr%d (lower)", i); |
130 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.fpr[i]), s)); |
131 |
s = new String(); |
132 |
s->assignFormat("fr%d (upper)", i); |
133 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.fpr[i]+4), s)); |
134 |
} |
135 |
for (int i=0; i<32; i++) { |
136 |
String *s; |
137 |
for (int j=0; j<4; j++) { |
138 |
s = new String(); |
139 |
s->assignFormat("vr%d (%d)", i, j); |
140 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.vr[i]+4*j), s)); |
141 |
} |
142 |
} |
143 |
for (int i=0; i<4; i++) { |
144 |
String *s = new String(); |
145 |
s->assignFormat("ibatl%d", i); |
146 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.ibatl[i]), s)); |
147 |
s = new String(); |
148 |
s->assignFormat("ibatu%d", i); |
149 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.ibatu[i]), s)); |
150 |
s = new String(); |
151 |
s->assignFormat("ibat_bl17_%d", i); |
152 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.ibat_bl17[i]), s)); |
153 |
s = new String(); |
154 |
s->assignFormat("dbatl%d", i); |
155 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.dbatl[i]), s)); |
156 |
s = new String(); |
157 |
s->assignFormat("dbatu%d", i); |
158 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.dbatu[i]), s)); |
159 |
s = new String(); |
160 |
s->assignFormat("dbat_bl17_%d", i); |
161 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.dbat_bl17[i]), s)); |
162 |
} |
163 |
for (int i=0; i<4; i++) { |
164 |
String *s = new String(); |
165 |
s->assignFormat("sprg%d", i); |
166 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.sprg[i]), s)); |
167 |
} |
168 |
for (int i=0; i<16; i++) { |
169 |
String *s = new String(); |
170 |
s->assignFormat("hid%d", i); |
171 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.hid[i]), s)); |
172 |
} |
173 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.ctr), new String("ctr"))); |
174 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.lr), new String("lr"))); |
175 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.cr), new String("cr"))); |
176 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.cr+1), new String("cr+1"))); |
177 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.cr+2), new String("cr+2"))); |
178 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.cr+3), new String("cr+3"))); |
179 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.xer), new String("xer"))); |
180 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.xer_ca), new String("xer_ca"))); |
181 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.xer+3), new String("xer+3"))); |
182 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.msr), new String("msr"))); |
183 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.srr[0]), new String("srr0"))); |
184 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.srr[1]), new String("srr1"))); |
185 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.dsisr), new String("dsisr"))); |
186 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.dar), new String("dar"))); |
187 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.dec), new String("dec"))); |
188 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.pvr), new String("pvr"))); |
189 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.vrsave), new String("vrsave"))); |
190 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.reserve), new String("reserve"))); |
191 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.temp), new String("tmp"))); |
192 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.vtemp), new String("vtmp"))); |
193 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.current_code_base), new String("current_code_base"))); |
194 |
symbols->insert(new KeyValue(new UInt((uint)&gCPU.current_opc), new String("current_opc"))); |
195 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_write_effective_byte_asm), new String("ppc_write_effective_byte_asm"))); |
196 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_write_effective_half_asm), new String("ppc_write_effective_half_asm"))); |
197 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_write_effective_word_asm), new String("ppc_write_effective_word_asm"))); |
198 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_write_effective_dword_asm), new String("ppc_write_effective_dword_asm"))); |
199 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_read_effective_byte_asm), new String("ppc_read_effective_byte_asm"))); |
200 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_read_effective_half_z_asm), new String("ppc_read_effective_half_z_asm"))); |
201 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_read_effective_half_s_asm), new String("ppc_read_effective_half_s_asm"))); |
202 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_read_effective_word_asm), new String("ppc_read_effective_word_asm"))); |
203 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_read_effective_dword_asm), new String("ppc_read_effective_dword_asm"))); |
204 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_opc_icbi_asm), new String("ppc_opc_icbi_asm"))); |
205 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_opc_stswi_asm), new String("ppc_opc_stswi_asm"))); |
206 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_opc_lswi_asm), new String("ppc_opc_lswi_asm"))); |
207 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_isi_exception_asm), new String("ppc_isi_exception_asm"))); |
208 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_dsi_exception_asm), new String("ppc_dsi_exception_asm"))); |
209 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_program_exception_asm), new String("ppc_program_exception_asm"))); |
210 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_no_fpu_exception_asm), new String("ppc_no_fpu_exception_asm"))); |
211 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_sc_exception_asm), new String("ppc_sc_exception_asm"))); |
212 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_flush_flags_asm), new String("ppc_flush_flags_asm"))); |
213 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_new_pc_asm), new String("ppc_new_pc_asm"))); |
214 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_new_pc_rel_asm), new String("ppc_new_pc_rel_asm"))); |
215 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_set_msr_asm), new String("ppc_set_msr_asm"))); |
216 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_mmu_tlb_invalidate_all_asm), new String("ppc_mmu_tlb_invalidate_all_asm"))); |
217 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_start_jitc_asm), new String("ppc_start_jitc_asm"))); |
218 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_new_pc_this_page_asm), new String("ppc_new_pc_this_page_asm"))); |
219 |
symbols->insert(new KeyValue(new UInt((uint)&ppc_heartbeat_ext_rel_asm), new String("ppc_heartbeat_ext_rel_asm"))); |
220 |
} |
221 |
|
222 |
void jitcDebugDone() |
223 |
{ |
224 |
fclose(gDebugLog); |
225 |
} |
226 |
|
227 |
#endif |