comparison gen_x86.c @ 61:918468c623e9

Add support for BTST instruction (untested), absolute addressing mode for instructions other than move (untested) and fix decoding of MOVEM.
author Mike Pavone <pavone@retrodev.com>
date Wed, 19 Dec 2012 20:23:59 -0800
parents 937b47c9b79b
children f80fa1776507
comparison
equal deleted inserted replaced
60:6ffea8607730 61:918468c623e9
38 #define OP_JMP_BYTE 0xEB 38 #define OP_JMP_BYTE 0xEB
39 #define OP_CALL_EA 0xFF 39 #define OP_CALL_EA 0xFF
40 40
41 #define OP2_JCC 0x80 41 #define OP2_JCC 0x80
42 #define OP2_SETCC 0x90 42 #define OP2_SETCC 0x90
43 #define OP2_BT 0xA3
44 #define OP2_BTX_I 0xBA
43 45
44 #define OP_EX_ADDI 0x0 46 #define OP_EX_ADDI 0x0
45 #define OP_EX_ORI 0x1 47 #define OP_EX_ORI 0x1
46 #define OP_EX_ADCI 0x2 48 #define OP_EX_ADCI 0x2
47 #define OP_EX_SBBI 0x3 49 #define OP_EX_SBBI 0x3
56 #define OP_EX_RCR 0x3 58 #define OP_EX_RCR 0x3
57 #define OP_EX_SHL 0x4 59 #define OP_EX_SHL 0x4
58 #define OP_EX_SHR 0x5 60 #define OP_EX_SHR 0x5
59 #define OP_EX_SAL 0x6 //identical to SHL 61 #define OP_EX_SAL 0x6 //identical to SHL
60 #define OP_EX_SAR 0x7 62 #define OP_EX_SAR 0x7
63
64 #define OP_EX_BT 0x4
65 #define OP_EX_BTS 0x5
66 #define OP_EX_BTR 0x6
67 #define OP_EX_BTC 0x7
61 68
62 #define BIT_IMMED_RAX 0x4 69 #define BIT_IMMED_RAX 0x4
63 #define BIT_DIR 0x2 70 #define BIT_DIR 0x2
64 #define BIT_SIZE 0x1 71 #define BIT_SIZE 0x1
65 72
878 *(out++) = OP2_SETCC | cc; 885 *(out++) = OP2_SETCC | cc;
879 *(out++) = MODE_REG_INDIRECT | dst; 886 *(out++) = MODE_REG_INDIRECT | dst;
880 return out; 887 return out;
881 } 888 }
882 889
890 uint8_t * bt_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size)
891 {
892 if (size == SZ_W) {
893 *(out++) = PRE_SIZE;
894 }
895 if (size == SZ_Q || src >= R8 || dst >= R8) {
896 *out = PRE_REX;
897 if (size == SZ_Q) {
898 *out |= REX_QUAD;
899 }
900 if (src >= R8) {
901 *out |= REX_REG_FIELD;
902 src -= (R8 - X86_R8);
903 }
904 if (dst >= R8) {
905 *out |= REX_RM_FIELD;
906 dst -= (R8 - X86_R8);
907 }
908 out++;
909 }
910 *(out++) = PRE_2BYTE;
911 *(out++) = OP2_BT;
912 *(out++) = MODE_REG_DIRECT | dst | (src << 3);
913 return out;
914 }
915
916 uint8_t * bt_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size)
917 {
918 if (size == SZ_W) {
919 *(out++) = PRE_SIZE;
920 }
921 if (size == SZ_Q || src >= R8 || dst_base >= R8) {
922 *out = PRE_REX;
923 if (size == SZ_Q) {
924 *out |= REX_QUAD;
925 }
926 if (src >= R8) {
927 *out |= REX_REG_FIELD;
928 src -= (R8 - X86_R8);
929 }
930 if (dst_base >= R8) {
931 *out |= REX_RM_FIELD;
932 dst_base -= (R8 - X86_R8);
933 }
934 out++;
935 }
936 *(out++) = PRE_2BYTE;
937 *(out++) = OP2_BT;
938 *(out++) = MODE_REG_DISPLACE8 | dst_base | (src << 3);
939 *(out++) = dst_disp;
940 return out;
941 }
942
943 uint8_t * bt_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size)
944 {
945 if (size == SZ_W) {
946 *(out++) = PRE_SIZE;
947 }
948 if (size == SZ_Q || dst >= R8) {
949 *out = PRE_REX;
950 if (size == SZ_Q) {
951 *out |= REX_QUAD;
952 }
953 if (dst >= R8) {
954 *out |= REX_RM_FIELD;
955 dst -= (R8 - X86_R8);
956 }
957 out++;
958 }
959 *(out++) = PRE_2BYTE;
960 *(out++) = OP2_BTX_I;
961 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_BT << 3);
962 *(out++) = val;
963 return out;
964 }
965
966 uint8_t * bt_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size)
967 {
968 if (size == SZ_W) {
969 *(out++) = PRE_SIZE;
970 }
971 if (size == SZ_Q || dst_base >= R8) {
972 *out = PRE_REX;
973 if (size == SZ_Q) {
974 *out |= REX_QUAD;
975 }
976 if (dst_base >= R8) {
977 *out |= REX_RM_FIELD;
978 dst_base -= (R8 - X86_R8);
979 }
980 out++;
981 }
982 *(out++) = PRE_2BYTE;
983 *(out++) = OP2_BTX_I;
984 *(out++) = MODE_REG_DISPLACE8 | dst_base | (OP_EX_BT << 3);
985 *(out++) = dst_disp;
986 *(out++) = val;
987 return out;
988 }
989
883 uint8_t * jcc(uint8_t * out, uint8_t cc, uint8_t * dest) 990 uint8_t * jcc(uint8_t * out, uint8_t cc, uint8_t * dest)
884 { 991 {
885 ptrdiff_t disp = dest-(out+2); 992 ptrdiff_t disp = dest-(out+2);
886 if (disp <= 0x7F && disp >= -0x80) { 993 if (disp <= 0x7F && disp >= -0x80) {
887 *(out++) = OP_JCC | cc; 994 *(out++) = OP_JCC | cc;