Mercurial > repos > blastem
comparison gen_x86.c @ 484:0bf5e6b672fe
Add support for test instruction to x86 generator library
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 03 Oct 2013 21:20:29 -0700 |
parents | 140af5509ce7 |
children | 96489fb27dbf |
comparison
equal
deleted
inserted
replaced
483:3e1573fa22cf | 484:0bf5e6b672fe |
---|---|
1 /* | 1 /* |
2 Copyright 2013 Michael Pavone | 2 Copyright 2013 Michael Pavone |
3 This file is part of BlastEm. | 3 This file is part of BlastEm. |
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. | 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. |
5 */ | 5 */ |
6 #include "gen_x86.h" | 6 #include "gen_x86.h" |
7 #include "68kinst.h" | 7 #include "68kinst.h" |
8 #include <stddef.h> | 8 #include <stddef.h> |
28 #define OP_POP 0x58 | 28 #define OP_POP 0x58 |
29 #define OP_MOVSXD 0x63 | 29 #define OP_MOVSXD 0x63 |
30 #define PRE_SIZE 0x66 | 30 #define PRE_SIZE 0x66 |
31 #define OP_JCC 0x70 | 31 #define OP_JCC 0x70 |
32 #define OP_IMMED_ARITH 0x80 | 32 #define OP_IMMED_ARITH 0x80 |
33 #define OP_TEST 0x84 | |
33 #define OP_XCHG 0x86 | 34 #define OP_XCHG 0x86 |
34 #define OP_MOV 0x88 | 35 #define OP_MOV 0x88 |
35 #define OP_XCHG_AX 0x90 | 36 #define OP_XCHG_AX 0x90 |
36 #define OP_CDQ 0x99 | 37 #define OP_CDQ 0x99 |
37 #define OP_PUSHF 0x9C | 38 #define OP_PUSHF 0x9C |
428 } | 429 } |
429 | 430 |
430 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) | 431 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) |
431 { | 432 { |
432 uint8_t sign_extend = 0; | 433 uint8_t sign_extend = 0; |
433 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { | 434 if (opcode != OP_NOT_NEG && (size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { |
434 sign_extend = 1; | 435 sign_extend = 1; |
435 opcode |= BIT_DIR; | 436 opcode |= BIT_DIR; |
436 } | 437 } |
437 if (size == SZ_W) { | 438 if (size == SZ_W) { |
438 *(out++) = PRE_SIZE; | 439 *(out++) = PRE_SIZE; |
1021 uint8_t * cmp_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | 1022 uint8_t * cmp_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) |
1022 { | 1023 { |
1023 return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); | 1024 return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); |
1024 } | 1025 } |
1025 | 1026 |
1027 uint8_t * test_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | |
1028 { | |
1029 return x86_rr_sizedir(out, OP_TEST, src, dst, size); | |
1030 } | |
1031 | |
1032 uint8_t * test_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) | |
1033 { | |
1034 return x86_ir(out, OP_NOT_NEG, OP_EX_TEST_I, OP_TEST, val, dst, size); | |
1035 } | |
1036 | |
1037 uint8_t * test_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) | |
1038 { | |
1039 return x86_irdisp8(out, OP_NOT_NEG, OP_EX_TEST_I, val, dst_base, disp, size); | |
1040 } | |
1041 | |
1042 uint8_t * test_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) | |
1043 { | |
1044 return x86_rrdisp8_sizedir(out, OP_TEST, src, dst_base, disp, size, 0); | |
1045 } | |
1046 | |
1047 uint8_t * test_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) | |
1048 { | |
1049 return x86_rrdisp8_sizedir(out, OP_TEST, dst, src_base, disp, size, BIT_DIR); | |
1050 } | |
1051 | |
1026 uint8_t * imul_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) | 1052 uint8_t * imul_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) |
1027 { | 1053 { |
1028 return x86_rr_sizedir(out, OP2_IMUL | (PRE_2BYTE << 8), dst, src, size); | 1054 return x86_rr_sizedir(out, OP2_IMUL | (PRE_2BYTE << 8), dst, src, size); |
1029 } | 1055 } |
1030 | 1056 |
1137 { | 1163 { |
1138 return x86_rrindex_sizedir(out, OP_MOV, dst, src_base, src_index, scale, size, BIT_DIR); | 1164 return x86_rrindex_sizedir(out, OP_MOV, dst, src_base, src_index, scale, size, BIT_DIR); |
1139 } | 1165 } |
1140 | 1166 |
1141 uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size) | 1167 uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size) |
1142 { | 1168 { |
1143 uint8_t sign_extend = 0; | 1169 uint8_t sign_extend = 0; |
1144 if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) { | 1170 if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) { |
1145 sign_extend = 1; | 1171 sign_extend = 1; |
1146 } | 1172 } |
1147 if (size == SZ_W) { | 1173 if (size == SZ_W) { |