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) {