VirtualBox

Changeset 39127 in vbox for trunk/src


Ignore:
Timestamp:
Oct 27, 2011 11:42:34 AM (13 years ago)
Author:
vboxsync
Message:

IEM: Adding GET_NEXT_U16_ZX_U32/64 and GET_NEXT_U32_ZX_U64.

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r39125 r39127  
    817817
    818818/**
    819  * Deals with the problematic cases that iemOpcodeGetNextByte doesn't like.
     819 * Deals with the problematic cases that iemOpcodeGetNextU8 doesn't like.
    820820 *
    821821 * @returns Strict VBox status code.
     
    823823 * @param   pb                  Where to return the opcode byte.
    824824 */
    825 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextByteSlow(PIEMCPU pIemCpu, uint8_t *pb)
     825DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU8Slow(PIEMCPU pIemCpu, uint8_t *pb)
    826826{
    827827    VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 1);
     
    839839
    840840/**
     841 * Fetches the next opcode byte.
     842 *
     843 * @returns Strict VBox status code.
     844 * @param   pIemCpu             The IEM state.
     845 * @param   pu8                 Where to return the opcode byte.
     846 */
     847DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8)
     848{
     849    uint8_t const offOpcode = pIemCpu->offOpcode;
     850    if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
     851        return iemOpcodeGetNextU8Slow(pIemCpu, pu8);
     852
     853    *pu8 = pIemCpu->abOpcode[offOpcode];
     854    pIemCpu->offOpcode = offOpcode + 1;
     855    return VINF_SUCCESS;
     856}
     857
     858
     859/**
     860 * Fetches the next opcode byte, returns automatically on failure.
     861 *
     862 * @param   a_pu8               Where to return the opcode byte.
     863 * @remark Implicitly references pIemCpu.
     864 */
     865#define IEM_OPCODE_GET_NEXT_U8(a_pu8) \
     866    do \
     867    { \
     868        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pIemCpu, (a_pu8)); \
     869        if (rcStrict2 != VINF_SUCCESS) \
     870            return rcStrict2; \
     871    } while (0)
     872
     873
     874/**
     875 * Fetches the next signed byte from the opcode stream.
     876 *
     877 * @returns Strict VBox status code.
     878 * @param   pIemCpu             The IEM state.
     879 * @param   pi8                 Where to return the signed byte.
     880 */
     881DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PIEMCPU pIemCpu, int8_t *pi8)
     882{
     883    return iemOpcodeGetNextU8(pIemCpu, (uint8_t *)pi8);
     884}
     885
     886
     887/**
     888 * Fetches the next signed byte from the opcode stream, returning automatically
     889 * on failure.
     890 *
     891 * @param   pi8                 Where to return the signed byte.
     892 * @remark Implicitly references pIemCpu.
     893 */
     894#define IEM_OPCODE_GET_NEXT_S8(a_pi8) \
     895    do \
     896    { \
     897        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pIemCpu, (a_pi8)); \
     898        if (rcStrict2 != VINF_SUCCESS) \
     899            return rcStrict2; \
     900    } while (0)
     901
     902
     903/**
    841904 * Deals with the problematic cases that iemOpcodeGetNextS8SxU16 doesn't like.
    842905 *
     
    847910DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS8SxU16Slow(PIEMCPU pIemCpu, uint16_t *pu16)
    848911{
    849     uint8_t     u8;
    850     VBOXSTRICTRC rcStrict = iemOpcodeGetNextByteSlow(pIemCpu, &u8);
     912    uint8_t      u8;
     913    VBOXSTRICTRC rcStrict = iemOpcodeGetNextU8Slow(pIemCpu, &u8);
    851914    if (rcStrict == VINF_SUCCESS)
    852915        *pu16 = (int8_t)u8;
     
    856919
    857920/**
     921 * Fetches the next signed byte from the opcode stream, extending it to
     922 * unsigned 16-bit.
     923 *
     924 * @returns Strict VBox status code.
     925 * @param   pIemCpu             The IEM state.
     926 * @param   pu16                Where to return the unsigned word.
     927 */
     928DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PIEMCPU pIemCpu, uint16_t *pu16)
     929{
     930    uint8_t const offOpcode = pIemCpu->offOpcode;
     931    if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
     932        return iemOpcodeGetNextS8SxU16Slow(pIemCpu, pu16);
     933
     934    *pu16 = (int8_t)pIemCpu->abOpcode[offOpcode];
     935    pIemCpu->offOpcode = offOpcode + 1;
     936    return VINF_SUCCESS;
     937}
     938
     939
     940/**
     941 * Fetches the next signed byte from the opcode stream and sign-extending it to
     942 * a word, returning automatically on failure.
     943 *
     944 * @param   pu16                Where to return the word.
     945 * @remark Implicitly references pIemCpu.
     946 */
     947#define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \
     948    do \
     949    { \
     950        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pIemCpu, (a_pu16)); \
     951        if (rcStrict2 != VINF_SUCCESS) \
     952            return rcStrict2; \
     953    } while (0)
     954
     955
     956/**
    858957 * Deals with the problematic cases that iemOpcodeGetNextU16 doesn't like.
    859958 *
     
    875974    return rcStrict;
    876975}
     976
     977
     978/**
     979 * Fetches the next opcode word.
     980 *
     981 * @returns Strict VBox status code.
     982 * @param   pIemCpu             The IEM state.
     983 * @param   pu16                Where to return the opcode word.
     984 */
     985DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PIEMCPU pIemCpu, uint16_t *pu16)
     986{
     987    uint8_t const offOpcode = pIemCpu->offOpcode;
     988    if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
     989        return iemOpcodeGetNextU16Slow(pIemCpu, pu16);
     990
     991    *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
     992    pIemCpu->offOpcode = offOpcode + 2;
     993    return VINF_SUCCESS;
     994}
     995
     996
     997/**
     998 * Fetches the next opcode word, returns automatically on failure.
     999 *
     1000 * @param   a_pu16              Where to return the opcode word.
     1001 * @remark Implicitly references pIemCpu.
     1002 */
     1003#define IEM_OPCODE_GET_NEXT_U16(a_pu16) \
     1004    do \
     1005    { \
     1006        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pIemCpu, (a_pu16)); \
     1007        if (rcStrict2 != VINF_SUCCESS) \
     1008            return rcStrict2; \
     1009    } while (0)
     1010
     1011
     1012/**
     1013 * Deals with the problematic cases that iemOpcodeGetNextU16ZxU32 doesn't like.
     1014 *
     1015 * @returns Strict VBox status code.
     1016 * @param   pIemCpu             The IEM state.
     1017 * @param   pu32                Where to return the opcode double word.
     1018 */
     1019DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32Slow(PIEMCPU pIemCpu, uint32_t *pu32)
     1020{
     1021    VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2);
     1022    if (rcStrict == VINF_SUCCESS)
     1023    {
     1024        uint8_t offOpcode = pIemCpu->offOpcode;
     1025        *pu32 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
     1026        pIemCpu->offOpcode = offOpcode + 2;
     1027    }
     1028    else
     1029        *pu32 = 0;
     1030    return rcStrict;
     1031}
     1032
     1033
     1034/**
     1035 * Fetches the next opcode word, zero extending it to a double word.
     1036 *
     1037 * @returns Strict VBox status code.
     1038 * @param   pIemCpu             The IEM state.
     1039 * @param   pu32                Where to return the opcode double word.
     1040 */
     1041DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32(PIEMCPU pIemCpu, uint32_t *pu32)
     1042{
     1043    uint8_t const offOpcode = pIemCpu->offOpcode;
     1044    if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
     1045        return iemOpcodeGetNextU16ZxU32Slow(pIemCpu, pu32);
     1046
     1047    *pu32 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
     1048    pIemCpu->offOpcode = offOpcode + 2;
     1049    return VINF_SUCCESS;
     1050}
     1051
     1052
     1053/**
     1054 * Fetches the next opcode word and zero extends it to a double word, returns
     1055 * automatically on failure.
     1056 *
     1057 * @param   a_pu32              Where to return the opcode double word.
     1058 * @remark Implicitly references pIemCpu.
     1059 */
     1060#define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) \
     1061    do \
     1062    { \
     1063        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU32(pIemCpu, (a_pu32)); \
     1064        if (rcStrict2 != VINF_SUCCESS) \
     1065            return rcStrict2; \
     1066    } while (0)
     1067
     1068
     1069/**
     1070 * Deals with the problematic cases that iemOpcodeGetNextU16ZxU64 doesn't like.
     1071 *
     1072 * @returns Strict VBox status code.
     1073 * @param   pIemCpu             The IEM state.
     1074 * @param   pu64                Where to return the opcode quad word.
     1075 */
     1076DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
     1077{
     1078    VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2);
     1079    if (rcStrict == VINF_SUCCESS)
     1080    {
     1081        uint8_t offOpcode = pIemCpu->offOpcode;
     1082        *pu64 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
     1083        pIemCpu->offOpcode = offOpcode + 2;
     1084    }
     1085    else
     1086        *pu64 = 0;
     1087    return rcStrict;
     1088}
     1089
     1090
     1091/**
     1092 * Fetches the next opcode word, zero extending it to a quad word.
     1093 *
     1094 * @returns Strict VBox status code.
     1095 * @param   pIemCpu             The IEM state.
     1096 * @param   pu64                Where to return the opcode quad word.
     1097 */
     1098DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64(PIEMCPU pIemCpu, uint64_t *pu64)
     1099{
     1100    uint8_t const offOpcode = pIemCpu->offOpcode;
     1101    if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
     1102        return iemOpcodeGetNextU16ZxU64Slow(pIemCpu, pu64);
     1103
     1104    *pu64 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
     1105    pIemCpu->offOpcode = offOpcode + 2;
     1106    return VINF_SUCCESS;
     1107}
     1108
     1109
     1110/**
     1111 * Fetches the next opcode word and zero extends it to a quad word, returns
     1112 * automatically on failure.
     1113 *
     1114 * @param   a_pu64              Where to return the opcode quad word.
     1115 * @remark Implicitly references pIemCpu.
     1116 */
     1117#define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64) \
     1118    do \
     1119    { \
     1120        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU64(pIemCpu, (a_pu64)); \
     1121        if (rcStrict2 != VINF_SUCCESS) \
     1122            return rcStrict2; \
     1123    } while (0)
     1124
     1125
     1126/**
     1127 * Fetches the next signed word from the opcode stream.
     1128 *
     1129 * @returns Strict VBox status code.
     1130 * @param   pIemCpu             The IEM state.
     1131 * @param   pi16                Where to return the signed word.
     1132 */
     1133DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PIEMCPU pIemCpu, int16_t *pi16)
     1134{
     1135    return iemOpcodeGetNextU16(pIemCpu, (uint16_t *)pi16);
     1136}
     1137
     1138
     1139/**
     1140 * Fetches the next signed word from the opcode stream, returning automatically
     1141 * on failure.
     1142 *
     1143 * @param   pi16                Where to return the signed word.
     1144 * @remark Implicitly references pIemCpu.
     1145 */
     1146#define IEM_OPCODE_GET_NEXT_S16(a_pi16) \
     1147    do \
     1148    { \
     1149        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pIemCpu, (a_pi16)); \
     1150        if (rcStrict2 != VINF_SUCCESS) \
     1151            return rcStrict2; \
     1152    } while (0)
    8771153
    8781154
     
    9031179
    9041180/**
     1181 * Fetches the next opcode dword.
     1182 *
     1183 * @returns Strict VBox status code.
     1184 * @param   pIemCpu             The IEM state.
     1185 * @param   pu32                Where to return the opcode double word.
     1186 */
     1187DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PIEMCPU pIemCpu, uint32_t *pu32)
     1188{
     1189    uint8_t const offOpcode = pIemCpu->offOpcode;
     1190    if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
     1191        return iemOpcodeGetNextU32Slow(pIemCpu, pu32);
     1192
     1193    *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
     1194                                pIemCpu->abOpcode[offOpcode + 1],
     1195                                pIemCpu->abOpcode[offOpcode + 2],
     1196                                pIemCpu->abOpcode[offOpcode + 3]);
     1197    pIemCpu->offOpcode = offOpcode + 4;
     1198    return VINF_SUCCESS;
     1199}
     1200
     1201
     1202/**
     1203 * Fetches the next opcode dword, returns automatically on failure.
     1204 *
     1205 * @param   a_pu32              Where to return the opcode dword.
     1206 * @remark Implicitly references pIemCpu.
     1207 */
     1208#define IEM_OPCODE_GET_NEXT_U32(a_pu32) \
     1209    do \
     1210    { \
     1211        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pIemCpu, (a_pu32)); \
     1212        if (rcStrict2 != VINF_SUCCESS) \
     1213            return rcStrict2; \
     1214    } while (0)
     1215
     1216
     1217/**
     1218 * Deals with the problematic cases that iemOpcodeGetNextU32ZxU64 doesn't like.
     1219 *
     1220 * @returns Strict VBox status code.
     1221 * @param   pIemCpu             The IEM state.
     1222 * @param   pu32                Where to return the opcode dword.
     1223 */
     1224DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64)
     1225{
     1226    VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4);
     1227    if (rcStrict == VINF_SUCCESS)
     1228    {
     1229        uint8_t offOpcode = pIemCpu->offOpcode;
     1230        *pu64 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
     1231                                    pIemCpu->abOpcode[offOpcode + 1],
     1232                                    pIemCpu->abOpcode[offOpcode + 2],
     1233                                    pIemCpu->abOpcode[offOpcode + 3]);
     1234        pIemCpu->offOpcode = offOpcode + 4;
     1235    }
     1236    else
     1237        *pu64 = 0;
     1238    return rcStrict;
     1239}
     1240
     1241
     1242/**
     1243 * Fetches the next opcode dword, zero extending it to a quad word.
     1244 *
     1245 * @returns Strict VBox status code.
     1246 * @param   pIemCpu             The IEM state.
     1247 * @param   pu64                Where to return the opcode quad word.
     1248 */
     1249DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64(PIEMCPU pIemCpu, uint64_t *pu64)
     1250{
     1251    uint8_t const offOpcode = pIemCpu->offOpcode;
     1252    if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
     1253        return iemOpcodeGetNextU32ZxU64Slow(pIemCpu, pu64);
     1254
     1255    *pu64 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
     1256                                pIemCpu->abOpcode[offOpcode + 1],
     1257                                pIemCpu->abOpcode[offOpcode + 2],
     1258                                pIemCpu->abOpcode[offOpcode + 3]);
     1259    pIemCpu->offOpcode = offOpcode + 4;
     1260    return VINF_SUCCESS;
     1261}
     1262
     1263
     1264/**
     1265 * Fetches the next opcode dword and zero extends it to a quad word, returns
     1266 * automatically on failure.
     1267 *
     1268 * @param   a_pu64              Where to return the opcode quad word.
     1269 * @remark Implicitly references pIemCpu.
     1270 */
     1271#define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) \
     1272    do \
     1273    { \
     1274        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32ZxU64(pIemCpu, (a_pu64)); \
     1275        if (rcStrict2 != VINF_SUCCESS) \
     1276            return rcStrict2; \
     1277    } while (0)
     1278
     1279
     1280/**
     1281 * Fetches the next signed double word from the opcode stream.
     1282 *
     1283 * @returns Strict VBox status code.
     1284 * @param   pIemCpu             The IEM state.
     1285 * @param   pi32                Where to return the signed double word.
     1286 */
     1287DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PIEMCPU pIemCpu, int32_t *pi32)
     1288{
     1289    return iemOpcodeGetNextU32(pIemCpu, (uint32_t *)pi32);
     1290}
     1291
     1292/**
     1293 * Fetches the next signed double word from the opcode stream, returning
     1294 * automatically on failure.
     1295 *
     1296 * @param   pi32                Where to return the signed double word.
     1297 * @remark Implicitly references pIemCpu.
     1298 */
     1299#define IEM_OPCODE_GET_NEXT_S32(a_pi32) \
     1300    do \
     1301    { \
     1302        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pIemCpu, (a_pi32)); \
     1303        if (rcStrict2 != VINF_SUCCESS) \
     1304            return rcStrict2; \
     1305    } while (0)
     1306
     1307
     1308/**
    9051309 * Deals with the problematic cases that iemOpcodeGetNextS32SxU64 doesn't like.
    9061310 *
     
    9251329    return rcStrict;
    9261330}
     1331
     1332
     1333/**
     1334 * Fetches the next opcode dword, sign extending it into a quad word.
     1335 *
     1336 * @returns Strict VBox status code.
     1337 * @param   pIemCpu             The IEM state.
     1338 * @param   pu64                Where to return the opcode quad word.
     1339 */
     1340DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64)
     1341{
     1342    uint8_t const offOpcode = pIemCpu->offOpcode;
     1343    if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
     1344        return iemOpcodeGetNextS32SxU64Slow(pIemCpu, pu64);
     1345
     1346    int32_t i32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
     1347                                      pIemCpu->abOpcode[offOpcode + 1],
     1348                                      pIemCpu->abOpcode[offOpcode + 2],
     1349                                      pIemCpu->abOpcode[offOpcode + 3]);
     1350    *pu64 = i32;
     1351    pIemCpu->offOpcode = offOpcode + 4;
     1352    return VINF_SUCCESS;
     1353}
     1354
     1355
     1356/**
     1357 * Fetches the next opcode double word and sign extends it to a quad word,
     1358 * returns automatically on failure.
     1359 *
     1360 * @param   a_pu64              Where to return the opcode quad word.
     1361 * @remark Implicitly references pIemCpu.
     1362 */
     1363#define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \
     1364    do \
     1365    { \
     1366        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pIemCpu, (a_pu64)); \
     1367        if (rcStrict2 != VINF_SUCCESS) \
     1368            return rcStrict2; \
     1369    } while (0)
    9271370
    9281371
     
    9571400
    9581401/**
    959  * Fetches the next opcode byte.
    960  *
    961  * @returns Strict VBox status code.
    962  * @param   pIemCpu             The IEM state.
    963  * @param   pu8                 Where to return the opcode byte.
    964  */
    965 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8)
    966 {
    967     uint8_t const offOpcode = pIemCpu->offOpcode;
    968     if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
    969         return iemOpcodeGetNextByteSlow(pIemCpu, pu8);
    970 
    971     *pu8 = pIemCpu->abOpcode[offOpcode];
    972     pIemCpu->offOpcode = offOpcode + 1;
    973     return VINF_SUCCESS;
    974 }
    975 
    976 /**
    977  * Fetches the next opcode byte, returns automatically on failure.
    978  *
    979  * @param   a_pu8               Where to return the opcode byte.
    980  * @remark Implicitly references pIemCpu.
    981  */
    982 #define IEM_OPCODE_GET_NEXT_U8(a_pu8) \
    983     do \
    984     { \
    985         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pIemCpu, (a_pu8)); \
    986         if (rcStrict2 != VINF_SUCCESS) \
    987             return rcStrict2; \
    988     } while (0)
    989 
    990 
    991 /**
    992  * Fetches the next signed byte from the opcode stream.
    993  *
    994  * @returns Strict VBox status code.
    995  * @param   pIemCpu             The IEM state.
    996  * @param   pi8                 Where to return the signed byte.
    997  */
    998 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PIEMCPU pIemCpu, int8_t *pi8)
    999 {
    1000     return iemOpcodeGetNextU8(pIemCpu, (uint8_t *)pi8);
    1001 }
    1002 
    1003 /**
    1004  * Fetches the next signed byte from the opcode stream, returning automatically
    1005  * on failure.
    1006  *
    1007  * @param   pi8                 Where to return the signed byte.
    1008  * @remark Implicitly references pIemCpu.
    1009  */
    1010 #define IEM_OPCODE_GET_NEXT_S8(a_pi8) \
    1011     do \
    1012     { \
    1013         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pIemCpu, (a_pi8)); \
    1014         if (rcStrict2 != VINF_SUCCESS) \
    1015             return rcStrict2; \
    1016     } while (0)
    1017 
    1018 
    1019 /**
    1020  * Fetches the next signed byte from the opcode stream, extending it to
    1021  * unsigned 16-bit.
    1022  *
    1023  * @returns Strict VBox status code.
    1024  * @param   pIemCpu             The IEM state.
    1025  * @param   pu16                Where to return the unsigned word.
    1026  */
    1027 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PIEMCPU pIemCpu, uint16_t *pu16)
    1028 {
    1029     uint8_t const offOpcode = pIemCpu->offOpcode;
    1030     if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))
    1031         return iemOpcodeGetNextS8SxU16Slow(pIemCpu, pu16);
    1032 
    1033     *pu16 = (int8_t)pIemCpu->abOpcode[offOpcode];
    1034     pIemCpu->offOpcode = offOpcode + 1;
    1035     return VINF_SUCCESS;
    1036 }
    1037 
    1038 
    1039 /**
    1040  * Fetches the next signed byte from the opcode stream and sign-extending it to
    1041  * a word, returning automatically on failure.
    1042  *
    1043  * @param   pu16                Where to return the word.
    1044  * @remark Implicitly references pIemCpu.
    1045  */
    1046 #define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \
    1047     do \
    1048     { \
    1049         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pIemCpu, (a_pu16)); \
    1050         if (rcStrict2 != VINF_SUCCESS) \
    1051             return rcStrict2; \
    1052     } while (0)
    1053 
    1054 
    1055 /**
    1056  * Fetches the next opcode word.
    1057  *
    1058  * @returns Strict VBox status code.
    1059  * @param   pIemCpu             The IEM state.
    1060  * @param   pu16                Where to return the opcode word.
    1061  */
    1062 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PIEMCPU pIemCpu, uint16_t *pu16)
    1063 {
    1064     uint8_t const offOpcode = pIemCpu->offOpcode;
    1065     if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))
    1066         return iemOpcodeGetNextU16Slow(pIemCpu, pu16);
    1067 
    1068     *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);
    1069     pIemCpu->offOpcode = offOpcode + 2;
    1070     return VINF_SUCCESS;
    1071 }
    1072 
    1073 /**
    1074  * Fetches the next opcode word, returns automatically on failure.
    1075  *
    1076  * @param   a_pu16              Where to return the opcode word.
    1077  * @remark Implicitly references pIemCpu.
    1078  */
    1079 #define IEM_OPCODE_GET_NEXT_U16(a_pu16) \
    1080     do \
    1081     { \
    1082         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pIemCpu, (a_pu16)); \
    1083         if (rcStrict2 != VINF_SUCCESS) \
    1084             return rcStrict2; \
    1085     } while (0)
    1086 
    1087 
    1088 /**
    1089  * Fetches the next signed word from the opcode stream.
    1090  *
    1091  * @returns Strict VBox status code.
    1092  * @param   pIemCpu             The IEM state.
    1093  * @param   pi16                Where to return the signed word.
    1094  */
    1095 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PIEMCPU pIemCpu, int16_t *pi16)
    1096 {
    1097     return iemOpcodeGetNextU16(pIemCpu, (uint16_t *)pi16);
    1098 }
    1099 
    1100 /**
    1101  * Fetches the next signed word from the opcode stream, returning automatically
    1102  * on failure.
    1103  *
    1104  * @param   pi16                Where to return the signed word.
    1105  * @remark Implicitly references pIemCpu.
    1106  */
    1107 #define IEM_OPCODE_GET_NEXT_S16(a_pi16) \
    1108     do \
    1109     { \
    1110         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pIemCpu, (a_pi16)); \
    1111         if (rcStrict2 != VINF_SUCCESS) \
    1112             return rcStrict2; \
    1113     } while (0)
    1114 
    1115 
    1116 /**
    1117  * Fetches the next opcode dword.
    1118  *
    1119  * @returns Strict VBox status code.
    1120  * @param   pIemCpu             The IEM state.
    1121  * @param   pu32                Where to return the opcode double word.
    1122  */
    1123 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PIEMCPU pIemCpu, uint32_t *pu32)
    1124 {
    1125     uint8_t const offOpcode = pIemCpu->offOpcode;
    1126     if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
    1127         return iemOpcodeGetNextU32Slow(pIemCpu, pu32);
    1128 
    1129     *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
    1130                                 pIemCpu->abOpcode[offOpcode + 1],
    1131                                 pIemCpu->abOpcode[offOpcode + 2],
    1132                                 pIemCpu->abOpcode[offOpcode + 3]);
    1133     pIemCpu->offOpcode = offOpcode + 4;
    1134     return VINF_SUCCESS;
    1135 }
    1136 
    1137 /**
    1138  * Fetches the next opcode dword, returns automatically on failure.
    1139  *
    1140  * @param   a_u32               Where to return the opcode dword.
    1141  * @remark Implicitly references pIemCpu.
    1142  */
    1143 #define IEM_OPCODE_GET_NEXT_U32(a_pu32) \
    1144     do \
    1145     { \
    1146         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pIemCpu, (a_pu32)); \
    1147         if (rcStrict2 != VINF_SUCCESS) \
    1148             return rcStrict2; \
    1149     } while (0)
    1150 
    1151 
    1152 /**
    1153  * Fetches the next signed double word from the opcode stream.
    1154  *
    1155  * @returns Strict VBox status code.
    1156  * @param   pIemCpu             The IEM state.
    1157  * @param   pi32                Where to return the signed double word.
    1158  */
    1159 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PIEMCPU pIemCpu, int32_t *pi32)
    1160 {
    1161     return iemOpcodeGetNextU32(pIemCpu, (uint32_t *)pi32);
    1162 }
    1163 
    1164 /**
    1165  * Fetches the next signed double word from the opcode stream, returning
    1166  * automatically on failure.
    1167  *
    1168  * @param   pi32                Where to return the signed double word.
    1169  * @remark Implicitly references pIemCpu.
    1170  */
    1171 #define IEM_OPCODE_GET_NEXT_S32(a_pi32) \
    1172     do \
    1173     { \
    1174         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pIemCpu, (a_pi32)); \
    1175         if (rcStrict2 != VINF_SUCCESS) \
    1176             return rcStrict2; \
    1177     } while (0)
    1178 
    1179 
    1180 /**
    1181  * Fetches the next opcode dword, sign extending it into a quad word.
    1182  *
    1183  * @returns Strict VBox status code.
    1184  * @param   pIemCpu             The IEM state.
    1185  * @param   pu64                Where to return the opcode quad word.
    1186  */
    1187 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64)
    1188 {
    1189     uint8_t const offOpcode = pIemCpu->offOpcode;
    1190     if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))
    1191         return iemOpcodeGetNextS32SxU64Slow(pIemCpu, pu64);
    1192 
    1193     int32_t i32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],
    1194                                       pIemCpu->abOpcode[offOpcode + 1],
    1195                                       pIemCpu->abOpcode[offOpcode + 2],
    1196                                       pIemCpu->abOpcode[offOpcode + 3]);
    1197     *pu64 = i32;
    1198     pIemCpu->offOpcode = offOpcode + 4;
    1199     return VINF_SUCCESS;
    1200 }
    1201 
    1202 /**
    1203  * Fetches the next opcode double word and sign extends it to a quad word,
    1204  * returns automatically on failure.
    1205  *
    1206  * @param   a_pu64              Where to return the opcode quad word.
    1207  * @remark Implicitly references pIemCpu.
    1208  */
    1209 #define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \
    1210     do \
    1211     { \
    1212         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pIemCpu, (a_pu64)); \
    1213         if (rcStrict2 != VINF_SUCCESS) \
    1214             return rcStrict2; \
    1215     } while (0)
    1216 
    1217 
    1218 /**
    12191402 * Fetches the next opcode qword.
    12201403 *
     
    12401423    return VINF_SUCCESS;
    12411424}
     1425
    12421426
    12431427/**
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r39125 r39127  
    77987798        IEM_OPCODE_GET_NEXT_U32(&offSeg);
    77997799    else
    7800     {
    7801         uint16_t offSeg16; IEM_OPCODE_GET_NEXT_U16(&offSeg16); /** @todo add GET_NEXT_U16_ZX_U32 to reduce code size. */
    7802         offSeg = offSeg16;
    7803     }
     7800        IEM_OPCODE_GET_NEXT_U16_ZX_U32(&offSeg);
    78047801    uint16_t uSel;  IEM_OPCODE_GET_NEXT_U16(&uSel);
    78057802    IEMOP_HLP_NO_LOCK_PREFIX();
     
    78957892        { \
    78967893            case IEMMODE_16BIT: \
    7897             { \
    7898                 uint16_t u16Off; IEM_OPCODE_GET_NEXT_U16(&u16Off); \
    7899                 (a_GCPtrMemOff) = u16Off; \
     7894                IEM_OPCODE_GET_NEXT_U16_ZX_U64(&(a_GCPtrMemOff)); \
    79007895                break; \
    7901             } \
    79027896            case IEMMODE_32BIT: \
    7903             { \
    7904                 uint32_t u32Off; IEM_OPCODE_GET_NEXT_U32(&u32Off); \
    7905                 (a_GCPtrMemOff) = u32Off; \
     7897                IEM_OPCODE_GET_NEXT_U32_ZX_U64(&(a_GCPtrMemOff)); \
    79067898                break; \
    7907             } \
    79087899            case IEMMODE_64BIT: \
    79097900                IEM_OPCODE_GET_NEXT_U64(&(a_GCPtrMemOff)); \
     
    1040110392        {
    1040210393            uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm);
    10403             return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_16, (int32_t)u16Imm);
     10394            return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_16, (int16_t)u16Imm);
    1040410395        }
    1040510396
     
    1046310454        IEM_OPCODE_GET_NEXT_U32(&offSeg);
    1046410455    else
    10465     {
    10466         uint16_t offSeg16; IEM_OPCODE_GET_NEXT_U16(&offSeg16);
    10467         offSeg = offSeg16;
    10468     }
     10456        IEM_OPCODE_GET_NEXT_U16_ZX_U32(&offSeg);
    1046910457    uint16_t uSel;  IEM_OPCODE_GET_NEXT_U16(&uSel);
    1047010458    IEMOP_HLP_NO_LOCK_PREFIX();
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r39125 r39127  
    7979#define IEM_OPCODE_GET_NEXT_U8(a_pu8)                       do { *(a_pu8)  = g_bRandom; CHK_PTYPE(uint8_t  *, a_pu8);  } while (0)
    8080#define IEM_OPCODE_GET_NEXT_U16(a_pu16)                     do { *(a_pu16) = g_bRandom; CHK_PTYPE(uint16_t *, a_pu16); } while (0)
     81#define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32)              do { *(a_pu32) = g_bRandom; CHK_PTYPE(uint32_t *, a_pu32); } while (0)
     82#define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64)              do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
    8183#define IEM_OPCODE_GET_NEXT_U32(a_pu32)                     do { *(a_pu32) = g_bRandom; CHK_PTYPE(uint32_t *, a_pu32); } while (0)
     84#define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64)              do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
    8285#define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64)              do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
    8386#define IEM_OPCODE_GET_NEXT_U64(a_pu64)                     do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette