Revision 7bfdb6d1

b/op-i386.c
1
typedef unsigned char uint8_t;
2
typedef unsigned short uint16_t;
3
typedef unsigned int uint32_t;
4
typedef unsigned long long uint64_t;
5

  
6
typedef signed char int8_t;
7
typedef signed short int16_t;
8
typedef signed int int32_t;
9
typedef signed long long int64_t;
10

  
11
#ifdef __i386__
12
register int T0 asm("esi");
13
register int T1 asm("ebx");
14
register int A0 asm("edi");
15
register struct CPU86State *env asm("ebp");
16
#define FORCE_RET() asm volatile ("ret");
17
#endif
18
#ifdef __powerpc__
19
register int T0 asm("r24");
20
register int T1 asm("r25");
21
register int A0 asm("r26");
22
register struct CPU86State *env asm("r27");
23
#define FORCE_RET() asm volatile ("blr");
24
#endif
25
#ifdef __arm__
26
register int T0 asm("r4");
27
register int T1 asm("r5");
28
register int A0 asm("r6");
29
register struct CPU86State *env asm("r7");
30
#define FORCE_RET() asm volatile ("mov pc, lr");
31
#endif
32
#ifdef __mips__
33
register int T0 asm("s0");
34
register int T1 asm("s1");
35
register int A0 asm("s2");
36
register struct CPU86State *env asm("s3");
37
#define FORCE_RET() asm volatile ("jr $31");
38
#endif
39
#ifdef __sparc__
40
register int T0 asm("l0");
41
register int T1 asm("l1");
42
register int A0 asm("l2");
43
register struct CPU86State *env asm("l3");
44
#define FORCE_RET() asm volatile ("retl ; nop");
45
#endif
46

  
47
#ifndef OPPROTO
48
#define OPPROTO
49
#endif
50

  
51
#define xglue(x, y) x ## y
52
#define glue(x, y) xglue(x, y)
53

  
54
#define EAX (env->regs[R_EAX])
55
#define ECX (env->regs[R_ECX])
56
#define EDX (env->regs[R_EDX])
57
#define EBX (env->regs[R_EBX])
58
#define ESP (env->regs[R_ESP])
59
#define EBP (env->regs[R_EBP])
60
#define ESI (env->regs[R_ESI])
61
#define EDI (env->regs[R_EDI])
62
#define PC  (env->pc)
63
#define DF  (env->df)
64

  
65
#define CC_SRC (env->cc_src)
66
#define CC_DST (env->cc_dst)
67
#define CC_OP (env->cc_op)
68

  
69
extern int __op_param1, __op_param2, __op_param3;
70
#define PARAM1 ((long)(&__op_param1))
71
#define PARAM2 ((long)(&__op_param2))
72
#define PARAM3 ((long)(&__op_param3))
73

  
74
#include "cpu-i386.h"
75

  
76
typedef struct CCTable {
77
    int (*compute_c)(void);  /* return the C flag */
78
    int (*compute_z)(void);  /* return the Z flag */
79
    int (*compute_s)(void);  /* return the S flag */
80
    int (*compute_o)(void);  /* return the O flag */
81
    int (*compute_all)(void); /* return all the flags */
82
} CCTable;
83

  
84
uint8_t parity_table[256] = {
85
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
86
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
87
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
88
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
89
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
90
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
91
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
92
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
93
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
94
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
95
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
96
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
97
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
98
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
99
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
100
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
101
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
102
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
103
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
104
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
105
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
106
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
107
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
108
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
109
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
110
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
111
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
112
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
113
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
114
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
115
    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
116
    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
117
};
118

  
119
static int compute_eflags_all(void)
120
{
121
    return CC_SRC;
122
}
123

  
124
static int compute_eflags_addb(void)
125
{
126
    int cf, pf, af, zf, sf, of;
127
    int src1, src2;
128
    src1 = CC_SRC;
129
    src2 = CC_DST - CC_SRC;
130
    cf = (uint8_t)CC_DST < (uint8_t)src1;
131
    pf = parity_table[(uint8_t)CC_DST];
132
    af = (CC_DST ^ src1 ^ src2) & 0x10;
133
    zf = ((uint8_t)CC_DST != 0) << 6;
134
    sf = CC_DST & 0x80;
135
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
136
    return cf | pf | af | zf | sf | of;
137
}
138

  
139
static int compute_eflags_subb(void)
140
{
141
    int cf, pf, af, zf, sf, of;
142
    int src1, src2;
143
    src1 = CC_SRC;
144
    src2 = CC_SRC - CC_DST;
145
    cf = (uint8_t)src1 < (uint8_t)src2;
146
    pf = parity_table[(uint8_t)CC_DST];
147
    af = (CC_DST ^ src1 ^ src2) & 0x10;
148
    zf = ((uint8_t)CC_DST != 0) << 6;
149
    sf = CC_DST & 0x80;
150
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
151
    return cf | pf | af | zf | sf | of;
152
}
153

  
154
static int compute_eflags_logicb(void)
155
{
156
    cf = 0;
157
    pf = parity_table[(uint8_t)CC_DST];
158
    af = 0;
159
    zf = ((uint8_t)CC_DST != 0) << 6;
160
    sf = CC_DST & 0x80;
161
    of = 0;
162
    return cf | pf | af | zf | sf | of;
163
}
164

  
165
static int compute_eflags_incb(void)
166
{
167
    int cf, pf, af, zf, sf, of;
168
    int src2;
169
    src1 = CC_DST - 1;
170
    src2 = 1;
171
    cf = CC_SRC;
172
    pf = parity_table[(uint8_t)CC_DST];
173
    af = (CC_DST ^ src1 ^ src2) & 0x10;
174
    zf = ((uint8_t)CC_DST != 0) << 6;
175
    sf = CC_DST & 0x80;
176
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
177
    return cf | pf | af | zf | sf | of;
178
}
179

  
180
static int compute_eflags_decb(void)
181
{
182
    int cf, pf, af, zf, sf, of;
183
    int src1, src2;
184
    src1 = CC_DST + 1;
185
    src2 = 1;
186
    cf = (uint8_t)src1 < (uint8_t)src2;
187
    pf = parity_table[(uint8_t)CC_DST];
188
    af = (CC_DST ^ src1 ^ src2) & 0x10;
189
    zf = ((uint8_t)CC_DST != 0) << 6;
190
    sf = CC_DST & 0x80;
191
    of = ((src1 ^ src2 ^ -1) & (src1 ^ CC_DST) & 0x80) << 4;
192
    return cf | pf | af | zf | sf | of;
193
}
194

  
195
static int compute_eflags_shlb(void)
196
{
197
    cf = CC_SRC;
198
    pf = parity_table[(uint8_t)CC_DST];
199
    af = 0; /* undefined */
200
    zf = ((uint8_t)CC_DST != 0) << 6;
201
    sf = CC_DST & 0x80;
202
    of = 0; /* undefined */
203
    return cf | pf | af | zf | sf | of;
204
}
205

  
206
static int compute_eflags_shrb(void)
207
{
208
    cf = CC_SRC & 1;
209
    pf = parity_table[(uint8_t)CC_DST];
210
    af = 0; /* undefined */
211
    zf = ((uint8_t)CC_DST != 0) << 6;
212
    sf = CC_DST & 0x80;
213
    of = sf << 4;
214
    return cf | pf | af | zf | sf | of;
215
}
216

  
217
static int compute_eflags_mul(void)
218
{
219
    cf = (CC_SRC != 0);
220
    pf = 0; /* undefined */
221
    af = 0; /* undefined */
222
    zf = 0; /* undefined */
223
    sf = 0; /* undefined */
224
    of = cf << 11;
225
    return cf | pf | af | zf | sf | of;
226
}
227
    
228
CTable cc_table[CC_OP_NB] = {
229
    [CC_OP_DYNAMIC] = { NULL, NULL, NULL },
230
    [CC_OP_EFLAGS] = { NULL, NULL, NULL },
231
    
232
};
233

  
234
/* we define the various pieces of code used by the JIT */
235

  
236
#define REG EAX
237
#define REGNAME _EAX
238
#include "opreg_template.h"
239
#undef REG
240
#undef REGNAME
241

  
242
#define REG ECX
243
#define REGNAME _ECX
244
#include "opreg_template.h"
245
#undef REG
246
#undef REGNAME
247

  
248
#define REG EDX
249
#define REGNAME _EDX
250
#include "opreg_template.h"
251
#undef REG
252
#undef REGNAME
253

  
254
#define REG EBX
255
#define REGNAME _EBX
256
#include "opreg_template.h"
257
#undef REG
258
#undef REGNAME
259

  
260
#define REG ESP
261
#define REGNAME _ESP
262
#include "opreg_template.h"
263
#undef REG
264
#undef REGNAME
265

  
266
#define REG EBP
267
#define REGNAME _EBP
268
#include "opreg_template.h"
269
#undef REG
270
#undef REGNAME
271

  
272
#define REG ESI
273
#define REGNAME _ESI
274
#include "opreg_template.h"
275
#undef REG
276
#undef REGNAME
277

  
278
#define REG EDI
279
#define REGNAME _EDI
280
#include "opreg_template.h"
281
#undef REG
282
#undef REGNAME
283

  
284
/* operations */
285

  
286
void OPPROTO op_addl_T0_T1_cc(void)
287
{
288
    CC_SRC = T0;
289
    T0 += T1;
290
    CC_DST = T0;
291
}
292

  
293
void OPPROTO op_orl_T0_T1_cc(void)
294
{
295
    T0 |= T1;
296
    CC_DST = T0;
297
}
298

  
299
void OPPROTO op_adcl_T0_T1_cc(void)
300
{
301
    CC_SRC = T0;
302
    T0 = T0 + T1 + cc_table[CC_OP].compute_c();
303
    CC_DST = T0;
304
}
305

  
306
void OPPROTO op_sbbl_T0_T1_cc(void)
307
{
308
    CC_SRC = T0;
309
    T0 = T0 - T1 - cc_table[CC_OP].compute_c();
310
    CC_DST = T0;
311
}
312

  
313
void OPPROTO op_andl_T0_T1_cc(void)
314
{
315
    T0 &= T1;
316
    CC_DST = T0;
317
}
318

  
319
void OPPROTO op_subl_T0_T1_cc(void)
320
{
321
    CC_SRC = T0;
322
    T0 -= T1;
323
    CC_DST = T0;
324
}
325

  
326
void OPPROTO op_xorl_T0_T1_cc(void)
327
{
328
    T0 ^= T1;
329
    CC_DST = T0;
330
}
331

  
332
void OPPROTO op_cmpl_T0_T1_cc(void)
333
{
334
    CC_SRC = T0;
335
    CC_DST = T0 - T1;
336
}
337

  
338
void OPPROTO op_notl_T0(void)
339
{
340
    T0 = ~T0;
341
}
342

  
343
void OPPROTO op_negl_T0_cc(void)
344
{
345
    CC_SRC = 0;
346
    T0 = -T0;
347
    CC_DST = T0;
348
}
349

  
350
void OPPROTO op_incl_T0_cc(void)
351
{
352
    T0++;
353
    CC_DST = T0;
354
}
355

  
356
void OPPROTO op_decl_T0_cc(void)
357
{
358
    T0--;
359
    CC_DST = T0;
360
}
361

  
362
void OPPROTO op_testl_T0_T1_cc(void)
363
{
364
    CC_SRC = T0;
365
    CC_DST = T0 & T1;
366
}
367

  
368
/* shifts */
369

  
370
void OPPROTO op_roll_T0_T1_cc(void)
371
{
372
    int count;
373
    count = T1 & 0x1f;
374
    if (count) {
375
        CC_SRC = T0;
376
        T0 = (T0 << count) | (T0 >> (32 - count));
377
        CC_DST = T0;
378
        CC_OP = CC_OP_ROLL;
379
    }
380
}
381

  
382
void OPPROTO op_rolw_T0_T1_cc(void)
383
{
384
    int count;
385
    count = T1 & 0xf;
386
    if (count) {
387
        T0 = T0 & 0xffff;
388
        CC_SRC = T0;
389
        T0 = (T0 << count) | (T0 >> (16 - count));
390
        CC_DST = T0;
391
        CC_OP = CC_OP_ROLW;
392
    }
393
}
394

  
395
void OPPROTO op_rolb_T0_T1_cc(void)
396
{
397
    int count;
398
    count = T1 & 0x7;
399
    if (count) {
400
        T0 = T0 & 0xff;
401
        CC_SRC = T0;
402
        T0 = (T0 << count) | (T0 >> (8 - count));
403
        CC_DST = T0;
404
        CC_OP = CC_OP_ROLB;
405
    }
406
}
407

  
408
void OPPROTO op_rorl_T0_T1_cc(void)
409
{
410
    int count;
411
    count = T1 & 0x1f;
412
    if (count) {
413
        CC_SRC = T0;
414
        T0 = (T0 >> count) | (T0 << (32 - count));
415
        CC_DST = T0;
416
        CC_OP = CC_OP_RORB;
417
    }
418
}
419

  
420
void OPPROTO op_rorw_T0_T1_cc(void)
421
{
422
    int count;
423
    count = T1 & 0xf;
424
    if (count) {
425
        CC_SRC = T0;
426
        T0 = (T0 >> count) | (T0 << (16 - count));
427
        CC_DST = T0;
428
        CC_OP = CC_OP_RORW;
429
    }
430
}
431

  
432
void OPPROTO op_rorb_T0_T1_cc(void)
433
{
434
    int count;
435
    count = T1 & 0x7;
436
    if (count) {
437
        CC_SRC = T0;
438
        T0 = (T0 >> count) | (T0 << (8 - count));
439
        CC_DST = T0;
440
        CC_OP = CC_OP_RORL;
441
    }
442
}
443

  
444
/* modulo 17 table */
445
const uint8_t rclw_table[32] = {
446
    0, 1, 2, 3, 4, 5, 6, 7, 
447
    8, 9,10,11,12,13,14,15,
448
   16, 0, 1, 2, 3, 4, 5, 6,
449
    7, 8, 9,10,11,12,13,14,
450
};
451

  
452
/* modulo 9 table */
453
const uint8_t rclb_table[32] = {
454
    0, 1, 2, 3, 4, 5, 6, 7, 
455
    8, 0, 1, 2, 3, 4, 5, 6,
456
    7, 8, 0, 1, 2, 3, 4, 5, 
457
    6, 7, 8, 0, 1, 2, 3, 4,
458
};
459

  
460
void helper_rcll_T0_T1_cc(void)
461
{
462
    int count, res;
463

  
464
    count = T1 & 0x1f;
465
    if (count) {
466
        CC_SRC = T0;
467
        res = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1));
