Mercurial > repos > blastem
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; |