~ubuntu-branches/ubuntu/karmic/xmame/karmic

« back to all changes in this revision

Viewing changes to src/x86drc.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno Barrera C.
  • Date: 2007-02-16 10:06:54 UTC
  • mfrom: (2.1.5 edgy)
  • Revision ID: james.westby@ubuntu.com-20070216100654-iztas2cl47k5j039
Tags: 0.106-2
* Added Italian debconf templates translation. (closes: #382672)
* Added German debconf templates translation. (closes: #396610)
* Added Japanese debconf templates translation. (closes: #400011)
* Added Portuguese debconf templates translation. (closes: #409960)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*###################################################################################################
2
 
**
3
 
**
4
 
**              drccore.c
5
 
**              x86 Dynamic recompiler support routines.
6
 
**              Written by Aaron Giles
7
 
**
8
 
**
9
 
**#################################################################################################*/
10
 
 
 
1
/***************************************************************************
 
2
 
 
3
    x86drc.c
 
4
 
 
5
    x86 Dynamic recompiler support routines.
 
6
 
 
7
    Copyright (c) 1996-2006, Nicola Salmoria and the MAME Team.
 
8
    Visit http://mamedev.org for licensing and usage restrictions.
 
9
 
 
10
***************************************************************************/
 
11
 
 
12
#include "osdepend.h"
11
13
#include "driver.h"
12
14
#include "x86drc.h"
 
15
#include "debugger.h"
13
16
 
14
17
#define LOG_DISPATCHES          0
15
18
 
22
25
static UINT32 sse_control[4] = { 0x9fc0, 0xbfc0, 0xdfc0, 0xffc0 };
23
26
 
24
27
 
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);
28
32
 
29
33
#if LOG_DISPATCHES
30
 
static void log_dispatch(struct drccore *drc);
 
34
static void log_dispatch(drc_core *drc);
31
35
#endif
32
36
 
33
37
 
34
 
/*###################################################################################################
35
 
**      EXTERNAL INTERFACES
36
 
**#################################################################################################*/
 
38
/***************************************************************************
 
39
    EXTERNAL INTERFACES
 
40
***************************************************************************/
37
41
 
38
42
/*------------------------------------------------------------------
39
 
        drc_init
 
43
    drc_init
40
44
------------------------------------------------------------------*/
41
45
 
42
 
struct drccore *drc_init(UINT8 cpunum, struct drcconfig *config)
 
46
drc_core *drc_init(UINT8 cpunum, drc_config *config)
43
47
{
44
48
        int address_bits = config->address_bits;
45
49
        int effective_address_bits = address_bits - config->lsbs_to_ignore;
46
 
        struct drccore *drc;
 
50
        drc_core *drc;
47
51
 
48
52
        /* allocate memory */
49
53
        drc = malloc(sizeof(*drc));
91
95
        drc->sequence_count_max = config->max_instructions;
92
96
        drc->sequence_list = malloc(drc->sequence_count_max * sizeof(*drc->sequence_list));
93
97
        drc->tentative_count_max = config->max_instructions;
94
 
        drc->tentative_list = malloc(drc->tentative_count_max * sizeof(*drc->tentative_list));
95
 
        if (!drc->sequence_list || !drc->tentative_list)
96
 
                return NULL;
 
98
        if (drc->tentative_count_max)
 
99
        {
 
100
                drc->tentative_list = malloc(drc->tentative_count_max * sizeof(*drc->tentative_list));
 
101
                if (!drc->sequence_list || !drc->tentative_list)
 
102
                        return NULL;
 
103
        }
97
104
 
98
105
        /* seed the cache */
99
106
        drc_cache_reset(drc);
102
109
 
103
110
 
104
111
/*------------------------------------------------------------------
105
 
        drc_cache_reset
 
112
    drc_cache_reset
106
113
------------------------------------------------------------------*/
107
114
 
108
 
void drc_cache_reset(struct drccore *drc)
 
115
void drc_cache_reset(drc_core *drc)
109
116
{
110
117
        int i;
111
118
 
113
120
        drc->cache_top = drc->cache_base;
114
121
 
115
122
        /* append the core entry points to the fresh cache */
116
 
        drc->entry_point = (void (*)(void))drc->cache_top;
 
123
        drc->entry_point = (void (*)(void))(UINT32)drc->cache_top;
117
124
        append_entry_point(drc);
118
125
        drc->out_of_cycles = drc->cache_top;
119
126
        append_out_of_cycles(drc);
121
128
        append_recompile(drc);
122
129
        drc->dispatch = drc->cache_top;
123
130
        drc_append_dispatcher(drc);
 
131
        drc->flush = drc->cache_top;
 
132
        append_flush(drc);
124
133
 
125
134
        /* populate the recompile table */
126
135
        for (i = 0; i < (1 << drc->l2bits); i++)
145
154
 
146
155
 
147
156
/*------------------------------------------------------------------
148
 
        drc_execute
 
157
    drc_execute
149
158
------------------------------------------------------------------*/
150
159
 
151
 
void drc_execute(struct drccore *drc)
 
160
void drc_execute(drc_core *drc)
152
161
{
153
162
        (*drc->entry_point)();
154
163
}
155
164
 
156
165
 
157
166
/*------------------------------------------------------------------
158
 
        drc_exit
 
167
    drc_exit
159
168
------------------------------------------------------------------*/
160
169
 
161
 
void drc_exit(struct drccore *drc)
 
170
void drc_exit(drc_core *drc)
162
171
{
163
172
        int i;
164
173
 
191
200
 
192
201
 
193
202
/*------------------------------------------------------------------
194
 
        drc_begin_sequence
 
203
    drc_begin_sequence
195
204
------------------------------------------------------------------*/
196
205
 
197
 
void drc_begin_sequence(struct drccore *drc, UINT32 pc)
 
206
void drc_begin_sequence(drc_core *drc, UINT32 pc)
198
207
{
199
208
        UINT32 l1index = pc >> drc->l1shift;
200
209
        UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / 4;
208
217
        {
209
218
                /* create a new copy of the recompile table */
210
219
                drc->lookup_l1[l1index] = malloc(sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
211
 
                if (!drc->lookup_l1[l1index])
212
 
                        exit(1);
 
220
                assert_always(drc->lookup_l1[l1index], "Out of memory");
 
221
 
213
222
                memcpy(drc->lookup_l1[l1index], drc->lookup_l2_recompile, sizeof(*drc->lookup_l2_recompile) * (1 << drc->l2bits));
214
223
        }
215
224
 
228
237
 
229
238
 
230
239
/*------------------------------------------------------------------
231
 
        drc_end_sequence
 
240
    drc_end_sequence
232
241
------------------------------------------------------------------*/
233
242
 
234
 
void drc_end_sequence(struct drccore *drc)
 
243
void drc_end_sequence(drc_core *drc)
235
244
{
236
245
        int i, j;
237
246
 
250
259
 
251
260
 
252
261
/*------------------------------------------------------------------
253
 
        drc_register_code_at_cache_top
 
262
    drc_register_code_at_cache_top
254
263
------------------------------------------------------------------*/
255
264
 
256
 
void drc_register_code_at_cache_top(struct drccore *drc, UINT32 pc)
 
265
void drc_register_code_at_cache_top(drc_core *drc, UINT32 pc)
257
266
{
258
 
        struct pc_ptr_pair *pair = &drc->sequence_list[drc->sequence_count++];
259
 
        if (drc->sequence_count > drc->sequence_count_max)
260
 
                osd_die("drc_register_code_at_cache_top: too many instructions!\n");
 
267
        pc_ptr_pair *pair = &drc->sequence_list[drc->sequence_count++];
 
268
        assert_always(drc->sequence_count <= drc->sequence_count_max, "drc_register_code_at_cache_top: too many instructions!");
261
269
 
262
270
        pair->target = drc->cache_top;
263
271
        pair->pc = pc;
265
273
 
266
274
 
267
275
/*------------------------------------------------------------------
268
 
        drc_get_code_at_pc
 
276
    drc_get_code_at_pc
269
277
------------------------------------------------------------------*/
270
278
 
271
 
void *drc_get_code_at_pc(struct drccore *drc, UINT32 pc)
 
279
void *drc_get_code_at_pc(drc_core *drc, UINT32 pc)
272
280
{
273
281
        UINT32 l1index = pc >> drc->l1shift;
274
282
        UINT32 l2index = ((pc & drc->l2mask) * drc->l2scale) / 4;
277
285
 
278
286
 
279
287
/*------------------------------------------------------------------
280
 
        drc_append_verify_code
 
288
    drc_append_verify_code
281
289
------------------------------------------------------------------*/
282
290
 
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)
284
292
{
285
293
        if (length > 8)
286
294
        {
287
295
                UINT32 *codeptr = code, sum = 0;
288
296
                void *target;
289
297
                int i;
290
 
                
 
298
 
291
299
                for (i = 0; i < length / 4; i++)
292
300
                {
293
301
                        sum = (sum >> 1) | (sum << 31);
294
302
                        sum += *codeptr++;
295
303
                }
296
 
                
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 */
 
304
 
 
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 */
308
316
        }
309
317
        else if (length >= 12)
310
318
        {
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 */
317
325
        }
318
326
        else if (length >= 8)
319
327
        {
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 */
324
332
        }
325
333
        else if (length >= 4)
326
334
        {
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 */
329
337
        }
330
338
        else if (length >= 2)
331
339
        {
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 */
334
342
        }
335
343
        else
336
344
        {
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 */
339
347
        }
340
348
}
341
349
 
342
350
 
343
351
/*------------------------------------------------------------------
344
 
        drc_append_call_debugger
 
352
    drc_append_call_debugger
345
353
------------------------------------------------------------------*/
346
354
 
347
 
void drc_append_call_debugger(struct drccore *drc)
 
355
void drc_append_call_debugger(drc_core *drc)
348
356
{
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)
 
359
        {
 
360
                link_info link;
 
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);
 
365
        }
355
366
#endif
356
367
}
357
368
 
358
369
 
359
370
/*------------------------------------------------------------------
360
 
        drc_append_save_volatiles
 
371
    drc_append_save_volatiles
361
372
------------------------------------------------------------------*/
362
373
 
363
 
void drc_append_save_volatiles(struct drccore *drc)
 
374
void drc_append_save_volatiles(drc_core *drc)
364
375
{
365
376
        if (drc->icountptr && !drc->icount_in_memory)
366
377
                _mov_m32abs_r32(drc->icountptr, REG_EBP);
372
383
 
373
384
 
374
385
/*------------------------------------------------------------------
375
 
        drc_append_restore_volatiles
 
386
    drc_append_restore_volatiles
376
387
------------------------------------------------------------------*/
377
388
 
378
 
void drc_append_restore_volatiles(struct drccore *drc)
 
389
void drc_append_restore_volatiles(drc_core *drc)
379
390
{
380
391
        if (drc->icountptr && !drc->icount_in_memory)
381
392
                _mov_r32_m32abs(REG_EBP, drc->icountptr);
387
398
 
388
399
 
389
400
/*------------------------------------------------------------------
390
 
        drc_append_save_call_restore
 
401
    drc_append_save_call_restore
391
402
------------------------------------------------------------------*/
392
403
 
393
 
void drc_append_save_call_restore(struct drccore *drc, void *target, UINT32 stackadj)
 
404
void drc_append_save_call_restore(drc_core *drc, genf *target, UINT32 stackadj)
394
405
{
395
406
        drc_append_save_volatiles(drc);                                                                 /* save volatiles */
396
 
        _call(target);                                                                                                  /* call target */
 
407
        _call(target);                                                                                                  /* call target */
397
408
        drc_append_restore_volatiles(drc);                                                              /* restore volatiles */
398
409
        if (stackadj)
399
410
                _add_r32_imm(REG_ESP, stackadj);                                                        /* adjust stack */
401
412
 
402
413
 
403
414
/*------------------------------------------------------------------
404
 
        drc_append_standard_epilogue
 
415
    drc_append_standard_epilogue
405
416
------------------------------------------------------------------*/
406
417
 
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)
408
419
{
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 */
411
422
        if (cycles != 0)
412
423
        {
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 */
415
426
                else
416
 
                        _sub_r32_imm(REG_EBP, cycles);                                                  /* sub  ebp,cycles */
 
427
                        _sub_or_dec_r32_imm(REG_EBP, cycles);                                   /* sub  ebp,cycles */
417
428
        }
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 */
422
433
}
423
434
 
424
435
 
425
436
/*------------------------------------------------------------------
426
 
        drc_append_dispatcher
 
437
    drc_append_dispatcher
427
438
------------------------------------------------------------------*/
428
439
 
429
 
void drc_append_dispatcher(struct drccore *drc)
 
440
void drc_append_dispatcher(drc_core *drc)
430
441
{
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 */
434
445
#endif
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] */
443
454
}
444
455
 
445
456
 
446
457
/*------------------------------------------------------------------
447
 
        drc_append_fixed_dispatcher
 
458
    drc_append_fixed_dispatcher
448
459
------------------------------------------------------------------*/
449
460
 
450
 
void drc_append_fixed_dispatcher(struct drccore *drc, UINT32 newpc)
 
461
void drc_append_fixed_dispatcher(drc_core *drc, UINT32 newpc)
451
462
{
452
463
        void **base = drc->lookup_l1[newpc >> drc->l1shift];
453
464
        if (base == drc->lookup_l2_recompile)
454
465
        {
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] */
457
468
        }
458
469
        else
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] */
460
471
}
461
472
 
462
473
 
463
474
/*------------------------------------------------------------------
464
 
        drc_append_tentative_fixed_dispatcher
 
475
    drc_append_tentative_fixed_dispatcher
465
476
------------------------------------------------------------------*/
466
477
 
467
 
void drc_append_tentative_fixed_dispatcher(struct drccore *drc, UINT32 newpc)
 
478
void drc_append_tentative_fixed_dispatcher(drc_core *drc, UINT32 newpc)
468
479
{
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!");
472
482
 
473
483
        pair->target = drc->cache_top;
474
484
        pair->pc = newpc;
477
487
 
478
488
 
479
489
/*------------------------------------------------------------------
480
 
        drc_append_set_fp_rounding
 
490
    drc_append_set_fp_rounding
481
491
------------------------------------------------------------------*/
482
492
 
483
 
void drc_append_set_fp_rounding(struct drccore *drc, UINT8 regindex)
 
493
void drc_append_set_fp_rounding(drc_core *drc, UINT8 regindex)
484
494
{
485
495
        _fldcw_m16isd(regindex, 2, &fp_control[0]);                                             /* fldcw [fp_control + reg*2] */
486
496
        _fnstcw_m16abs(&drc->fpcw_curr);                                                                /* fnstcw [fpcw_curr] */
489
499
 
490
500
 
491
501
/*------------------------------------------------------------------
492
 
        drc_append_set_temp_fp_rounding
 
502
    drc_append_set_temp_fp_rounding
493
503
------------------------------------------------------------------*/
494
504
 
495
 
void drc_append_set_temp_fp_rounding(struct drccore *drc, UINT8 rounding)
 
505
void drc_append_set_temp_fp_rounding(drc_core *drc, UINT8 rounding)
496
506
{
497
507
        _fldcw_m16abs(&fp_control[rounding]);                                                   /* fldcw [fp_control] */
498
508
}
500
510
 
501
511
 
502
512
/*------------------------------------------------------------------
503
 
        drc_append_restore_fp_rounding
 
513
    drc_append_restore_fp_rounding
504
514
------------------------------------------------------------------*/
505
515
 
506
 
void drc_append_restore_fp_rounding(struct drccore *drc)
 
516
void drc_append_restore_fp_rounding(drc_core *drc)
507
517
{
508
518
        _fldcw_m16abs(&drc->fpcw_curr);                                                                 /* fldcw [fpcw_curr] */
509
519
}
511
521
 
512
522
 
513
523
/*------------------------------------------------------------------
514
 
        drc_append_set_sse_rounding
 
524
    drc_append_set_sse_rounding
515
525
------------------------------------------------------------------*/
516
526
 
517
 
void drc_append_set_sse_rounding(struct drccore *drc, UINT8 regindex)
 
527
void drc_append_set_sse_rounding(drc_core *drc, UINT8 regindex)
518
528
{
519
529
        _ldmxcsr_m32isd(regindex, 4, &sse_control[0]);                                  /* ldmxcsr [sse_control + reg*2] */
520
530
        _stmxcsr_m32abs(&drc->mxcsr_curr);                                                              /* stmxcsr [mxcsr_curr] */
523
533
 
524
534
 
525
535
/*------------------------------------------------------------------
526
 
        drc_append_set_temp_sse_rounding
 
536
    drc_append_set_temp_sse_rounding
527
537
------------------------------------------------------------------*/
528
538
 
529
 
void drc_append_set_temp_sse_rounding(struct drccore *drc, UINT8 rounding)
 
539
void drc_append_set_temp_sse_rounding(drc_core *drc, UINT8 rounding)
530
540
{
531
541
        _ldmxcsr_m32abs(&sse_control[rounding]);                                                /* ldmxcsr [sse_control] */
532
542
}
534
544
 
535
545
 
536
546
/*------------------------------------------------------------------
537
 
        drc_append_restore_sse_rounding
 
547
    drc_append_restore_sse_rounding
538
548
------------------------------------------------------------------*/
539
549
 
540
 
void drc_append_restore_sse_rounding(struct drccore *drc)
 
550
void drc_append_restore_sse_rounding(drc_core *drc)
541
551
{
542
552
        _ldmxcsr_m32abs(&drc->mxcsr_curr);                                                              /* ldmxcsr [mxcsr_curr] */
543
553
}
545
555
 
546
556
 
547
557
/*------------------------------------------------------------------
548
 
        drc_dasm
 
558
    drc_dasm
549
559
 
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
------------------------------------------------------------------*/
553
563
 
554
 
void drc_dasm(FILE *f, unsigned pc, void *begin, void *end)
 
564
void drc_dasm(FILE *f, const void *begin, const void *end)
555
565
{
556
 
#if 0
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);
558
567
 
559
568
        char buffer[256];
560
 
        char buffer2[256];
561
 
        unsigned addr = (unsigned) begin;
562
 
        unsigned addr_end = (unsigned) end;
563
 
        unsigned offset;
564
 
        UINT8 *saved_op_rom;
565
 
        UINT8 *saved_op_ram;
566
 
        size_t saved_op_mem_min;
567
 
        size_t saved_op_mem_max;
568
 
 
569
 
        activecpu_dasm(buffer, pc);
570
 
        if (addr == addr_end)
571
 
        {
572
 
                logerror("%08x: %s\t(NOP)\n", pc, buffer);
573
 
        }
574
 
        else
575
 
        {
576
 
                logerror("%08x: %s\t(%08x-%08x)\n", pc, buffer, addr, addr_end - 1);
577
 
 
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;
585
 
 
586
 
                while(addr < addr_end)
587
 
                {
588
 
                        offset = DasmI386(buffer, addr);
589
 
                        sprintf(buffer2, "\t%08x: %s\n", addr, buffer);
590
 
                        logerror("%s", buffer2);
591
 
                        if (f)
592
 
                                fputs(buffer2, f);
593
 
                        addr += offset;
594
 
                }
595
 
 
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;
600
 
        }
 
569
        const UINT8 *begin_ptr = (const UINT8 *) begin;
 
570
        const UINT8 *end_ptr = (const UINT8 *) end;
 
571
        UINT32 pc = (UINT32) begin;
 
572
        int length;
 
573
 
 
574
        while(begin_ptr < end_ptr)
 
575
        {
 
576
#if defined(MAME_DEBUG) && HAS_I386
 
577
                length = i386_dasm_one(buffer, pc, (UINT8 *) begin_ptr, 1, 1) & DASMFLAG_LENGTHMASK;
 
578
#else
 
579
                sprintf(buffer, "%02X", *begin_ptr);
 
580
                length = 1;
601
581
#endif
 
582
 
 
583
                fprintf(f, "%08X:\t%s\n", (unsigned) pc, buffer);
 
584
                begin_ptr += length;
 
585
                pc += length;
 
586
        }
602
587
}
603
588
 
604
589
 
605
590
 
606
591
 
607
 
/*###################################################################################################
608
 
**      INTERNAL CODEGEN
609
 
**#################################################################################################*/
 
592
/***************************************************************************
 
593
    INTERNAL CODEGEN
 
594
***************************************************************************/
610
595
 
611
596
/*------------------------------------------------------------------
612
 
        append_entry_point
 
597
    append_entry_point
613
598
------------------------------------------------------------------*/
614
599
 
615
 
static void append_entry_point(struct drccore *drc)
 
600
static void append_entry_point(drc_core *drc)
616
601
{
617
602
        _pushad();                                                                                                              /* pushad */
618
603
        if (drc->uses_fp)
633
618
 
634
619
 
635
620
/*------------------------------------------------------------------
636
 
        recompile_code
 
621
    recompile_code
637
622
------------------------------------------------------------------*/
638
623
 
639
 
static void recompile_code(struct drccore *drc)
 
624
static void recompile_code(drc_core *drc)
640
625
{
641
626
        if (drc->cache_top >= drc->cache_danger)
642
627
                drc_cache_reset(drc);
645
630
 
646
631
 
647
632
/*------------------------------------------------------------------
648
 
        append_recompile
649
 
------------------------------------------------------------------*/
650
 
 
651
 
static void append_recompile(struct drccore *drc)
652
 
{
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 */
656
 
}
657
 
 
658
 
 
659
 
/*------------------------------------------------------------------
660
 
        append_out_of_cycles
661
 
------------------------------------------------------------------*/
662
 
 
663
 
static void append_out_of_cycles(struct drccore *drc)
 
633
    append_recompile
 
634
------------------------------------------------------------------*/
 
635
 
 
636
static void append_recompile(drc_core *drc)
 
637
{
 
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 */
 
641
}
 
642
 
 
643
 
 
644
/*------------------------------------------------------------------
 
645
    append_flush
 
646
------------------------------------------------------------------*/
 
647
 
 
648
static void append_flush(drc_core *drc)
 
649
{
 
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 */
 
653
}
 
654
 
 
655
 
 
656
/*------------------------------------------------------------------
 
657
    append_out_of_cycles
 
658
------------------------------------------------------------------*/
 
659
 
 
660
static void append_out_of_cycles(drc_core *drc)
664
661
{
665
662
        drc_append_save_volatiles(drc);                                                                 /* save volatiles */
666
663
        if (drc->uses_fp)
677
674
 
678
675
 
679
676
/*------------------------------------------------------------------
680
 
        drc_x86_get_features()
 
677
    drc_x86_get_features()
681
678
------------------------------------------------------------------*/
682
679
UINT32 drc_x86_get_features(void)
683
680
{
684
681
        UINT32 features = 0;
685
682
#ifdef _MSC_VER
686
 
        __asm 
 
683
        __asm
687
684
        {
688
685
                mov eax, 1
689
686
                xor ebx, ebx
690
687
                xor ecx, ecx
691
688
                xor edx, edx
692
 
                cpuid
 
689
                __asm _emit 0Fh __asm _emit 0A2h        /* cpuid */
693
690
                mov features, edx
694
691
        }
695
692
#else /* !_MSC_VER */
696
693
        __asm__
697
694
        (
 
695
                "pushl %%ebx         ; "
698
696
                "movl $1,%%eax       ; "
699
697
                "xorl %%ebx,%%ebx    ; "
700
698
                "xorl %%ecx,%%ecx    ; "
701
699
                "xorl %%edx,%%edx    ; "
702
700
                "cpuid               ; "
703
701
                "movl %%edx,%0       ; "
 
702
                "popl %%ebx          ; "
704
703
        : "=&a" (features)              /* result has to go in eax */
705
704
        :                               /* no inputs */
706
 
        : "%ebx", "%ecx", "%edx"        /* clobbers ebx, ecx and edx */
 
705
        : "%ecx", "%edx"        /* clobbers ebx, ecx and edx */
707
706
        );
708
707
#endif /* MSC_VER */
709
708
        return features;
712
711
 
713
712
 
714
713
/*------------------------------------------------------------------
715
 
        log_dispatch
 
714
    log_dispatch
716
715
------------------------------------------------------------------*/
717
716
 
718
717
#if LOG_DISPATCHES
719
 
static void log_dispatch(struct drccore *drc)
 
718
static void log_dispatch(drc_core *drc)
720
719
{
721
720
        if (code_pressed(KEYCODE_D))
722
721
                logerror("Disp:%08X\n", *drc->pcptr);