468
        if (count > 1)
469
            res |= T0 >> (33 - count);
470
        T0 = res;
471
        CC_DST = T0 ^ CC_SRC;    /* O is in bit 31 */
472
        CC_SRC >>= (32 - count); /* CC is in bit 0 */
473
        CC_OP = CC_OP_RCLL;
474
    }
475
}
476

  
477
void OPPROTO op_rcll_T0_T1_cc(void)
478
{
479
    helper_rcll_T0_T1_cc();
480
}
481

  
482
void OPPROTO op_rclw_T0_T1_cc(void)
483
{
484
    int count;
485
    count = rclw_table[T1 & 0x1f];
486
    if (count) {
487
        T0 = T0 & 0xffff;
488
        CC_SRC = T0;
489
        T0 = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1)) |
490
            (T0 >> (17 - count));
491
        CC_DST = T0 ^ CC_SRC;
492
        CC_SRC >>= (16 - count);
493
        CC_OP = CC_OP_RCLW;
494
    }
495
}
496

  
497
void OPPROTO op_rclb_T0_T1_cc(void)
498
{
499
    int count;
500
    count = rclb_table[T1 & 0x1f];
501
    if (count) {
502
        T0 = T0 & 0xff;
503
        CC_SRC = T0;
504
        T0 = (T0 << count) | (cc_table[CC_OP].compute_c() << (count - 1)) |
505
            (T0 >> (9 - count));
506
        CC_DST = T0 ^ CC_SRC;
507
        CC_SRC >>= (8 - count);
508
        CC_OP = CC_OP_RCLB;
509
    }
510
}
511

  
512
void OPPROTO op_rcrl_T0_T1_cc(void)
513
{
514
    int count, res;
515
    count = T1 & 0x1f;
516
    if (count) {
517
        CC_SRC = T0;
518
        res = (T0 >> count) | (cc_table[CC_OP].compute_c() << (32 - count));
519
        if (count > 1)
520
            res |= T0 << (33 - count);
521
        T0 = res;
522
        CC_DST = T0 ^ CC_SRC;
523
        CC_SRC >>= (count - 1);
524
        CC_OP = CC_OP_RCLL;
525
    }
526
}
527

  
528
void OPPROTO op_rcrw_T0_T1_cc(void)
529
{
530
    int count;
531
    count = rclw_table[T1 & 0x1f];
532
    if (count) {
533
        T0 = T0 & 0xffff;
534
        CC_SRC = T0;
535
        T0 = (T0 >> count) | (cc_table[CC_OP].compute_c() << (16 - count)) |
536
            (T0 << (17 - count));
537
        CC_DST = T0 ^ CC_SRC;
538
        CC_SRC >>= (count - 1);
539
        CC_OP = CC_OP_RCLW;
540
    }
541
}
542

  
543
void OPPROTO op_rcrb_T0_T1_cc(void)
544
{
545
    int count;
546
    count = rclb_table[T1 & 0x1f];
547
    if (count) {
548
        T0 = T0 & 0xff;
549
        CC_SRC = T0;
550
        T0 = (T0 >> count) | (cc_table[CC_OP].compute_c() << (8 - count)) |
551
            (T0 << (9 - count));
552
        CC_DST = T0 ^ CC_SRC;
553
        CC_SRC >>= (count - 1);
554
        CC_OP = CC_OP_RCLB;
555
    }
556
}
557

  
558
void OPPROTO op_shll_T0_T1_cc(void)
559
{
560
    int count;
561
    count = T1 & 0x1f;
562
    if (count == 1) {
563
        CC_SRC = T0;
564
        T0 = T0 << 1;
565
        CC_DST = T0;
566
        CC_OP = CC_OP_ADDL;
567
    } else if (count) {
568
        CC_SRC = T0 >> (32 - count);
569
        T0 = T0 << count;
570
        CC_DST = T0;
571
        CC_OP = CC_OP_SHLL;
572
    }
573
}
574

  
575
void OPPROTO op_shlw_T0_T1_cc(void)
576
{
577
    int count;
578
    count = T1 & 0x1f;
579
    if (count == 1) {
580
        CC_SRC = T0;
581
        T0 = T0 << 1;
582
        CC_DST = T0;
583
        CC_OP = CC_OP_ADDW;
584
    } else if (count) {
585
        CC_SRC = T0 >> (16 - count);
586
        T0 = T0 << count;
587
        CC_DST = T0;
588
        CC_OP = CC_OP_SHLW;
589
    }
590
}
591

  
592
void OPPROTO op_shlb_T0_T1_cc(void)
593
{
594
    int count;
595
    count = T1 & 0x1f;
596
    if (count == 1) {
597
        CC_SRC = T0;
598
        T0 = T0 << 1;
599
        CC_DST = T0;
600
        CC_OP = CC_OP_ADDB;
601
    } else if (count) {
602
        CC_SRC = T0 >> (8 - count);
603
        T0 = T0 << count;
604
        CC_DST = T0;
605
        CC_OP = CC_OP_SHLB;
606
    }
607
}
608

  
609
void OPPROTO op_shrl_T0_T1_cc(void)
610
{
611
    int count;
612
    count = T1 & 0x1f;
613
    if (count == 1) {
614
        CC_SRC = T0;
615
        T0 = T0 >> 1;
616
        CC_DST = T0;
617
        CC_OP = CC_OP_SHRL;
618
    } else if (count) {
619
        CC_SRC = T0 >> (count - 1);
620
        T0 = T0 >> count;
621
        CC_DST = T0;
622
        CC_OP = CC_OP_SHLL;
623
    }
624
}
625

  
626
void OPPROTO op_shrw_T0_T1_cc(void)
627
{
628
    int count;
629
    count = T1 & 0x1f;
630
    if (count == 1) {
631
        T0 = T0 & 0xffff;
632
        CC_SRC = T0;
633
        T0 = T0 >> 1;
634
        CC_DST = T0;
635
        CC_OP = CC_OP_SHRW;
636
    } else if (count) {
637
        T0 = T0 & 0xffff;
638
        CC_SRC = T0 >> (count - 1);
639
        T0 = T0 >> count;
640
        CC_DST = T0;
641
        CC_OP = CC_OP_SHLW;
642
    }
643
}
644

  
645
void OPPROTO op_shrb_T0_T1_cc(void)
646
{
647
    int count;
648
    count = T1 & 0x1f;
649
    if (count == 1) {
650
        T0 = T0 & 0xff;
651
        CC_SRC = T0;
652
        T0 = T0 >> 1;
653
        CC_DST = T0;
654
        CC_OP = CC_OP_SHRB;
655
    } else if (count) {
656
        T0 = T0 & 0xff;
657
        CC_SRC = T0 >> (count - 1);
658
        T0 = T0 >> count;
659
        CC_DST = T0;
660
        CC_OP = CC_OP_SHLB;
661
    }
662
}
663

  
664
void OPPROTO op_sarl_T0_T1_cc(void)
665
{
666
    int count;
667
    count = T1 & 0x1f;
668
    if (count) {
669
        CC_SRC = (int32_t)T0 >> (count - 1);
670
        T0 = (int32_t)T0 >> count;
671
        CC_DST = T0;
672
        CC_OP = CC_OP_SHLL;
673
    }
674
}
675

  
676
void OPPROTO op_sarw_T0_T1_cc(void)
677
{
678
    int count;
679
    count = T1 & 0x1f;
680
    if (count) {
681
        CC_SRC = (int16_t)T0 >> (count - 1);
682
        T0 = (int16_t)T0 >> count;
683
        CC_DST = T0;
684
        CC_OP = CC_OP_SHLW;
685
    }
686
}
687

  
688
void OPPROTO op_sarb_T0_T1_cc(void)
689
{
690
    int count;
691
    count = T1 & 0x1f;
692
    if (count) {
693
        CC_SRC = (int8_t)T0 >> (count - 1);
694
        T0 = (int8_t)T0 >> count;
695
        CC_DST = T0;
696
        CC_OP = CC_OP_SHLB;
697
    }
698
}
699

  
700
/* multiply/divide */
701
void OPPROTO op_mulb_AL_T0(void)
702
{
703
    unsigned int res;
704
    res = (uint8_t)EAX * (uint8_t)T0;
705
    EAX = (EAX & 0xffff0000) | res;
706
    CC_SRC = (res & 0xff00);
707
}
708

  
709
void OPPROTO op_imulb_AL_T0(void)
710
{
711
    int res;
712
    res = (int8_t)EAX * (int8_t)T0;
713
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
714
    CC_SRC = (res != (int8_t)res);
715
}
716

  
717
void OPPROTO op_mulw_AX_T0(void)
718
{
719
    unsigned int res;
720
    res = (uint16_t)EAX * (uint16_t)T0;
721
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
722
    EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
723
    CC_SRC = res >> 16;
724
}
725

  
726
void OPPROTO op_imulw_AX_T0(void)
727
{
728
    int res;
729
    res = (int16_t)EAX * (int16_t)T0;
730
    EAX = (EAX & 0xffff0000) | (res & 0xffff);
731
    EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
732
    CC_SRC = (res != (int16_t)res);
733
}
734

  
735
void OPPROTO op_mull_EAX_T0(void)
736
{
737
    uint64_t res;
738
    res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
739
    EAX = res;
740
    EDX = res >> 32;
741
    CC_SRC = res >> 32;
742
}
743

  
744
void OPPROTO op_imull_EAX_T0(void)
745
{
746
    int64_t res;
747
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
748
    EAX = res;
749
    EDX = res >> 32;
750
    CC_SRC = (res != (int32_t)res);
751
}
752

  
753
void OPPROTO op_imulw_T0_T1(void)
754
{
755
    int res;
756
    res = (int16_t)T0 * (int16_t)T1;
757
    T0 = res;
758
    CC_SRC = (res != (int16_t)res);
759
}
760

  
761
void OPPROTO op_imull_T0_T1(void)
762
{
763
    int64_t res;
764
    res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T1);
