comparison gen_x86.c @ 81:6d231dbe75ab

Add support for indexed modes as a source, some work on jmp and jsr with areg indirect mode
author Mike Pavone <pavone@retrodev.com>
date Sat, 22 Dec 2012 21:37:25 -0800
parents f80fa1776507
children 6331ddec228f
comparison
equal deleted inserted replaced
80:7b1e16e981ef 81:6d231dbe75ab
18 #define OP_XOR 0x30 18 #define OP_XOR 0x30
19 #define OP_CMP 0x38 19 #define OP_CMP 0x38
20 #define PRE_REX 0x40 20 #define PRE_REX 0x40
21 #define OP_PUSH 0x50 21 #define OP_PUSH 0x50
22 #define OP_POP 0x58 22 #define OP_POP 0x58
23 #define OP_MOVSXD 0x63
23 #define PRE_SIZE 0x66 24 #define PRE_SIZE 0x66
24 #define OP_JCC 0x70 25 #define OP_JCC 0x70
25 #define OP_IMMED_ARITH 0x80 26 #define OP_IMMED_ARITH 0x80
26 #define OP_MOV 0x88 27 #define OP_MOV 0x88
27 #define OP_PUSHF 0x9C 28 #define OP_PUSHF 0x9C
34 #define OP_SHIFTROT_1 0xD0 35 #define OP_SHIFTROT_1 0xD0
35 #define OP_SHIFTROT_CL 0xD2 36 #define OP_SHIFTROT_CL 0xD2
36 #define OP_CALL 0xE8 37 #define OP_CALL 0xE8
37 #define OP_JMP 0xE9 38 #define OP_JMP 0xE9
38 #define OP_JMP_BYTE 0xEB 39 #define OP_JMP_BYTE 0xEB
39 #define OP_CALL_EA 0xFF 40 #define OP_SINGLE_EA 0xFF
40 41
41 #define OP2_JCC 0x80 42 #define OP2_JCC 0x80
42 #define OP2_SETCC 0x90 43 #define OP2_SETCC 0x90
43 #define OP2_BT 0xA3 44 #define OP2_BT 0xA3
44 #define OP2_BTX_I 0xBA 45 #define OP2_BTX_I 0xBA
46 #define OP2_MOVSX 0xBE
45 47
46 #define OP_EX_ADDI 0x0 48 #define OP_EX_ADDI 0x0
47 #define OP_EX_ORI 0x1 49 #define OP_EX_ORI 0x1
48 #define OP_EX_ADCI 0x2 50 #define OP_EX_ADCI 0x2
49 #define OP_EX_SBBI 0x3 51 #define OP_EX_SBBI 0x3
63 65
64 #define OP_EX_BT 0x4 66 #define OP_EX_BT 0x4
65 #define OP_EX_BTS 0x5 67 #define OP_EX_BTS 0x5
66 #define OP_EX_BTR 0x6 68 #define OP_EX_BTR 0x6
67 #define OP_EX_BTC 0x7 69 #define OP_EX_BTC 0x7
70
71 #define OP_EX_INC 0x0
72 #define OP_EX_DEC 0x1
73 #define OP_EX_CALL_EA 0x2
74 #define OP_EX_JMP_EA 0x4
75 #define OP_EX_PUSH_EA 0x6
68 76
69 #define BIT_IMMED_RAX 0x4 77 #define BIT_IMMED_RAX 0x4
70 #define BIT_DIR 0x2 78 #define BIT_DIR 0x2
71 #define BIT_SIZE 0x1 79 #define BIT_SIZE 0x1
72 80
861 } 869 }
862 } 870 }
863 return out; 871 return out;
864 } 872 }
865 873
874 uint8_t * movsx_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t src_size, uint8_t size)
875 {
876 if (size == SZ_W) {
877 *(out++) = PRE_SIZE;
878 }
879 if (size == SZ_Q || dst >= R8 || src >= R8) {
880 *out = PRE_REX;
881 if (size == SZ_Q) {
882 *out |= REX_QUAD;
883 }
884 if (src >= R8) {
885 *out |= REX_REG_FIELD;
886 src -= (R8 - X86_R8);
887 }
888 if (dst >= R8) {
889 *out |= REX_RM_FIELD;
890 dst -= (R8 - X86_R8);
891 }
892 out++;
893 }
894 if (src_size == SZ_D) {
895 *(out++) = OP_MOVSXD;
896 } else {
897 *(out++) = PRE_2BYTE;
898 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE);
899 }
900 *(out++) = MODE_REG_DIRECT | src | (dst << 3);
901 return out;
902 }
903
904 uint8_t * movsx_rdisp8r(uint8_t * out, uint8_t src, int8_t disp, uint8_t dst, uint8_t src_size, uint8_t size)
905 {
906 if (size == SZ_W) {
907 *(out++) = PRE_SIZE;
908 }
909 if (size == SZ_Q || dst >= R8 || src >= R8) {
910 *out = PRE_REX;
911 if (size == SZ_Q) {
912 *out |= REX_QUAD;
913 }
914 if (src >= R8) {
915 *out |= REX_REG_FIELD;
916 src -= (R8 - X86_R8);
917 }
918 if (dst >= R8) {
919 *out |= REX_RM_FIELD;
920 dst -= (R8 - X86_R8);
921 }
922 out++;
923 }
924 if (src_size == SZ_D) {
925 *(out++) = OP_MOVSXD;
926 } else {
927 *(out++) = PRE_2BYTE;
928 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE);
929 }
930 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3);
931 *(out++) = disp;
932 return out;
933 }
934
866 uint8_t * pushf(uint8_t * out) 935 uint8_t * pushf(uint8_t * out)
867 { 936 {
868 *(out++) = OP_PUSHF; 937 *(out++) = OP_PUSHF;
869 return out; 938 return out;
870 } 939 }
1072 } 1141 }
1073 } 1142 }
1074 return out; 1143 return out;
1075 } 1144 }
1076 1145
1146 uint8_t * jmp_r(uint8_t * out, uint8_t dst)
1147 {
1148 *(out++) = OP_SINGLE_EA;
1149 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_JMP_EA << 3);
1150 }
1151
1077 uint8_t * call(uint8_t * out, uint8_t * fun) 1152 uint8_t * call(uint8_t * out, uint8_t * fun)
1078 { 1153 {
1079 ptrdiff_t disp = fun-(out+5); 1154 ptrdiff_t disp = fun-(out+5);
1080 if (disp <= 0x7FFFFFFF && disp >= -2147483648) { 1155 if (disp <= 0x7FFFFFFF && disp >= -2147483648) {
1081 *(out++) = OP_CALL; 1156 *(out++) = OP_CALL;
1092 return NULL; 1167 return NULL;
1093 } 1168 }
1094 return out; 1169 return out;
1095 } 1170 }
1096 1171
1172 uint8_t * call_r(uint8_t * out, uint8_t dst)
1173 {
1174 *(out++) = OP_SINGLE_EA;
1175 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_CALL_EA << 3);
1176 }
1177
1097 uint8_t * retn(uint8_t * out) 1178 uint8_t * retn(uint8_t * out)
1098 { 1179 {
1099 *(out++) = OP_RETN; 1180 *(out++) = OP_RETN;
1100 return out; 1181 return out;
1101 } 1182 }