Commit 7bfdb6d18c7bb5792c896a0bf6cf1ad7431630cb

Authored by bellard
1 parent 379ca80d

new i386 emulator core


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@13 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 1200 additions and 0 deletions
op-i386.c 0 → 100644
  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 +}
... ...
opreg_template.h 0 → 100644
  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 +}
... ...