765
    T0 = res;
766
    CC_SRC = (res != (int32_t)res);
767
}
768

  
769
/* division, flags are undefined */
770
/* XXX: add exceptions for overflow & div by zero */
771
void OPPROTO op_divb_AL_T0(void)
772
{
773
    unsigned int num, den, q, r;
774

  
775
    num = (EAX & 0xffff);
776
    den = (T0 & 0xff);
777
    q = (num / den) & 0xff;
778
    r = (num % den) & 0xff;
779
    EAX = (EAX & 0xffff0000) | (r << 8) | q;
780
}
781

  
782
void OPPROTO op_idivb_AL_T0(void)
783
{
784
    int num, den, q, r;
785

  
786
    num = (int16_t)EAX;
787
    den = (int8_t)T0;
788
    q = (num / den) & 0xff;
789
    r = (num % den) & 0xff;
790
    EAX = (EAX & 0xffff0000) | (r << 8) | q;
791
}
792

  
793
void OPPROTO op_divw_AX_T0(void)
794
{
795
    unsigned int num, den, q, r;
796

  
797
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
798
    den = (T0 & 0xffff);
799
    q = (num / den) & 0xffff;
800
    r = (num % den) & 0xffff;
801
    EAX = (EAX & 0xffff0000) | q;
802
    EDX = (EDX & 0xffff0000) | r;
803
}
804

  
805
void OPPROTO op_idivw_AX_T0(void)
806
{
807
    int num, den, q, r;
808

  
809
    num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
810
    den = (int16_t)T0;
811
    q = (num / den) & 0xffff;
812
    r = (num % den) & 0xffff;
813
    EAX = (EAX & 0xffff0000) | q;
814
    EDX = (EDX & 0xffff0000) | r;
815
}
816

  
817
void OPPROTO op_divl_EAX_T0(void)
818
{
819
    unsigned int den, q, r;
820
    uint64_t num;
821
    
822
    num = EAX | ((uint64_t)EDX << 32);
823
    den = T0;
824
    q = (num / den);
825
    r = (num % den);
826
    EAX = q;
827
    EDX = r;
828
}
829

  
830
void OPPROTO op_idivl_EAX_T0(void)
831
{
832
    int den, q, r;
833
    int16_t num;
834
    
835
    num = EAX | ((uint64_t)EDX << 32);
836
    den = (int16_t)T0;
837
    q = (num / den);
838
    r = (num % den);
839
    EAX = q;
840
    EDX = r;
841
}
842

  
843
/* constant load */
844

  
845
void OPPROTO op1_movl_T0_im(void)
846
{
847
    T0 = PARAM1;
848
}
849

  
850
void OPPROTO op1_movl_T1_im(void)
851
{
852
    T1 = PARAM1;
853
}
854

  
855
void OPPROTO op1_movl_A0_im(void)
856
{
857
    A0 = PARAM1;
858
}
859

  
860
/* memory access */
861

  
862
void OPPROTO op_ldub_T0_A0(void)
863
{
864
    T0 = ldub((uint8_t *)A0);
865
}
866

  
867
void OPPROTO op_ldsb_T0_A0(void)
868
{
869
    T0 = ldsb((int8_t *)A0);
870
}
871

  
872
void OPPROTO op_lduw_T0_A0(void)
873
{
874
    T0 = lduw((uint8_t *)A0);
875
}
876

  
877
void OPPROTO op_ldsw_T0_A0(void)
878
{
879
    T0 = ldsw((int8_t *)A0);
880
}
881

  
882
void OPPROTO op_ldl_T0_A0(void)
883
{
884
    T0 = ldl((uint8_t *)A0);
885
}
886

  
887
void OPPROTO op_ldub_T1_A0(void)
888
{
889
    T1 = ldub((uint8_t *)A0);
890
}
891

  
892
void OPPROTO op_ldsb_T1_A0(void)
893
{
894
    T1 = ldsb((int8_t *)A0);
895
}
896

  
897
void OPPROTO op_lduw_T1_A0(void)
898
{
899
    T1 = lduw((uint8_t *)A0);
900
}
901

  
902
void OPPROTO op_ldsw_T1_A0(void)
903
{
904
    T1 = ldsw((int8_t *)A0);
905
}
906

  
907
void OPPROTO op_ldl_T1_A0(void)
908
{
909
    T1 = ldl((uint8_t *)A0);
910
}
911

  
912
void OPPROTO op_stb_T0_A0(void)
913
{
914
    stb((uint8_t *)A0, T0);
915
}
916

  
917
void OPPROTO op_stw_T0_A0(void)
918
{
919
    stw((uint8_t *)A0, T0);
920
}
921

  
922
void OPPROTO op_stl_T0_A0(void)
923
{
924
    stl((uint8_t *)A0, T0);
925
}
926

  
927
/* flags */
928

  
929
void OPPROTO op_set_cc_op(void)
930
{
931
    CC_OP = PARAM1;
932
}
933

  
934
void OPPROTO op_movl_eflags_T0(void)
935
{
936
    CC_SRC = T0;
937
    DF = (T0 & DIRECTION_FLAG) ? -1 : 1;
938
}
939

  
940
void OPPROTO op_movb_eflags_T0(void)
941
{
942
    int cc_o;
943
    cc_o = cc_table[CC_OP].compute_o();
944
    CC_SRC = T0 | (cc_o << 11);
945
}
946

  
947
void OPPROTO op_movl_T0_eflags(void)
948
{
949
    cc_table[CC_OP].compute_eflags();
950
}
951

  
952
void OPPROTO op_cld(void)
953
{
954
    DF = 1;
955
}
956

  
957
void OPPROTO op_std(void)
958
{
959
    DF = -1;
960
}
961

  
962
/* jumps */
963

  
964
/* indirect jump */
965
void OPPROTO op_jmp_T0(void)
966
{
967
    PC = T0;
968
}
969

  
970
void OPPROTO op_jmp_im(void)
971
{
972
    PC = PARAM1;
973
}
974

  
975
void OPPROTO op_jne_b(void)
976
{
977
    if ((uint8_t)CC_DST != 0)
978
        PC += PARAM1;
979
    else
980
        PC += PARAM2;
981
    FORCE_RET();
982
}
983

  
984
void OPPROTO op_jne_w(void)
985
{
986
    if ((uint16_t)CC_DST != 0)
987
        PC += PARAM1;
988
    else
989
        PC += PARAM2;
990
    FORCE_RET();
991
}
992

  
993
void OPPROTO op_jne_l(void)
994
{
995
    if (CC_DST != 0)
996
        PC += PARAM1;
997
    else
998
        PC += PARAM2;
999
    FORCE_RET(); /* generate a return so that gcc does not generate an
1000
                    early function return */
1001
}
1002

  
1003
/* string ops */
1004

  
1005
#define ldul ldl
1006

  
1007
#define SUFFIX b
1008
#define SHIFT 0
1009
#include "opstring_template.h"
1010
#undef SUFFIX
1011
#undef SHIFT
1012

  
1013
#define SUFFIX w
1014
#define SHIFT 1
1015
#include "opstring_template.h"
1016
#undef SUFFIX
1017
#undef SHIFT
1018

  
1019
#define SUFFIX l
1020
#define SHIFT 2
1021
#include "opstring_template.h"
1022
#undef SUFFIX
1023
#undef SHIFT
1024

  
1025
/* sign extend */
1026

  
1027
void OPPROTO op_movsbl_T0_T0(void)
1028
{
1029
    T0 = (int8_t)T0;
1030
}
1031

  
1032
void OPPROTO op_movzbl_T0_T0(void)
1033
{
1034
    T0 = (uint8_t)T0;
1035
}
1036

  
1037
void OPPROTO op_movswl_T0_T0(void)
1038
{
1039
    T0 = (int16_t)T0;
1040
}
1041

  
1042
void OPPROTO op_movzwl_T0_T0(void)
1043
{
1044
    T0 = (uint16_t)T0;
1045
}
1046

  
1047
void OPPROTO op_movswl_EAX_AX(void)
1048
{
1049
    EAX = (int16_t)EAX;
1050
}
1051

  
1052
void OPPROTO op_movsbw_AX_AL(void)
1053
{
1054
    EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
1055
}
1056

  
1057
void OPPROTO op_movslq_EDX_EAX(void)
1058
{
1059
    EDX = (int32_t)EAX >> 31;
1060
}
1061

  
1062
void OPPROTO op_movswl_DX_AX(void)
1063
{
1064
    EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
1065
}
1066

  
1067
/* push/pop */
1068
/* XXX: add 16 bit operand/16 bit seg variants */
1069

  
1070
void op_pushl_T0(void)
1071
{
1072
    uint32_t offset;
1073
    offset = ESP - 4;
1074
    stl((void *)offset, T0);
1075
    /* modify ESP after to handle exceptions correctly */
1076
    ESP = offset;
1077
}
1078

  
1079
void op_pushl_T1(void)
1080
{
1081
    uint32_t offset;
1082
    offset = ESP - 4;
1083
    stl((void *)offset, T1);
1084
    /* modify ESP after to handle exceptions correctly */
1085
    ESP = offset;
1086
}
1087

  
1088
void op_popl_T0(void)
1089
{
1090
    T0 = ldl((void *)ESP);
1091
    ESP += 4;
1092
}
1093

  
1094
void op_addl_ESP_im(void)
1095
{
1096
    ESP += PARAM1;
1097
}
b/opreg_template.h
1
/* templates for various register related operations */
2

  
3
void OPPROTO glue(op_movl_A0,REGNAME)(void)
4
{
5
    A0 = REG;
6
}
7

  
8
void OPPROTO glue(op_addl_A0,REGNAME)(void)
9
{
10
    A0 += REG;
11
}
12

  
13
void OPPROTO glue(glue(op_addl_A0,REGNAME),_s1)(void)
14
{
15
    A0 += REG << 1;
16
}
17

  
18
void OPPROTO glue(glue(op_addl_A0,REGNAME),_s2)(void)
19
{
20
    A0 += REG << 2;
21
}
22

  
23
void OPPROTO glue(glue(op_addl_A0,REGNAME),_s3)(void)
24
{
25
    A0 += REG << 3;
26
}
27

  
28
void OPPROTO glue(op_movl_T0,REGNAME)(void)
29
{
30
    T0 = REG;
31
}
32

  
33
void OPPROTO glue(op_movl_T1,REGNAME)(void)
34
{
35
    T1 = REG;
36
}
37

  
38
void OPPROTO glue(op_movh_T0,REGNAME)(void)
39
{
40
    T0 = REG >> 8;
41
}
42

  
43
void OPPROTO glue(op_movh_T1,REGNAME)(void)
44
{
45
    T1 = REG >> 8;
46
}
47

  
48
void OPPROTO glue(glue(op_movl,REGNAME),_T0)(void)
49
{
50
    REG = T0;
51
}
52

  
53
void OPPROTO glue(glue(op_movl,REGNAME),_T1)(void)
54
{
55
    REG = T1;
56
}
57

  
58
void OPPROTO glue(glue(op_movl,REGNAME),_A0)(void)
59
{
60
    REG = A0;
61
}
62

  
63
/* NOTE: T0 high order bits are ignored */
64
void OPPROTO glue(glue(op_movw,REGNAME),_T0)(void)
65
{
66
    REG = (REG & 0xffff0000) | (T0 & 0xffff);
67
}
68

  
69
/* NOTE: T0 high order bits are ignored */
70
void OPPROTO glue(glue(op_movw,REGNAME),_T1)(void)
71
{
72
    REG = (REG & 0xffff0000) | (T1 & 0xffff);
73
}
74

  
75
/* NOTE: A0 high order bits are ignored */
76
void OPPROTO glue(glue(op_movw,REGNAME),_A0)(void)
77
{
78
    REG = (REG & 0xffff0000) | (A0 & 0xffff);
79
}
80

  
81
/* NOTE: T0 high order bits are ignored */
82
void OPPROTO glue(glue(op_movb,REGNAME),_T0)(void)
83
{
84
    REG = (REG & 0xffffff00) | (T0 & 0xff);
85
}
86

  
87
/* NOTE: T0 high order bits are ignored */
88
void OPPROTO glue(glue(op_movh,REGNAME),_T0)(void)
89
{
90
    REG = (REG & 0xffff00ff) | ((T0 & 0xff) << 8);
91
}
92

  
93
/* NOTE: T1 high order bits are ignored */
94
void OPPROTO glue(glue(op_movb,REGNAME),_T1)(void)
95
{
96
    REG = (REG & 0xffffff00) | (T1 & 0xff);
97
}
98

  
99
/* NOTE: T1 high order bits are ignored */
100
void OPPROTO glue(glue(op_movh,REGNAME),_T1)(void)
101
{
102
    REG = (REG & 0xffff00ff) | ((T1 & 0xff) << 8);
103
}

Also available in: Unified diff