Commit cad3a37d3ef861a3a84b57b630b5ad1ed204ad5f
1 parent
b6abf97d
converted adc, sbb, cmpxchg to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4471 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
151 additions
and
305 deletions
target-i386/ops_template.h
... | ... | @@ -415,20 +415,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void) |
415 | 415 | T0 = ((DATA_STYPE)src1 <= (DATA_STYPE)src2); |
416 | 416 | } |
417 | 417 | |
418 | -#undef MEM_WRITE | |
419 | -#include "ops_template_mem.h" | |
420 | - | |
421 | -#define MEM_WRITE 0 | |
422 | -#include "ops_template_mem.h" | |
423 | - | |
424 | -#if !defined(CONFIG_USER_ONLY) | |
425 | -#define MEM_WRITE 1 | |
426 | -#include "ops_template_mem.h" | |
427 | - | |
428 | -#define MEM_WRITE 2 | |
429 | -#include "ops_template_mem.h" | |
430 | -#endif | |
431 | - | |
432 | 418 | /* bit operations */ |
433 | 419 | #if DATA_BITS >= 16 |
434 | 420 | ... | ... |
target-i386/ops_template_mem.h deleted
100644 → 0
1 | -/* | |
2 | - * i386 micro operations (included several times to generate | |
3 | - * different operand sizes) | |
4 | - * | |
5 | - * Copyright (c) 2003 Fabrice Bellard | |
6 | - * | |
7 | - * This library is free software; you can redistribute it and/or | |
8 | - * modify it under the terms of the GNU Lesser General Public | |
9 | - * License as published by the Free Software Foundation; either | |
10 | - * version 2 of the License, or (at your option) any later version. | |
11 | - * | |
12 | - * This library is distributed in the hope that it will be useful, | |
13 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | - * Lesser General Public License for more details. | |
16 | - * | |
17 | - * You should have received a copy of the GNU Lesser General Public | |
18 | - * License along with this library; if not, write to the Free Software | |
19 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | - */ | |
21 | -#ifdef MEM_WRITE | |
22 | - | |
23 | -#if MEM_WRITE == 0 | |
24 | - | |
25 | -#if DATA_BITS == 8 | |
26 | -#define MEM_SUFFIX b_raw | |
27 | -#elif DATA_BITS == 16 | |
28 | -#define MEM_SUFFIX w_raw | |
29 | -#elif DATA_BITS == 32 | |
30 | -#define MEM_SUFFIX l_raw | |
31 | -#elif DATA_BITS == 64 | |
32 | -#define MEM_SUFFIX q_raw | |
33 | -#endif | |
34 | - | |
35 | -#elif MEM_WRITE == 1 | |
36 | - | |
37 | -#if DATA_BITS == 8 | |
38 | -#define MEM_SUFFIX b_kernel | |
39 | -#elif DATA_BITS == 16 | |
40 | -#define MEM_SUFFIX w_kernel | |
41 | -#elif DATA_BITS == 32 | |
42 | -#define MEM_SUFFIX l_kernel | |
43 | -#elif DATA_BITS == 64 | |
44 | -#define MEM_SUFFIX q_kernel | |
45 | -#endif | |
46 | - | |
47 | -#elif MEM_WRITE == 2 | |
48 | - | |
49 | -#if DATA_BITS == 8 | |
50 | -#define MEM_SUFFIX b_user | |
51 | -#elif DATA_BITS == 16 | |
52 | -#define MEM_SUFFIX w_user | |
53 | -#elif DATA_BITS == 32 | |
54 | -#define MEM_SUFFIX l_user | |
55 | -#elif DATA_BITS == 64 | |
56 | -#define MEM_SUFFIX q_user | |
57 | -#endif | |
58 | - | |
59 | -#else | |
60 | - | |
61 | -#error invalid MEM_WRITE | |
62 | - | |
63 | -#endif | |
64 | - | |
65 | -#else | |
66 | - | |
67 | -#define MEM_SUFFIX SUFFIX | |
68 | - | |
69 | -#endif | |
70 | - | |
71 | -/* carry add/sub (we only need to set CC_OP differently) */ | |
72 | - | |
73 | -void OPPROTO glue(glue(op_adc, MEM_SUFFIX), _T0_T1_cc)(void) | |
74 | -{ | |
75 | - int cf; | |
76 | - cf = cc_table[CC_OP].compute_c(); | |
77 | - T0 = T0 + T1 + cf; | |
78 | -#ifdef MEM_WRITE | |
79 | - glue(st, MEM_SUFFIX)(A0, T0); | |
80 | -#endif | |
81 | - CC_SRC = T1; | |
82 | - CC_DST = T0; | |
83 | - CC_OP = CC_OP_ADDB + SHIFT + cf * 4; | |
84 | -} | |
85 | - | |
86 | -void OPPROTO glue(glue(op_sbb, MEM_SUFFIX), _T0_T1_cc)(void) | |
87 | -{ | |
88 | - int cf; | |
89 | - cf = cc_table[CC_OP].compute_c(); | |
90 | - T0 = T0 - T1 - cf; | |
91 | -#ifdef MEM_WRITE | |
92 | - glue(st, MEM_SUFFIX)(A0, T0); | |
93 | -#endif | |
94 | - CC_SRC = T1; | |
95 | - CC_DST = T0; | |
96 | - CC_OP = CC_OP_SUBB + SHIFT + cf * 4; | |
97 | -} | |
98 | - | |
99 | -void OPPROTO glue(glue(op_cmpxchg, MEM_SUFFIX), _T0_T1_EAX_cc)(void) | |
100 | -{ | |
101 | - target_ulong src, dst; | |
102 | - | |
103 | - src = T0; | |
104 | - dst = EAX - T0; | |
105 | - if ((DATA_TYPE)dst == 0) { | |
106 | - T0 = T1; | |
107 | -#ifdef MEM_WRITE | |
108 | - glue(st, MEM_SUFFIX)(A0, T0); | |
109 | -#endif | |
110 | - } else { | |
111 | - EAX = (EAX & ~DATA_MASK) | (T0 & DATA_MASK); | |
112 | - } | |
113 | - CC_SRC = src; | |
114 | - CC_DST = dst; | |
115 | - FORCE_RET(); | |
116 | -} | |
117 | - | |
118 | -#undef MEM_SUFFIX | |
119 | -#undef MEM_WRITE |
target-i386/translate.c
... | ... | @@ -498,65 +498,6 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = { |
498 | 498 | #endif |
499 | 499 | }; |
500 | 500 | |
501 | -#define DEF_ARITHC(SUFFIX)\ | |
502 | - {\ | |
503 | - gen_op_adcb ## SUFFIX ## _T0_T1_cc,\ | |
504 | - gen_op_sbbb ## SUFFIX ## _T0_T1_cc,\ | |
505 | - },\ | |
506 | - {\ | |
507 | - gen_op_adcw ## SUFFIX ## _T0_T1_cc,\ | |
508 | - gen_op_sbbw ## SUFFIX ## _T0_T1_cc,\ | |
509 | - },\ | |
510 | - {\ | |
511 | - gen_op_adcl ## SUFFIX ## _T0_T1_cc,\ | |
512 | - gen_op_sbbl ## SUFFIX ## _T0_T1_cc,\ | |
513 | - },\ | |
514 | - {\ | |
515 | - X86_64_ONLY(gen_op_adcq ## SUFFIX ## _T0_T1_cc),\ | |
516 | - X86_64_ONLY(gen_op_sbbq ## SUFFIX ## _T0_T1_cc),\ | |
517 | - }, | |
518 | - | |
519 | -static GenOpFunc *gen_op_arithc_T0_T1_cc[4][2] = { | |
520 | - DEF_ARITHC( ) | |
521 | -}; | |
522 | - | |
523 | -static GenOpFunc *gen_op_arithc_mem_T0_T1_cc[3 * 4][2] = { | |
524 | - DEF_ARITHC(_raw) | |
525 | -#ifndef CONFIG_USER_ONLY | |
526 | - DEF_ARITHC(_kernel) | |
527 | - DEF_ARITHC(_user) | |
528 | -#endif | |
529 | -}; | |
530 | - | |
531 | -static const int cc_op_arithb[8] = { | |
532 | - CC_OP_ADDB, | |
533 | - CC_OP_LOGICB, | |
534 | - CC_OP_ADDB, | |
535 | - CC_OP_SUBB, | |
536 | - CC_OP_LOGICB, | |
537 | - CC_OP_SUBB, | |
538 | - CC_OP_LOGICB, | |
539 | - CC_OP_SUBB, | |
540 | -}; | |
541 | - | |
542 | -#define DEF_CMPXCHG(SUFFIX)\ | |
543 | - gen_op_cmpxchgb ## SUFFIX ## _T0_T1_EAX_cc,\ | |
544 | - gen_op_cmpxchgw ## SUFFIX ## _T0_T1_EAX_cc,\ | |
545 | - gen_op_cmpxchgl ## SUFFIX ## _T0_T1_EAX_cc,\ | |
546 | - X86_64_ONLY(gen_op_cmpxchgq ## SUFFIX ## _T0_T1_EAX_cc), | |
547 | - | |
548 | -static GenOpFunc *gen_op_cmpxchg_T0_T1_EAX_cc[4] = { | |
549 | - DEF_CMPXCHG( ) | |
550 | -}; | |
551 | - | |
552 | -static GenOpFunc *gen_op_cmpxchg_mem_T0_T1_EAX_cc[3 * 4] = { | |
553 | - DEF_CMPXCHG(_raw) | |
554 | -#ifndef CONFIG_USER_ONLY | |
555 | - DEF_CMPXCHG(_kernel) | |
556 | - DEF_CMPXCHG(_user) | |
557 | -#endif | |
558 | -}; | |
559 | - | |
560 | 501 | static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = { |
561 | 502 | [0] = { |
562 | 503 | gen_op_btw_T0_T1_cc, |
... | ... | @@ -1257,11 +1198,53 @@ static void *helper_fp_arith_STN_ST0[8] = { |
1257 | 1198 | helper_fdiv_STN_ST0, |
1258 | 1199 | }; |
1259 | 1200 | |
1201 | +/* compute eflags.C to reg */ | |
1202 | +static void gen_compute_eflags_c(TCGv reg) | |
1203 | +{ | |
1204 | +#if TCG_TARGET_REG_BITS == 32 | |
1205 | + tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3); | |
1206 | + tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, | |
1207 | + (long)cc_table + offsetof(CCTable, compute_c)); | |
1208 | + tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0); | |
1209 | + tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, | |
1210 | + 1, &cpu_tmp2_i32, 0, NULL); | |
1211 | +#else | |
1212 | + tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op); | |
1213 | + tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4); | |
1214 | + tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, | |
1215 | + (long)cc_table + offsetof(CCTable, compute_c)); | |
1216 | + tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0); | |
1217 | + tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, | |
1218 | + 1, &cpu_tmp2_i32, 0, NULL); | |
1219 | +#endif | |
1220 | + tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32); | |
1221 | +} | |
1222 | + | |
1223 | +/* compute all eflags to cc_src */ | |
1224 | +static void gen_compute_eflags(TCGv reg) | |
1225 | +{ | |
1226 | +#if TCG_TARGET_REG_BITS == 32 | |
1227 | + tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3); | |
1228 | + tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, | |
1229 | + (long)cc_table + offsetof(CCTable, compute_all)); | |
1230 | + tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0); | |
1231 | + tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, | |
1232 | + 1, &cpu_tmp2_i32, 0, NULL); | |
1233 | +#else | |
1234 | + tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op); | |
1235 | + tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4); | |
1236 | + tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, | |
1237 | + (long)cc_table + offsetof(CCTable, compute_all)); | |
1238 | + tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0); | |
1239 | + tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, | |
1240 | + 1, &cpu_tmp2_i32, 0, NULL); | |
1241 | +#endif | |
1242 | + tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32); | |
1243 | +} | |
1244 | + | |
1260 | 1245 | /* if d == OR_TMP0, it means memory operand (address in A0) */ |
1261 | 1246 | static void gen_op(DisasContext *s1, int op, int ot, int d) |
1262 | 1247 | { |
1263 | - GenOpFunc *gen_update_cc; | |
1264 | - | |
1265 | 1248 | if (d != OR_TMP0) { |
1266 | 1249 | gen_op_mov_TN_reg(ot, 0, d); |
1267 | 1250 | } else { |
... | ... | @@ -1269,104 +1252,90 @@ static void gen_op(DisasContext *s1, int op, int ot, int d) |
1269 | 1252 | } |
1270 | 1253 | switch(op) { |
1271 | 1254 | case OP_ADCL: |
1255 | + if (s1->cc_op != CC_OP_DYNAMIC) | |
1256 | + gen_op_set_cc_op(s1->cc_op); | |
1257 | + gen_compute_eflags_c(cpu_tmp4); | |
1258 | + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
1259 | + tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp4); | |
1260 | + if (d != OR_TMP0) | |
1261 | + gen_op_mov_reg_T0(ot, d); | |
1262 | + else | |
1263 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1264 | + tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]); | |
1265 | + tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); | |
1266 | + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4); | |
1267 | + tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2); | |
1268 | + tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_ADDB + ot); | |
1269 | + s1->cc_op = CC_OP_DYNAMIC; | |
1270 | + break; | |
1272 | 1271 | case OP_SBBL: |
1273 | 1272 | if (s1->cc_op != CC_OP_DYNAMIC) |
1274 | 1273 | gen_op_set_cc_op(s1->cc_op); |
1275 | - if (d != OR_TMP0) { | |
1276 | - gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL](); | |
1274 | + gen_compute_eflags_c(cpu_tmp4); | |
1275 | + tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
1276 | + tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp4); | |
1277 | + if (d != OR_TMP0) | |
1277 | 1278 | gen_op_mov_reg_T0(ot, d); |
1278 | - } else { | |
1279 | - gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL](); | |
1280 | - } | |
1279 | + else | |
1280 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1281 | + tcg_gen_mov_tl(cpu_cc_src, cpu_T[1]); | |
1282 | + tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]); | |
1283 | + tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_tmp4); | |
1284 | + tcg_gen_shli_i32(cpu_tmp2_i32, cpu_tmp2_i32, 2); | |
1285 | + tcg_gen_addi_i32(cpu_cc_op, cpu_tmp2_i32, CC_OP_SUBB + ot); | |
1281 | 1286 | s1->cc_op = CC_OP_DYNAMIC; |
1282 | - goto the_end; | |
1287 | + break; | |
1283 | 1288 | case OP_ADDL: |
1284 | 1289 | gen_op_addl_T0_T1(); |
1290 | + if (d != OR_TMP0) | |
1291 | + gen_op_mov_reg_T0(ot, d); | |
1292 | + else | |
1293 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1294 | + gen_op_update2_cc(); | |
1285 | 1295 | s1->cc_op = CC_OP_ADDB + ot; |
1286 | - gen_update_cc = gen_op_update2_cc; | |
1287 | 1296 | break; |
1288 | 1297 | case OP_SUBL: |
1289 | 1298 | tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1299 | + if (d != OR_TMP0) | |
1300 | + gen_op_mov_reg_T0(ot, d); | |
1301 | + else | |
1302 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1303 | + gen_op_update2_cc(); | |
1290 | 1304 | s1->cc_op = CC_OP_SUBB + ot; |
1291 | - gen_update_cc = gen_op_update2_cc; | |
1292 | 1305 | break; |
1293 | 1306 | default: |
1294 | 1307 | case OP_ANDL: |
1295 | 1308 | tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1309 | + if (d != OR_TMP0) | |
1310 | + gen_op_mov_reg_T0(ot, d); | |
1311 | + else | |
1312 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1313 | + gen_op_update1_cc(); | |
1296 | 1314 | s1->cc_op = CC_OP_LOGICB + ot; |
1297 | - gen_update_cc = gen_op_update1_cc; | |
1298 | 1315 | break; |
1299 | 1316 | case OP_ORL: |
1300 | 1317 | tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1318 | + if (d != OR_TMP0) | |
1319 | + gen_op_mov_reg_T0(ot, d); | |
1320 | + else | |
1321 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1322 | + gen_op_update1_cc(); | |
1301 | 1323 | s1->cc_op = CC_OP_LOGICB + ot; |
1302 | - gen_update_cc = gen_op_update1_cc; | |
1303 | 1324 | break; |
1304 | 1325 | case OP_XORL: |
1305 | 1326 | tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1327 | + if (d != OR_TMP0) | |
1328 | + gen_op_mov_reg_T0(ot, d); | |
1329 | + else | |
1330 | + gen_op_st_T0_A0(ot + s1->mem_index); | |
1331 | + gen_op_update1_cc(); | |
1306 | 1332 | s1->cc_op = CC_OP_LOGICB + ot; |
1307 | - gen_update_cc = gen_op_update1_cc; | |
1308 | 1333 | break; |
1309 | 1334 | case OP_CMPL: |
1310 | 1335 | gen_op_cmpl_T0_T1_cc(); |
1311 | 1336 | s1->cc_op = CC_OP_SUBB + ot; |
1312 | - gen_update_cc = NULL; | |
1313 | 1337 | break; |
1314 | 1338 | } |
1315 | - if (op != OP_CMPL) { | |
1316 | - if (d != OR_TMP0) | |
1317 | - gen_op_mov_reg_T0(ot, d); | |
1318 | - else | |
1319 | - gen_op_st_T0_A0(ot + s1->mem_index); | |
1320 | - } | |
1321 | - /* the flags update must happen after the memory write (precise | |
1322 | - exception support) */ | |
1323 | - if (gen_update_cc) | |
1324 | - gen_update_cc(); | |
1325 | - the_end: ; | |
1326 | -} | |
1327 | - | |
1328 | -/* compute eflags.C to reg */ | |
1329 | -static void gen_compute_eflags_c(TCGv reg) | |
1330 | -{ | |
1331 | -#if TCG_TARGET_REG_BITS == 32 | |
1332 | - tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3); | |
1333 | - tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, | |
1334 | - (long)cc_table + offsetof(CCTable, compute_c)); | |
1335 | - tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0); | |
1336 | - tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, | |
1337 | - 1, ®, 0, NULL); | |
1338 | -#else | |
1339 | - tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op); | |
1340 | - tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4); | |
1341 | - tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, | |
1342 | - (long)cc_table + offsetof(CCTable, compute_c)); | |
1343 | - tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0); | |
1344 | - tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, | |
1345 | - 1, &cpu_tmp2_i32, 0, NULL); | |
1346 | - tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32); | |
1347 | -#endif | |
1348 | -} | |
1349 | - | |
1350 | -/* compute all eflags to cc_src */ | |
1351 | -static void gen_compute_eflags(TCGv reg) | |
1352 | -{ | |
1353 | -#if TCG_TARGET_REG_BITS == 32 | |
1354 | - tcg_gen_shli_i32(cpu_tmp2_i32, cpu_cc_op, 3); | |
1355 | - tcg_gen_addi_i32(cpu_tmp2_i32, cpu_tmp2_i32, | |
1356 | - (long)cc_table + offsetof(CCTable, compute_all)); | |
1357 | - tcg_gen_ld_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0); | |
1358 | - tcg_gen_call(&tcg_ctx, cpu_tmp2_i32, TCG_CALL_PURE, | |
1359 | - 1, ®, 0, NULL); | |
1360 | -#else | |
1361 | - tcg_gen_extu_i32_tl(cpu_tmp1_i64, cpu_cc_op); | |
1362 | - tcg_gen_shli_i64(cpu_tmp1_i64, cpu_tmp1_i64, 4); | |
1363 | - tcg_gen_addi_i64(cpu_tmp1_i64, cpu_tmp1_i64, | |
1364 | - (long)cc_table + offsetof(CCTable, compute_all)); | |
1365 | - tcg_gen_ld_i64(cpu_tmp1_i64, cpu_tmp1_i64, 0); | |
1366 | - tcg_gen_call(&tcg_ctx, cpu_tmp1_i64, TCG_CALL_PURE, | |
1367 | - 1, &cpu_tmp2_i32, 0, NULL); | |
1368 | - tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32); | |
1369 | -#endif | |
1370 | 1339 | } |
1371 | 1340 | |
1372 | 1341 | /* if d == OR_TMP0, it means memory operand (address in A0) */ |
... | ... | @@ -1393,6 +1362,23 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c) |
1393 | 1362 | gen_compute_eflags_c(cpu_cc_src); |
1394 | 1363 | } |
1395 | 1364 | |
1365 | +static void gen_extu(int ot, TCGv reg) | |
1366 | +{ | |
1367 | + switch(ot) { | |
1368 | + case OT_BYTE: | |
1369 | + tcg_gen_ext8u_tl(reg, reg); | |
1370 | + break; | |
1371 | + case OT_WORD: | |
1372 | + tcg_gen_ext16u_tl(reg, reg); | |
1373 | + break; | |
1374 | + case OT_LONG: | |
1375 | + tcg_gen_ext32u_tl(reg, reg); | |
1376 | + break; | |
1377 | + default: | |
1378 | + break; | |
1379 | + } | |
1380 | +} | |
1381 | + | |
1396 | 1382 | /* XXX: add faster immediate case */ |
1397 | 1383 | static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, |
1398 | 1384 | int is_right, int is_arith) |
... | ... | @@ -1433,19 +1419,7 @@ static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, |
1433 | 1419 | tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5); |
1434 | 1420 | tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1435 | 1421 | } else { |
1436 | - switch(ot) { | |
1437 | - case OT_BYTE: | |
1438 | - tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); | |
1439 | - break; | |
1440 | - case OT_WORD: | |
1441 | - tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); | |
1442 | - break; | |
1443 | - case OT_LONG: | |
1444 | - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); | |
1445 | - break; | |
1446 | - default: | |
1447 | - break; | |
1448 | - } | |
1422 | + gen_extu(ot, cpu_T[0]); | |
1449 | 1423 | tcg_gen_shr_tl(cpu_T3, cpu_T[0], cpu_tmp5); |
1450 | 1424 | tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]); |
1451 | 1425 | } |
... | ... | @@ -1516,19 +1490,7 @@ static void gen_rot_rm_T1(DisasContext *s, int ot, int op1, |
1516 | 1490 | else |
1517 | 1491 | tcg_gen_mov_tl(cpu_tmp0, cpu_T[1]); |
1518 | 1492 | |
1519 | - switch(ot) { | |
1520 | - case OT_BYTE: | |
1521 | - tcg_gen_ext8u_tl(cpu_T[0], cpu_T[0]); | |
1522 | - break; | |
1523 | - case OT_WORD: | |
1524 | - tcg_gen_ext16u_tl(cpu_T[0], cpu_T[0]); | |
1525 | - break; | |
1526 | - case OT_LONG: | |
1527 | - tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]); | |
1528 | - break; | |
1529 | - default: | |
1530 | - break; | |
1531 | - } | |
1493 | + gen_extu(ot, cpu_T[0]); | |
1532 | 1494 | tcg_gen_mov_tl(cpu_T3, cpu_T[0]); |
1533 | 1495 | |
1534 | 1496 | data_bits = 8 << ot; |
... | ... | @@ -4270,25 +4232,42 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) |
4270 | 4232 | break; |
4271 | 4233 | case 0x1b0: |
4272 | 4234 | case 0x1b1: /* cmpxchg Ev, Gv */ |
4273 | - if ((b & 1) == 0) | |
4274 | - ot = OT_BYTE; | |
4275 | - else | |
4276 | - ot = dflag + OT_WORD; | |
4277 | - modrm = ldub_code(s->pc++); | |
4278 | - reg = ((modrm >> 3) & 7) | rex_r; | |
4279 | - mod = (modrm >> 6) & 3; | |
4280 | - gen_op_mov_TN_reg(ot, 1, reg); | |
4281 | - if (mod == 3) { | |
4282 | - rm = (modrm & 7) | REX_B(s); | |
4283 | - gen_op_mov_TN_reg(ot, 0, rm); | |
4284 | - gen_op_cmpxchg_T0_T1_EAX_cc[ot](); | |
4285 | - gen_op_mov_reg_T0(ot, rm); | |
4286 | - } else { | |
4287 | - gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | |
4288 | - gen_op_ld_T0_A0(ot + s->mem_index); | |
4289 | - gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index](); | |
4235 | + { | |
4236 | + int label1; | |
4237 | + | |
4238 | + if ((b & 1) == 0) | |
4239 | + ot = OT_BYTE; | |
4240 | + else | |
4241 | + ot = dflag + OT_WORD; | |
4242 | + modrm = ldub_code(s->pc++); | |
4243 | + reg = ((modrm >> 3) & 7) | rex_r; | |
4244 | + mod = (modrm >> 6) & 3; | |
4245 | + gen_op_mov_TN_reg(ot, 1, reg); | |
4246 | + if (mod == 3) { | |
4247 | + rm = (modrm & 7) | REX_B(s); | |
4248 | + gen_op_mov_TN_reg(ot, 0, rm); | |
4249 | + } else { | |
4250 | + gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | |
4251 | + gen_op_ld_T0_A0(ot + s->mem_index); | |
4252 | + rm = 0; /* avoid warning */ | |
4253 | + } | |
4254 | + label1 = gen_new_label(); | |
4255 | + tcg_gen_ld_tl(cpu_T3, cpu_env, offsetof(CPUState, regs[R_EAX])); | |
4256 | + tcg_gen_sub_tl(cpu_T3, cpu_T3, cpu_T[0]); | |
4257 | + gen_extu(ot, cpu_T3); | |
4258 | + tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T3, tcg_const_tl(0), label1); | |
4259 | + tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); | |
4260 | + gen_op_mov_reg_T0(ot, R_EAX); | |
4261 | + gen_set_label(label1); | |
4262 | + if (mod == 3) { | |
4263 | + gen_op_mov_reg_T1(ot, rm); | |
4264 | + } else { | |
4265 | + gen_op_st_T1_A0(ot + s->mem_index); | |
4266 | + } | |
4267 | + tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]); | |
4268 | + tcg_gen_mov_tl(cpu_cc_dst, cpu_T3); | |
4269 | + s->cc_op = CC_OP_SUBB + ot; | |
4290 | 4270 | } |
4291 | - s->cc_op = CC_OP_SUBB + ot; | |
4292 | 4271 | break; |
4293 | 4272 | case 0x1c7: /* cmpxchg8b */ |
4294 | 4273 | modrm = ldub_code(s->pc++); | ... | ... |