22
25
static UINT32 sse_control[4] = { 0x9fc0, 0xbfc0, 0xdfc0, 0xffc0 };
25
static void append_entry_point(struct drccore *drc);
26
static void append_recompile(struct drccore *drc);
27
static void append_out_of_cycles(struct drccore *drc);
28
static void append_entry_point(drc_core *drc);
29
static void append_recompile(drc_core *drc);
30
static void append_flush(drc_core *drc);
31
static void append_out_of_cycles(drc_core *drc);
30
static void log_dispatch(struct drccore *drc);
34
static void log_dispatch(drc_core *drc);
34
/*###################################################################################################
35
** EXTERNAL INTERFACES
36
**#################################################################################################*/
38
/***************************************************************************
40
***************************************************************************/
38
42
/*------------------------------------------------------------------
40
44
------------------------------------------------------------------*/
42
struct drccore *drc_init(UINT8 cpunum, struct drcconfig *config)
46
drc_core *drc_init(UINT8 cpunum, drc_config *config)
44
48
int address_bits = config->address_bits;
45
49
int effective_address_bits = address_bits - config->lsbs_to_ignore;
48
52
/* allocate memory */
49
53
drc = malloc(sizeof(*drc));
279
287
/*------------------------------------------------------------------
280
drc_append_verify_code
288
drc_append_verify_code
281
289
------------------------------------------------------------------*/
283
void drc_append_verify_code(struct drccore *drc, void *code, UINT8 length)
291
void drc_append_verify_code(drc_core *drc, void *code, UINT8 length)
287
295
UINT32 *codeptr = code, sum = 0;
291
299
for (i = 0; i < length / 4; i++)
293
301
sum = (sum >> 1) | (sum << 31);
294
302
sum += *codeptr++;
297
_xor_r32_r32(REG_EAX, REG_EAX); /* xor eax,eax */
298
_mov_r32_imm(REG_EBX, code); /* mov ebx,code */
299
_mov_r32_imm(REG_ECX, length / 4); /* mov ecx,length / 4 */
305
_xor_r32_r32(REG_EAX, REG_EAX); /* xor eax,eax */
306
_mov_r32_imm(REG_EBX, code); /* mov ebx,code */
307
_mov_r32_imm(REG_ECX, length / 4); /* mov ecx,length / 4 */
300
308
target = drc->cache_top; /* target: */
301
_ror_r32_imm(REG_EAX, 1); /* ror eax,1 */
302
_add_r32_m32bd(REG_EAX, REG_EBX, 0); /* add eax,[ebx] */
303
_sub_r32_imm(REG_ECX, 1); /* sub ecx,1 */
304
_lea_r32_m32bd(REG_EBX, REG_EBX, 4); /* lea ebx,[ebx+4] */
305
_jcc(COND_NZ, target); /* jnz target */
306
_cmp_r32_imm(REG_EAX, sum); /* cmp eax,sum */
307
_jcc(COND_NE, drc->recompile); /* jne recompile */
309
_ror_r32_imm(REG_EAX, 1); /* ror eax,1 */
310
_add_r32_m32bd(REG_EAX, REG_EBX, 0); /* add eax,[ebx] */
311
_sub_or_dec_r32_imm(REG_ECX, 1); /* sub ecx,1 */
312
_lea_r32_m32bd(REG_EBX, REG_EBX, 4); /* lea ebx,[ebx+4] */
313
_jcc(COND_NZ, target); /* jnz target */
314
_cmp_r32_imm(REG_EAX, sum); /* cmp eax,sum */
315
_jcc(COND_NE, drc->recompile); /* jne recompile */
309
317
else if (length >= 12)
311
_cmp_m32abs_imm(code, *(UINT32 *)code); /* cmp [pc],opcode */
312
_jcc(COND_NE, drc->recompile); /* jne recompile */
313
_cmp_m32abs_imm((UINT8 *)code + 4, ((UINT32 *)code)[1]); /* cmp [pc+4],opcode+4 */
314
_jcc(COND_NE, drc->recompile); /* jne recompile */
315
_cmp_m32abs_imm((UINT8 *)code + 8, ((UINT32 *)code)[2]); /* cmp [pc+8],opcode+8 */
316
_jcc(COND_NE, drc->recompile); /* jne recompile */
319
_cmp_m32abs_imm(code, *(UINT32 *)code); /* cmp [pc],opcode */
320
_jcc(COND_NE, drc->recompile); /* jne recompile */
321
_cmp_m32abs_imm((UINT8 *)code + 4, ((UINT32 *)code)[1]); /* cmp [pc+4],opcode+4 */
322
_jcc(COND_NE, drc->recompile); /* jne recompile */
323
_cmp_m32abs_imm((UINT8 *)code + 8, ((UINT32 *)code)[2]); /* cmp [pc+8],opcode+8 */
324
_jcc(COND_NE, drc->recompile); /* jne recompile */
318
326
else if (length >= 8)
320
_cmp_m32abs_imm(code, *(UINT32 *)code); /* cmp [pc],opcode */
321
_jcc(COND_NE, drc->recompile); /* jne recompile */
322
_cmp_m32abs_imm((UINT8 *)code + 4, ((UINT32 *)code)[1]); /* cmp [pc+4],opcode+4 */
323
_jcc(COND_NE, drc->recompile); /* jne recompile */
328
_cmp_m32abs_imm(code, *(UINT32 *)code); /* cmp [pc],opcode */
329
_jcc(COND_NE, drc->recompile); /* jne recompile */
330
_cmp_m32abs_imm((UINT8 *)code + 4, ((UINT32 *)code)[1]); /* cmp [pc+4],opcode+4 */
331
_jcc(COND_NE, drc->recompile); /* jne recompile */
325
333
else if (length >= 4)
327
_cmp_m32abs_imm(code, *(UINT32 *)code); /* cmp [pc],opcode */
328
_jcc(COND_NE, drc->recompile); /* jne recompile */
335
_cmp_m32abs_imm(code, *(UINT32 *)code); /* cmp [pc],opcode */
336
_jcc(COND_NE, drc->recompile); /* jne recompile */
330
338
else if (length >= 2)
332
_cmp_m16abs_imm(code, *(UINT16 *)code); /* cmp [pc],opcode */
333
_jcc(COND_NE, drc->recompile); /* jne recompile */
340
_cmp_m16abs_imm(code, *(UINT16 *)code); /* cmp [pc],opcode */
341
_jcc(COND_NE, drc->recompile); /* jne recompile */
337
_cmp_m8abs_imm(code, *(UINT8 *)code); /* cmp [pc],opcode */
338
_jcc(COND_NE, drc->recompile); /* jne recompile */
345
_cmp_m8abs_imm(code, *(UINT8 *)code); /* cmp [pc],opcode */
346
_jcc(COND_NE, drc->recompile); /* jne recompile */
343
351
/*------------------------------------------------------------------
344
drc_append_call_debugger
352
drc_append_call_debugger
345
353
------------------------------------------------------------------*/
347
void drc_append_call_debugger(struct drccore *drc)
355
void drc_append_call_debugger(drc_core *drc)
349
357
#ifdef MAME_DEBUG
350
struct linkdata link;
351
_cmp_m32abs_imm(&mame_debug, 0); /* cmp [mame_debug],0 */
352
_jcc_short_link(COND_E, &link); /* je skip */
353
drc_append_save_call_restore(drc, (void *)MAME_Debug, 0); /* save volatiles */
354
_resolve_link(&link);
358
if (Machine->debug_mode)
361
_cmp_m32abs_imm(&Machine->debug_mode, 0); /* cmp [Machine->debug_mode],0 */
362
_jcc_short_link(COND_E, &link); /* je skip */
363
drc_append_save_call_restore(drc, (genf *)mame_debug_hook, 0); /* save volatiles */
364
_resolve_link(&link);
359
370
/*------------------------------------------------------------------
360
drc_append_save_volatiles
371
drc_append_save_volatiles
361
372
------------------------------------------------------------------*/
363
void drc_append_save_volatiles(struct drccore *drc)
374
void drc_append_save_volatiles(drc_core *drc)
365
376
if (drc->icountptr && !drc->icount_in_memory)
366
377
_mov_m32abs_r32(drc->icountptr, REG_EBP);
403
414
/*------------------------------------------------------------------
404
drc_append_standard_epilogue
415
drc_append_standard_epilogue
405
416
------------------------------------------------------------------*/
407
void drc_append_standard_epilogue(struct drccore *drc, INT32 cycles, INT32 pcdelta, int allow_exit)
418
void drc_append_standard_epilogue(drc_core *drc, INT32 cycles, INT32 pcdelta, int allow_exit)
409
420
if (pcdelta != 0 && drc->pc_in_memory)
410
_add_m32abs_imm(drc->pcptr, pcdelta); /* add [pc],pcdelta */
421
_add_m32abs_imm(drc->pcptr, pcdelta); /* add [pc],pcdelta */
413
424
if (drc->icount_in_memory)
414
_sub_m32abs_imm(drc->icountptr, cycles); /* sub [icount],cycles */
425
_sub_m32abs_imm(drc->icountptr, cycles); /* sub [icount],cycles */
416
_sub_r32_imm(REG_EBP, cycles); /* sub ebp,cycles */
427
_sub_or_dec_r32_imm(REG_EBP, cycles); /* sub ebp,cycles */
418
429
if (pcdelta != 0 && !drc->pc_in_memory)
419
_lea_r32_m32bd(REG_EDI, REG_EDI, pcdelta); /* lea edi,[edi+pcdelta] */
430
_lea_r32_m32bd(REG_EDI, REG_EDI, pcdelta); /* lea edi,[edi+pcdelta] */
420
431
if (allow_exit && cycles != 0)
421
_jcc(COND_S, drc->out_of_cycles); /* js out_of_cycles */
432
_jcc(COND_S, drc->out_of_cycles); /* js out_of_cycles */
425
436
/*------------------------------------------------------------------
426
drc_append_dispatcher
437
drc_append_dispatcher
427
438
------------------------------------------------------------------*/
429
void drc_append_dispatcher(struct drccore *drc)
440
void drc_append_dispatcher(drc_core *drc)
431
442
#if LOG_DISPATCHES
432
_push_imm(drc); /* push drc */
433
drc_append_save_call_restore(drc, (void *)log_dispatch, 4); /* call log_dispatch */
443
_push_imm(drc); /* push drc */
444
drc_append_save_call_restore(drc, (void *)log_dispatch, 4); /* call log_dispatch */
435
446
if (drc->pc_in_memory)
436
_mov_r32_m32abs(REG_EDI, drc->pcptr); /* mov edi,[pc] */
437
_mov_r32_r32(REG_EAX, REG_EDI); /* mov eax,edi */
438
_shr_r32_imm(REG_EAX, drc->l1shift); /* shr eax,l1shift */
439
_mov_r32_r32(REG_EDX, REG_EDI); /* mov edx,edi */
440
_mov_r32_m32isd(REG_EAX, REG_EAX, 4, drc->lookup_l1); /* mov eax,[eax*4 + l1lookup] */
441
_and_r32_imm(REG_EDX, drc->l2mask); /* and edx,l2mask */
442
_jmp_m32bisd(REG_EAX, REG_EDX, drc->l2scale, 0); /* jmp [eax+edx*l2scale] */
447
_mov_r32_m32abs(REG_EDI, drc->pcptr); /* mov edi,[pc] */
448
_mov_r32_r32(REG_EAX, REG_EDI); /* mov eax,edi */
449
_shr_r32_imm(REG_EAX, drc->l1shift); /* shr eax,l1shift */
450
_mov_r32_r32(REG_EDX, REG_EDI); /* mov edx,edi */
451
_mov_r32_m32isd(REG_EAX, REG_EAX, 4, drc->lookup_l1); /* mov eax,[eax*4 + l1lookup] */
452
_and_r32_imm(REG_EDX, drc->l2mask); /* and edx,l2mask */
453
_jmp_m32bisd(REG_EAX, REG_EDX, drc->l2scale, 0); /* jmp [eax+edx*l2scale] */
446
457
/*------------------------------------------------------------------
447
drc_append_fixed_dispatcher
458
drc_append_fixed_dispatcher
448
459
------------------------------------------------------------------*/
450
void drc_append_fixed_dispatcher(struct drccore *drc, UINT32 newpc)
461
void drc_append_fixed_dispatcher(drc_core *drc, UINT32 newpc)
452
463
void **base = drc->lookup_l1[newpc >> drc->l1shift];
453
464
if (base == drc->lookup_l2_recompile)
455
_mov_r32_m32abs(REG_EAX, &drc->lookup_l1[newpc >> drc->l1shift]);/* mov eax,[(newpc >> l1shift)*4 + l1lookup] */
456
_jmp_m32bd(REG_EAX, (newpc & drc->l2mask) * drc->l2scale); /* jmp [eax+(newpc & l2mask)*l2scale] */
466
_mov_r32_m32abs(REG_EAX, &drc->lookup_l1[newpc >> drc->l1shift]);/* mov eax,[(newpc >> l1shift)*4 + l1lookup] */
467
_jmp_m32bd(REG_EAX, (newpc & drc->l2mask) * drc->l2scale); /* jmp [eax+(newpc & l2mask)*l2scale] */
459
_jmp_m32abs((UINT8 *)base + (newpc & drc->l2mask) * drc->l2scale); /* jmp [eax+(newpc & l2mask)*l2scale] */
470
_jmp_m32abs((UINT8 *)base + (newpc & drc->l2mask) * drc->l2scale); /* jmp [eax+(newpc & l2mask)*l2scale] */
463
474
/*------------------------------------------------------------------
464
drc_append_tentative_fixed_dispatcher
475
drc_append_tentative_fixed_dispatcher
465
476
------------------------------------------------------------------*/
467
void drc_append_tentative_fixed_dispatcher(struct drccore *drc, UINT32 newpc)
478
void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc)
469
struct pc_ptr_pair *pair = &drc->tentative_list[drc->tentative_count++];
470
if (drc->tentative_count > drc->tentative_count_max)
471
osd_die("drc_append_tentative_fixed_dispatcher: too many tentative branches!\n");
480
pc_ptr_pair *pair = &drc->tentative_list[drc->tentative_count++];
481
assert_always(drc->tentative_count <= drc->tentative_count_max, "drc_append_tentative_fixed_dispatcher: too many tentative branches!");
473
483
pair->target = drc->cache_top;
474
484
pair->pc = newpc;
547
557
/*------------------------------------------------------------------
550
An attempt to make a disassembler for DRC code; currently limited
551
by the functionality of DasmI386
560
An attempt to make a disassembler for DRC code; currently limited
561
by the functionality of DasmI386
552
562
------------------------------------------------------------------*/
554
void drc_dasm(FILE *f, unsigned pc, void *begin, void *end)
564
void drc_dasm(FILE *f, const void *begin, const void *end)
557
unsigned DasmI386(char* buffer, unsigned _pc);
566
extern int i386_dasm_one(char *buffer, UINT32 eip, UINT8 *oprom, int addr_size, int op_size);
559
568
char buffer[256];
561
unsigned addr = (unsigned) begin;
562
unsigned addr_end = (unsigned) end;
566
size_t saved_op_mem_min;
567
size_t saved_op_mem_max;
569
activecpu_dasm(buffer, pc);
570
if (addr == addr_end)
572
logerror("%08x: %s\t(NOP)\n", pc, buffer);
576
logerror("%08x: %s\t(%08x-%08x)\n", pc, buffer, addr, addr_end - 1);
578
saved_op_rom = opcode_base;
579
saved_op_ram = opcode_arg_base;
580
saved_op_mem_min = opcode_memory_min;
581
saved_op_mem_max = opcode_memory_max;
582
opcode_base = opcode_arg_base = (UINT8 *) 0;
583
opcode_memory_min = (size_t) 0;
584
opcode_memory_max = (size_t) -1;
586
while(addr < addr_end)
588
offset = DasmI386(buffer, addr);
589
sprintf(buffer2, "\t%08x: %s\n", addr, buffer);
590
logerror("%s", buffer2);
596
opcode_base = saved_op_rom;
597
opcode_arg_base = saved_op_ram;
598
opcode_memory_min = saved_op_mem_min;
599
opcode_memory_max = saved_op_mem_max;
569
const UINT8 *begin_ptr = (const UINT8 *) begin;
570
const UINT8 *end_ptr = (const UINT8 *) end;
571
UINT32 pc = (UINT32) begin;
574
while(begin_ptr < end_ptr)
576
#if defined(MAME_DEBUG) && HAS_I386
577
length = i386_dasm_one(buffer, pc, (UINT8 *) begin_ptr, 1, 1) & DASMFLAG_LENGTHMASK;
579
sprintf(buffer, "%02X", *begin_ptr);
583
fprintf(f, "%08X:\t%s\n", (unsigned) pc, buffer);
607
/*###################################################################################################
609
**#################################################################################################*/
592
/***************************************************************************
594
***************************************************************************/
611
596
/*------------------------------------------------------------------
613
598
------------------------------------------------------------------*/
615
static void append_entry_point(struct drccore *drc)
600
static void append_entry_point(drc_core *drc)
617
602
_pushad(); /* pushad */
618
603
if (drc->uses_fp)
647
632
/*------------------------------------------------------------------
649
------------------------------------------------------------------*/
651
static void append_recompile(struct drccore *drc)
653
_push_imm(drc); /* push drc */
654
drc_append_save_call_restore(drc, (void *)recompile_code, 4); /* call recompile_code */
655
drc_append_dispatcher(drc); /* dispatch */
659
/*------------------------------------------------------------------
661
------------------------------------------------------------------*/
663
static void append_out_of_cycles(struct drccore *drc)
634
------------------------------------------------------------------*/
636
static void append_recompile(drc_core *drc)
638
_push_imm(drc); /* push drc */
639
drc_append_save_call_restore(drc, (genf *)recompile_code, 4); /* call recompile_code */
640
drc_append_dispatcher(drc); /* dispatch */
644
/*------------------------------------------------------------------
646
------------------------------------------------------------------*/
648
static void append_flush(drc_core *drc)
650
_push_imm(drc); /* push drc */
651
drc_append_save_call_restore(drc, (genf *)drc_cache_reset, 4); /* call drc_cache_reset */
652
drc_append_dispatcher(drc); /* dispatch */
656
/*------------------------------------------------------------------
658
------------------------------------------------------------------*/
660
static void append_out_of_cycles(drc_core *drc)
665
662
drc_append_save_volatiles(drc); /* save volatiles */
666
663
if (drc->uses_fp)