Home | History | Annotate | Download | only in AssemblerX8664
      1 //===- subzero/unittest/AssemblerX8664/DataMov.cpp ------------------------===//
      2 //
      3 //                        The Subzero Code Generator
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include "AssemblerX8664/TestUtil.h"
     10 
     11 namespace Ice {
     12 namespace X8664 {
     13 namespace Test {
     14 namespace {
     15 
     16 TEST_F(AssemblerX8664Test, MovRegImm) {
     17   static constexpr uint32_t Mask8 = 0x000000FF;
     18   static constexpr uint32_t Mask16 = 0x0000FFFF;
     19   static constexpr uint32_t Mask32 = 0xFFFFFFFF;
     20 
     21 #define MovRegImm(Reg, Suffix, Size)                                           \
     22   do {                                                                         \
     23     static constexpr char TestString[] = "(" #Reg ", " #Size ")";              \
     24     static constexpr uint32_t Value = (0xABCD7645) & Mask##Size;               \
     25     static constexpr uint32_t Marker = 0xBEEFFEEB;                             \
     26     __ mov(IceType_i32, Encoded_GPR_##Reg##q(), Immediate(Marker));            \
     27     __ mov(IceType_i##Size, Encoded_GPR_##Reg##Suffix(), Immediate(Value));    \
     28                                                                                \
     29     AssembledTest test = assemble();                                           \
     30     test.run();                                                                \
     31                                                                                \
     32     ASSERT_EQ(Value, test.Reg##Suffix()) << TestString;                        \
     33     ASSERT_EQ((Marker & ~Mask##Size) | Value, test.Reg##d()) << TestString;    \
     34     reset();                                                                   \
     35   } while (0)
     36 
     37 #define TestImpl(Reg)                                                          \
     38   do {                                                                         \
     39     MovRegImm(Reg, l, 8);                                                      \
     40     MovRegImm(Reg, w, 16);                                                     \
     41     MovRegImm(Reg, d, 32);                                                     \
     42     /* MovRegImm64 not implemented */                                          \
     43   } while (0)
     44 
     45   TestImpl(r1);
     46   TestImpl(r2);
     47   TestImpl(r3);
     48   TestImpl(r4);
     49   TestImpl(r5);
     50   TestImpl(r6);
     51   TestImpl(r7);
     52   TestImpl(r8);
     53   TestImpl(r10);
     54   TestImpl(r11);
     55   TestImpl(r12);
     56   TestImpl(r13);
     57   TestImpl(r14);
     58   TestImpl(r15);
     59 
     60 #undef TestImpl
     61 #undef MovRegImm
     62 }
     63 
     64 TEST_F(AssemblerX8664Test, MovMemImm) {
     65   const uint32_t T0 = allocateDword();
     66   constexpr uint32_t ExpectedT0 = 0x00111100ul;
     67   const uint32_t T1 = allocateDword();
     68   constexpr uint32_t ExpectedT1 = 0x00222200ul;
     69   const uint32_t T2 = allocateDword();
     70   constexpr uint32_t ExpectedT2 = 0x03333000ul;
     71   const uint32_t T3 = allocateDword();
     72   constexpr uint32_t ExpectedT3 = 0x00444400ul;
     73 
     74   __ mov(IceType_i32, dwordAddress(T0), Immediate(ExpectedT0));
     75   __ mov(IceType_i16, dwordAddress(T1), Immediate(ExpectedT1));
     76   __ mov(IceType_i8, dwordAddress(T2), Immediate(ExpectedT2));
     77   __ mov(IceType_i32, dwordAddress(T3), Immediate(ExpectedT3));
     78 
     79   AssembledTest test = assemble();
     80   test.run();
     81   EXPECT_EQ(0ul, test.eax());
     82   EXPECT_EQ(0ul, test.ebx());
     83   EXPECT_EQ(0ul, test.ecx());
     84   EXPECT_EQ(0ul, test.edx());
     85   EXPECT_EQ(0ul, test.edi());
     86   EXPECT_EQ(0ul, test.esi());
     87   EXPECT_EQ(ExpectedT0, test.contentsOfDword(T0));
     88   EXPECT_EQ(ExpectedT1 & 0xFFFF, test.contentsOfDword(T1));
     89   EXPECT_EQ(ExpectedT2 & 0xFF, test.contentsOfDword(T2));
     90   EXPECT_EQ(ExpectedT3, test.contentsOfDword(T3));
     91 }
     92 
     93 TEST_F(AssemblerX8664Test, MovMemReg) {
     94   static constexpr uint64_t Mask8 = 0x00000000000000FF;
     95   static constexpr uint64_t Mask16 = 0x000000000000FFFF;
     96   static constexpr uint64_t Mask32 = 0x00000000FFFFFFFF;
     97   static constexpr uint64_t Mask64 = 0xFFFFFFFFFFFFFFFF;
     98 
     99 #define TestMemReg(Src, Size)                                                  \
    100   do {                                                                         \
    101     static constexpr char TestString[] = "(" #Src ", " #Size ")";              \
    102     static constexpr uint32_t Value = 0x1a4d567e & Mask##Size;                 \
    103     static constexpr uint64_t Marker = 0xD0DA33EEBEEFFEEB;                     \
    104     const uint32_t T0 = allocateQword();                                       \
    105                                                                                \
    106     __ mov(IceType_i32, Encoded_GPR_##Src(), Immediate(Value));                \
    107     __ mov(IceType_i##Size, dwordAddress(T0), Encoded_GPR_##Src());            \
    108                                                                                \
    109     AssembledTest test = assemble();                                           \
    110     test.setQwordTo(T0, Marker);                                               \
    111     test.run();                                                                \
    112                                                                                \
    113     ASSERT_EQ((Marker & ~Mask##Size) | Value, test.contentsOfQword(T0))        \
    114         << TestString;                                                         \
    115     reset();                                                                   \
    116   } while (0)
    117 
    118 #define TestImpl(Src)                                                          \
    119   do {                                                                         \
    120     TestMemReg(Src, 8);                                                        \
    121     TestMemReg(Src, 16);                                                       \
    122     TestMemReg(Src, 32);                                                       \
    123     TestMemReg(Src, 64);                                                       \
    124   } while (0)
    125 
    126   TestImpl(r1);
    127   TestImpl(r2);
    128   TestImpl(r3);
    129   TestImpl(r4);
    130   TestImpl(r5);
    131   TestImpl(r6);
    132   TestImpl(r7);
    133   TestImpl(r8);
    134   TestImpl(r10);
    135   TestImpl(r11);
    136   TestImpl(r12);
    137   TestImpl(r13);
    138   TestImpl(r14);
    139   TestImpl(r15);
    140 
    141 #undef TestImpl
    142 #undef TestMemReg
    143 }
    144 
    145 TEST_F(AssemblerX8664Test, MovRegReg) {
    146   static constexpr uint64_t Mask8 = 0x00000000000000FFull;
    147   static constexpr uint64_t Mask16 = 0x000000000000FFFFull;
    148   static constexpr uint64_t Mask32 = 0x00000000FFFFFFFFull;
    149   static constexpr uint64_t Mask64 = 0xFFFFFFFFFFFFFFFFull;
    150 
    151   static constexpr uint64_t MaskResult8 = 0x00000000000000FFull;
    152   static constexpr uint64_t MaskResult16 = 0x000000000000FFFFull;
    153   static constexpr uint64_t MaskResult32 = 0xFFFFFFFFFFFFFFFFull;
    154   static constexpr uint64_t MaskResult64 = 0xFFFFFFFFFFFFFFFFull;
    155 
    156 #define TestRegReg(Dst, Src, Suffix, Size)                                     \
    157   do {                                                                         \
    158     static constexpr char TestString[] =                                       \
    159         "(" #Dst ", " #Src ", " #Suffix ", " #Size ")";                        \
    160     const uint8_t T0 = allocateQword();                                        \
    161     static constexpr uint64_t Value = 0xA4DD30Af86CCE321ull & Mask##Size;      \
    162     const uint8_t T1 = allocateQword();                                        \
    163     static constexpr uint64_t Marker = 0xC0FFEEA0BEEFFEEFull;                  \
    164                                                                                \
    165     __ mov(IceType_i64, Encoded_GPR_##Src(), dwordAddress(T0));                \
    166     __ mov(IceType_i64, Encoded_GPR_##Dst(), dwordAddress(T1));                \
    167     __ mov(IceType_i##Size, Encoded_GPR_##Dst(), Encoded_GPR_##Src());         \
    168                                                                                \
    169     AssembledTest test = assemble();                                           \
    170     test.setQwordTo(T0, Value);                                                \
    171     test.setQwordTo(T1, Marker);                                               \
    172     test.run();                                                                \
    173                                                                                \
    174     ASSERT_EQ((Marker & ~MaskResult##Size) | Value, test.Dst()) << TestString; \
    175     ASSERT_EQ(Value, test.Dst##Suffix()) << TestString;                        \
    176     reset();                                                                   \
    177   } while (0)
    178 
    179 #define TestImpl(Dst, Src)                                                     \
    180   do {                                                                         \
    181     TestRegReg(Dst, Src, l, 8);                                                \
    182     TestRegReg(Dst, Src, w, 16);                                               \
    183     TestRegReg(Dst, Src, d, 32);                                               \
    184     TestRegReg(Dst, Src, q, 64);                                               \
    185   } while (0)
    186 
    187   TestImpl(r1, r2);
    188   TestImpl(r2, r3);
    189   TestImpl(r3, r4);
    190   TestImpl(r4, r5);
    191   TestImpl(r5, r6);
    192   TestImpl(r6, r7);
    193   TestImpl(r7, r8);
    194   TestImpl(r8, r10);
    195   TestImpl(r10, r11);
    196   TestImpl(r11, r12);
    197   TestImpl(r12, r13);
    198   TestImpl(r13, r14);
    199   TestImpl(r14, r15);
    200   TestImpl(r15, r1);
    201 
    202 #undef TestImpl
    203 #undef TestRegReg
    204 }
    205 
    206 TEST_F(AssemblerX8664Test, MovRegMem) {
    207   static constexpr uint64_t Mask8 = 0x00000000000000FFull;
    208   static constexpr uint64_t Mask16 = 0x000000000000FFFFull;
    209   static constexpr uint64_t Mask32 = 0x00000000FFFFFFFFull;
    210   static constexpr uint64_t Mask64 = 0xFFFFFFFFFFFFFFFFull;
    211 
    212   static constexpr uint64_t MaskResult8 = ~0x00000000000000FFull;
    213   static constexpr uint64_t MaskResult16 = ~0x000000000000FFFFull;
    214   static constexpr uint64_t MaskResult32 = ~0xFFFFFFFFFFFFFFFFull;
    215   static constexpr uint64_t MaskResult64 = ~0xFFFFFFFFFFFFFFFFull;
    216 
    217 #define TestRegAddr(Dst, Suffix, Size)                                         \
    218   do {                                                                         \
    219     static constexpr char TestString[] =                                       \
    220         "(" #Dst ", Addr, " #Suffix ", " #Size ")";                            \
    221     const uint8_t T0 = allocateQword();                                        \
    222     static constexpr uint64_t Value = 0xA4DD30Af86CCE321ull & Mask##Size;      \
    223     const uint8_t T1 = allocateQword();                                        \
    224     static constexpr uint64_t Marker = 0xC0FFEEA0BEEFFEEFull;                  \
    225                                                                                \
    226     __ mov(IceType_i64, Encoded_GPR_##Dst(), dwordAddress(T1));                \
    227     __ mov(IceType_i##Size, Encoded_GPR_##Dst(), dwordAddress(T0));            \
    228                                                                                \
    229     AssembledTest test = assemble();                                           \
    230     test.setQwordTo(T0, Value);                                                \
    231     test.setQwordTo(T1, Marker);                                               \
    232     test.run();                                                                \
    233                                                                                \
    234     ASSERT_EQ((Marker & MaskResult##Size) | Value, test.Dst()) << TestString;  \
    235     ASSERT_EQ(Value, test.Dst##Suffix()) << TestString;                        \
    236     reset();                                                                   \
    237   } while (0)
    238 
    239 #define TestImpl(Dst)                                                          \
    240   do {                                                                         \
    241     TestRegAddr(Dst, l, 8);                                                    \
    242     TestRegAddr(Dst, w, 16);                                                   \
    243     TestRegAddr(Dst, d, 32);                                                   \
    244     TestRegAddr(Dst, q, 64);                                                   \
    245   } while (0)
    246 
    247   TestImpl(r1);
    248   TestImpl(r2);
    249   TestImpl(r3);
    250   TestImpl(r4);
    251   TestImpl(r5);
    252   TestImpl(r6);
    253   TestImpl(r7);
    254   TestImpl(r8);
    255   TestImpl(r10);
    256   TestImpl(r11);
    257   TestImpl(r12);
    258   TestImpl(r13);
    259   TestImpl(r14);
    260   TestImpl(r15);
    261 
    262 #undef TestImpl
    263 #undef TestRegAddr
    264 }
    265 
    266 TEST_F(AssemblerX8664Test, Movabs) {
    267 #define TestImplValue(Dst, Value)                                              \
    268   do {                                                                         \
    269     static constexpr char TestString[] = "(" #Dst ", " #Value ")";             \
    270     uint64_t V = (Value);                                                      \
    271     __ movabs(Encoded_GPR_##Dst##q(), V);                                      \
    272                                                                                \
    273     AssembledTest test = assemble();                                           \
    274                                                                                \
    275     test.run();                                                                \
    276                                                                                \
    277     ASSERT_EQ(V, test.DST()) << TestString;                                    \
    278   } while (0)
    279 
    280 #define TestImpl(Dst)                                                          \
    281   do {                                                                         \
    282     for (uint64_t V = {0, 1, 0xFFFFFFull, 0x80000000ull,                       \
    283                        0xFFFFFFFFFFFFFFFFull}) {                               \
    284       TestImpl(Dst, V);                                                        \
    285     }                                                                          \
    286   } while (0)
    287 
    288 #undef TestImpl
    289 #undef TestImplValue
    290 }
    291 
    292 TEST_F(AssemblerX8664Test, Movzx) {
    293   static constexpr uint32_t Mask8 = 0x000000FF;
    294   static constexpr uint32_t Mask16 = 0x0000FFFF;
    295 
    296 #define TestImplRegReg(Dst, Src, Suffix, Size)                                 \
    297   do {                                                                         \
    298     const uint32_t T0 = allocateDqword();                                      \
    299     static constexpr uint64_t V0 = 0xAAAAAAAAAAAAAAAAull;                      \
    300     static constexpr uint32_t Value = (0xBEEF) & Mask##Size;                   \
    301     __ mov(IceType_i64, Encoded_GPR_##Dst##q(), dwordAddress(T0));             \
    302     __ mov(IceType_i##Size, Encoded_GPR_##Src##Suffix(), Immediate(Value));    \
    303     __ movzx(IceType_i##Size, Encoded_GPR_##Dst##d(),                          \
    304              Encoded_GPR_##Src##Suffix());                                     \
    305     AssembledTest test = assemble();                                           \
    306     test.setQwordTo(T0, V0);                                                   \
    307     test.run();                                                                \
    308     ASSERT_EQ(Value, test.Dst##q()) << "(" #Dst ", " #Src ", " #Size ")";      \
    309     reset();                                                                   \
    310   } while (0)
    311 
    312 #define TestImplRegAddr(Dst, Suffix, Size)                                     \
    313   do {                                                                         \
    314     const uint32_t T0 = allocateDqword();                                      \
    315     static constexpr uint64_t V0 = 0xAAAAAAAAAAAAAAAAull;                      \
    316     static constexpr uint32_t Value = (0xBEEF) & Mask##Size;                   \
    317     __ movzx(IceType_i##Size, Encoded_GPR_##Dst##d(), dwordAddress(T0));       \
    318                                                                                \
    319     AssembledTest test = assemble();                                           \
    320     test.setQwordTo(T0, (V0 & ~Mask##Size) | Value);                           \
    321     test.run();                                                                \
    322     ASSERT_EQ(Value, test.Dst##q()) << "(" #Dst ", Addr, " #Size ")";          \
    323     reset();                                                                   \
    324   } while (0)
    325 
    326 #define TestImpl(Dst, Src)                                                     \
    327   do {                                                                         \
    328     TestImplRegReg(Dst, Src, l, 8);                                            \
    329     TestImplRegAddr(Dst, l, 8);                                                \
    330     TestImplRegReg(Dst, Src, w, 16);                                           \
    331     TestImplRegAddr(Dst, w, 16);                                               \
    332   } while (0)
    333 
    334   TestImpl(r1, r2);
    335   TestImpl(r2, r3);
    336   TestImpl(r3, r4);
    337   TestImpl(r4, r5);
    338   TestImpl(r5, r6);
    339   TestImpl(r6, r7);
    340   TestImpl(r7, r8);
    341   TestImpl(r8, r10);
    342   TestImpl(r10, r11);
    343   TestImpl(r11, r12);
    344   TestImpl(r12, r13);
    345   TestImpl(r13, r14);
    346   TestImpl(r14, r15);
    347   TestImpl(r15, r1);
    348 
    349 #undef TestImpl
    350 #undef TestImplRegAddr
    351 #undef TestImplRegReg
    352 }
    353 
    354 TEST_F(AssemblerX8664Test, Movsx) {
    355   static constexpr uint64_t Mask8 = 0x000000FF;
    356   static constexpr uint64_t Mask16 = 0x0000FFFF;
    357   static constexpr uint64_t Mask32 = 0xFFFFFFFF;
    358 
    359 #define TestImplRegReg(Dst, Src, Suffix, Size)                                 \
    360   do {                                                                         \
    361     const uint32_t T0 = allocateDqword();                                      \
    362     static constexpr uint64_t V0 = 0xAAAAAAAAAAAAAAAAull;                      \
    363     static constexpr uint64_t Value = (0xC0BEBEEF) & Mask##Size;               \
    364     __ mov(IceType_i64, Encoded_GPR_##Dst##q(), dwordAddress(T0));             \
    365     __ mov(IceType_i##Size, Encoded_GPR_##Src##Suffix(), Immediate(Value));    \
    366     __ movsx(IceType_i##Size, Encoded_GPR_##Dst##d(),                          \
    367              Encoded_GPR_##Src##Suffix());                                     \
    368     AssembledTest test = assemble();                                           \
    369     test.setQwordTo(T0, V0);                                                   \
    370     test.run();                                                                \
    371     ASSERT_EQ((uint64_t(-1) & ~Mask##Size) | Value, test.Dst##q())             \
    372         << "(" #Dst ", " #Src ", " #Size ")";                                  \
    373     reset();                                                                   \
    374   } while (0)
    375 
    376 #define TestImplRegAddr(Dst, Suffix, Size)                                     \
    377   do {                                                                         \
    378     const uint32_t T0 = allocateDqword();                                      \
    379     static constexpr uint64_t V0 = 0xC0BEBEEF & Mask##Size;                    \
    380     static constexpr uint64_t Value = (0xC0BEBEEF) & Mask##Size;               \
    381     __ movsx(IceType_i##Size, Encoded_GPR_##Dst##d(), dwordAddress(T0));       \
    382                                                                                \
    383     AssembledTest test = assemble();                                           \
    384     test.setQwordTo(T0, V0);                                                   \
    385     test.run();                                                                \
    386     ASSERT_EQ((uint64_t(-1) & ~Mask##Size) | Value, test.Dst##q())             \
    387         << "(" #Dst ", Addr, " #Size ")";                                      \
    388     reset();                                                                   \
    389   } while (0)
    390 
    391 #define TestImpl(Dst, Src)                                                     \
    392   do {                                                                         \
    393     TestImplRegReg(Dst, Src, l, 8);                                            \
    394     TestImplRegAddr(Dst, l, 8);                                                \
    395     TestImplRegReg(Dst, Src, w, 16);                                           \
    396     TestImplRegAddr(Dst, w, 16);                                               \
    397     TestImplRegReg(Dst, Src, w, 32);                                           \
    398     TestImplRegAddr(Dst, w, 32);                                               \
    399   } while (0)
    400 
    401   TestImpl(r1, r2);
    402   TestImpl(r2, r3);
    403   TestImpl(r3, r4);
    404   TestImpl(r4, r5);
    405   TestImpl(r5, r6);
    406   TestImpl(r6, r7);
    407   TestImpl(r7, r8);
    408   TestImpl(r8, r10);
    409   TestImpl(r10, r11);
    410   TestImpl(r11, r12);
    411   TestImpl(r12, r13);
    412   TestImpl(r13, r14);
    413   TestImpl(r14, r15);
    414   TestImpl(r15, r1);
    415 
    416 #undef TestImpl
    417 #undef TestImplRegAddr
    418 #undef TestImplRegReg
    419 }
    420 
    421 TEST_F(AssemblerX8664Test, Cmov) {
    422 #define TestRegReg(C, Dest, IsTrue, Src0, Value0, Src1, Value1)                \
    423   do {                                                                         \
    424     static constexpr char TestString[] =                                       \
    425         "(" #C ", " #Dest ", " #IsTrue ", " #Src0 ", " #Value0 ", " #Src1      \
    426         ", " #Value1 ")";                                                      \
    427     __ mov(IceType_i32, Encoded_GPR_##Src0(), Immediate(Value0));              \
    428     __ mov(IceType_i32, Encoded_GPR_##Src1(), Immediate(Value1));              \
    429     __ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(Value0));              \
    430     __ cmp(IceType_i32, Encoded_GPR_##Src0(), Encoded_GPR_##Src1());           \
    431     __ cmov(IceType_i32, Cond::Br_##C, Encoded_GPR_##Dest(),                   \
    432             Encoded_GPR_##Src1());                                             \
    433                                                                                \
    434     AssembledTest test = assemble();                                           \
    435     test.run();                                                                \
    436     ASSERT_EQ((IsTrue) ? (Value1) : (Value0), test.Dest()) << TestString;      \
    437                                                                                \
    438     reset();                                                                   \
    439   } while (0)
    440 
    441 #define TestRegAddr(C, Dest, IsTrue, Src0, Value0, Value1)                     \
    442   do {                                                                         \
    443     static constexpr char TestString[] =                                       \
    444         "(" #C ", " #Dest ", " #IsTrue ", " #Src0 ", " #Value0                 \
    445         ", Addr, " #Value1 ")";                                                \
    446     const uint32_t T0 = allocateDword();                                       \
    447     const uint32_t V0 = Value1;                                                \
    448     __ mov(IceType_i32, Encoded_GPR_##Src0(), Immediate(Value0));              \
    449     __ mov(IceType_i32, Encoded_GPR_##Dest(), Immediate(Value0));              \
    450     __ cmp(IceType_i32, Encoded_GPR_##Src0(), dwordAddress(T0));               \
    451     __ cmov(IceType_i32, Cond::Br_##C, Encoded_GPR_##Dest(),                   \
    452             dwordAddress(T0));                                                 \
    453                                                                                \
    454     AssembledTest test = assemble();                                           \
    455     test.setDwordTo(T0, V0);                                                   \
    456     test.run();                                                                \
    457     ASSERT_EQ((IsTrue) ? (Value1) : (Value0), test.Dest()) << TestString;      \
    458                                                                                \
    459     reset();                                                                   \
    460   } while (0)
    461 
    462 #define TestValue(C, Dest, IsTrue, Src0, Value0, Src1, Value1)                 \
    463   do {                                                                         \
    464     TestRegReg(C, Dest, IsTrue, Src0, Value0, Src1, Value1);                   \
    465     TestRegAddr(C, Dest, IsTrue, Src0, Value0, Value1);                        \
    466   } while (0)
    467 
    468 #define TestImpl(Dest, Src0, Src1)                                             \
    469   do {                                                                         \
    470     TestValue(o, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                     \
    471     TestValue(o, Dest, 0u, Src0, 0x1u, Src1, 0x10000000u);                     \
    472     TestValue(no, Dest, 1u, Src0, 0x1u, Src1, 0x10000000u);                    \
    473     TestValue(no, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u);                    \
    474     TestValue(b, Dest, 1u, Src0, 0x1, Src1, 0x80000000u);                      \
    475     TestValue(b, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u);                     \
    476     TestValue(ae, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                    \
    477     TestValue(ae, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u);                    \
    478     TestValue(e, Dest, 1u, Src0, 0x1u, Src1, 0x1u);                            \
    479     TestValue(e, Dest, 0u, Src0, 0x1u, Src1, 0x11111u);                        \
    480     TestValue(ne, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                    \
    481     TestValue(ne, Dest, 0u, Src0, 0x1u, Src1, 0x1u);                           \
    482     TestValue(be, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u);                    \
    483     TestValue(be, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u);                    \
    484     TestValue(a, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                     \
    485     TestValue(a, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u);                     \
    486     TestValue(s, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u);                     \
    487     TestValue(s, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u);                     \
    488     TestValue(ns, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                    \
    489     TestValue(ns, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u);                    \
    490     TestValue(p, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                     \
    491     TestValue(p, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u);                     \
    492     TestValue(np, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u);                    \
    493     TestValue(np, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u);                    \
    494     TestValue(l, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                     \
    495     TestValue(l, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u);                     \
    496     TestValue(ge, Dest, 1u, Src0, 0x1u, Src1, 0x80000000u);                    \
    497     TestValue(ge, Dest, 0u, Src0, 0x80000000u, Src1, 0x1u);                    \
    498     TestValue(le, Dest, 1u, Src0, 0x80000000u, Src1, 0x1u);                    \
    499     TestValue(le, Dest, 0u, Src0, 0x1u, Src1, 0x80000000u);                    \
    500   } while (0)
    501 
    502   TestImpl(r1, r2, r3);
    503 
    504 #undef TestImpl
    505 #undef TestValue
    506 #undef TestRegAddr
    507 #undef TestRegReg
    508 }
    509 
    510 TEST_F(AssemblerX8664LowLevelTest, RepMovsb) {
    511   __ rep_movsb();
    512 
    513   static constexpr uint32_t ByteCount = 2;
    514   static constexpr uint8_t Prefix = 0xF3;
    515   static constexpr uint8_t Opcode = 0xA4;
    516 
    517   ASSERT_EQ(ByteCount, codeBytesSize());
    518   verifyBytes<ByteCount>(codeBytes(), Prefix, Opcode);
    519 }
    520 
    521 TEST_F(AssemblerX8664Test, MovssXmmAddr) {
    522 #define TestMovssXmmAddrFloatLength(FloatLength, Xmm, Value)                   \
    523   do {                                                                         \
    524     static_assert((FloatLength) == 32 || (FloatLength) == 64,                  \
    525                   "Invalid fp length #FloatLength");                           \
    526     using Type = std::conditional<FloatLength == 32, float, double>::type;     \
    527                                                                                \
    528     static constexpr char TestString[] = "(" #FloatLength ", " #Xmm ")";       \
    529     static constexpr bool IsDouble = std::is_same<Type, double>::value;        \
    530     const uint32_t T0 = allocateQword();                                       \
    531     const Type V0 = Value;                                                     \
    532                                                                                \
    533     __ movss(IceType_f##FloatLength, Encoded_Xmm_##Xmm(), dwordAddress(T0));   \
    534                                                                                \
    535     AssembledTest test = assemble();                                           \
    536     if (IsDouble) {                                                            \
    537       test.setQwordTo(T0, static_cast<double>(V0));                            \
    538     } else {                                                                   \
    539       test.setDwordTo(T0, static_cast<float>(V0));                             \
    540     }                                                                          \
    541     test.run();                                                                \
    542     ASSERT_DOUBLE_EQ(Value, test.Xmm<Type>()) << TestString << " value is "    \
    543                                               << Value;                        \
    544     reset();                                                                   \
    545   } while (0)
    546 
    547 #define TestMovssXmmAddr(FloatLength)                                          \
    548   do {                                                                         \
    549     using Type = std::conditional<FloatLength == 32, float, double>::type;     \
    550     for (const Type Value : {0.0, -0.0, 1.0, -1.0, 3.14, 99999.9999}) {        \
    551       TestMovssXmmAddrFloatLength(FloatLength, xmm0, Value);                   \
    552       TestMovssXmmAddrFloatLength(FloatLength, xmm1, Value);                   \
    553       TestMovssXmmAddrFloatLength(FloatLength, xmm2, Value);                   \
    554       TestMovssXmmAddrFloatLength(FloatLength, xmm3, Value);                   \
    555       TestMovssXmmAddrFloatLength(FloatLength, xmm4, Value);                   \
    556       TestMovssXmmAddrFloatLength(FloatLength, xmm5, Value);                   \
    557       TestMovssXmmAddrFloatLength(FloatLength, xmm6, Value);                   \
    558       TestMovssXmmAddrFloatLength(FloatLength, xmm7, Value);                   \
    559       TestMovssXmmAddrFloatLength(FloatLength, xmm8, Value);                   \
    560       TestMovssXmmAddrFloatLength(FloatLength, xmm9, Value);                   \
    561       TestMovssXmmAddrFloatLength(FloatLength, xmm10, Value);                  \
    562       TestMovssXmmAddrFloatLength(FloatLength, xmm11, Value);                  \
    563       TestMovssXmmAddrFloatLength(FloatLength, xmm12, Value);                  \
    564       TestMovssXmmAddrFloatLength(FloatLength, xmm13, Value);                  \
    565       TestMovssXmmAddrFloatLength(FloatLength, xmm14, Value);                  \
    566       TestMovssXmmAddrFloatLength(FloatLength, xmm15, Value);                  \
    567     }                                                                          \
    568   } while (0)
    569 
    570   TestMovssXmmAddr(32);
    571   TestMovssXmmAddr(64);
    572 
    573 #undef TestMovssXmmAddr
    574 #undef TestMovssXmmAddrType
    575 }
    576 
    577 TEST_F(AssemblerX8664Test, MovssAddrXmm) {
    578 #define TestMovssAddrXmmFloatLength(FloatLength, Xmm, Value)                   \
    579   do {                                                                         \
    580     static_assert((FloatLength) == 32 || (FloatLength) == 64,                  \
    581                   "Invalid fp length #FloatLength");                           \
    582     using Type = std::conditional<FloatLength == 32, float, double>::type;     \
    583                                                                                \
    584     static constexpr char TestString[] = "(" #FloatLength ", " #Xmm ")";       \
    585     static constexpr bool IsDouble = std::is_same<Type, double>::value;        \
    586     const uint32_t T0 = allocateQword();                                       \
    587     const Type V0 = Value;                                                     \
    588     const uint32_t T1 = allocateQword();                                       \
    589     static_assert(std::numeric_limits<Type>::has_quiet_NaN,                    \
    590                   "f" #FloatLength " does not have quiet nan.");               \
    591     const Type V1 = std::numeric_limits<Type>::quiet_NaN();                    \
    592                                                                                \
    593     __ movss(IceType_f##FloatLength, Encoded_Xmm_##Xmm(), dwordAddress(T0));   \
    594                                                                                \
    595     AssembledTest test = assemble();                                           \
    596     if (IsDouble) {                                                            \
    597       test.setQwordTo(T0, static_cast<double>(V0));                            \
    598       test.setQwordTo(T1, static_cast<double>(V1));                            \
    599     } else {                                                                   \
    600       test.setDwordTo(T0, static_cast<float>(V0));                             \
    601       test.setDwordTo(T1, static_cast<float>(V1));                             \
    602     }                                                                          \
    603     test.run();                                                                \
    604     ASSERT_DOUBLE_EQ(Value, test.Xmm<Type>()) << TestString << " value is "    \
    605                                               << Value;                        \
    606     reset();                                                                   \
    607   } while (0)
    608 
    609 #define TestMovssAddrXmm(FloatLength)                                          \
    610   do {                                                                         \
    611     using Type = std::conditional<FloatLength == 32, float, double>::type;     \
    612     for (const Type Value : {0.0, -0.0, 1.0, -1.0, 3.14, 99999.9999}) {        \
    613       TestMovssAddrXmmFloatLength(FloatLength, xmm0, Value);                   \
    614       TestMovssAddrXmmFloatLength(FloatLength, xmm1, Value);                   \
    615       TestMovssAddrXmmFloatLength(FloatLength, xmm2, Value);                   \
    616       TestMovssAddrXmmFloatLength(FloatLength, xmm3, Value);                   \
    617       TestMovssAddrXmmFloatLength(FloatLength, xmm4, Value);                   \
    618       TestMovssAddrXmmFloatLength(FloatLength, xmm5, Value);                   \
    619       TestMovssAddrXmmFloatLength(FloatLength, xmm6, Value);                   \
    620       TestMovssAddrXmmFloatLength(FloatLength, xmm7, Value);                   \
    621       TestMovssAddrXmmFloatLength(FloatLength, xmm8, Value);                   \
    622       TestMovssAddrXmmFloatLength(FloatLength, xmm9, Value);                   \
    623       TestMovssAddrXmmFloatLength(FloatLength, xmm10, Value);                  \
    624       TestMovssAddrXmmFloatLength(FloatLength, xmm11, Value);                  \
    625       TestMovssAddrXmmFloatLength(FloatLength, xmm12, Value);                  \
    626       TestMovssAddrXmmFloatLength(FloatLength, xmm13, Value);                  \
    627       TestMovssAddrXmmFloatLength(FloatLength, xmm14, Value);                  \
    628       TestMovssAddrXmmFloatLength(FloatLength, xmm15, Value);                  \
    629     }                                                                          \
    630   } while (0)
    631 
    632   TestMovssAddrXmm(32);
    633   TestMovssAddrXmm(64);
    634 
    635 #undef TestMovssAddrXmm
    636 #undef TestMovssAddrXmmType
    637 }
    638 
    639 TEST_F(AssemblerX8664Test, MovssXmmXmm) {
    640 #define TestMovssXmmXmmFloatLength(FloatLength, Src, Dst, Value)               \
    641   do {                                                                         \
    642     static_assert((FloatLength) == 32 || (FloatLength) == 64,                  \
    643                   "Invalid fp length #FloatLength");                           \
    644     using Type = std::conditional<FloatLength == 32, float, double>::type;     \
    645                                                                                \
    646     static constexpr char TestString[] =                                       \
    647         "(" #FloatLength ", " #Src ", " #Dst ")";                              \
    648     static constexpr bool IsDouble = std::is_same<Type, double>::value;        \
    649     const uint32_t T0 = allocateQword();                                       \
    650     const Type V0 = Value;                                                     \
    651     const uint32_t T1 = allocateQword();                                       \
    652     static_assert(std::numeric_limits<Type>::has_quiet_NaN,                    \
    653                   "f" #FloatLength " does not have quiet nan.");               \
    654     const Type V1 = std::numeric_limits<Type>::quiet_NaN();                    \
    655                                                                                \
    656     __ movss(IceType_f##FloatLength, Encoded_Xmm_##Src(), dwordAddress(T0));   \
    657     __ movss(IceType_f##FloatLength, Encoded_Xmm_##Dst(), dwordAddress(T1));   \
    658     __ movss(IceType_f##FloatLength, Encoded_Xmm_##Dst(),                      \
    659              Encoded_Xmm_##Src());                                             \
    660                                                                                \
    661     AssembledTest test = assemble();                                           \
    662     if (IsDouble) {                                                            \
    663       test.setQwordTo(T0, static_cast<double>(V0));                            \
    664       test.setQwordTo(T1, static_cast<double>(V1));                            \
    665     } else {                                                                   \
    666       test.setDwordTo(T0, static_cast<float>(V0));                             \
    667       test.setDwordTo(T1, static_cast<float>(V1));                             \
    668     }                                                                          \
    669     test.run();                                                                \
    670     ASSERT_DOUBLE_EQ(Value, test.Dst<Type>()) << TestString << " value is "    \
    671                                               << Value;                        \
    672     reset();                                                                   \
    673   } while (0)
    674 
    675 #define TestMovssXmmXmm(FloatLength)                                           \
    676   do {                                                                         \
    677     using Type = std::conditional<FloatLength == 32, float, double>::type;     \
    678     for (const Type Value : {0.0, -0.0, 1.0, -1.0, 3.14, 99999.9999}) {        \
    679       TestMovssXmmXmmFloatLength(FloatLength, xmm0, xmm1, Value);              \
    680       TestMovssXmmXmmFloatLength(FloatLength, xmm1, xmm2, Value);              \
    681       TestMovssXmmXmmFloatLength(FloatLength, xmm2, xmm3, Value);              \
    682       TestMovssXmmXmmFloatLength(FloatLength, xmm3, xmm4, Value);              \
    683       TestMovssXmmXmmFloatLength(FloatLength, xmm4, xmm5, Value);              \
    684       TestMovssXmmXmmFloatLength(FloatLength, xmm5, xmm6, Value);              \
    685       TestMovssXmmXmmFloatLength(FloatLength, xmm6, xmm7, Value);              \
    686       TestMovssXmmXmmFloatLength(FloatLength, xmm7, xmm8, Value);              \
    687       TestMovssXmmXmmFloatLength(FloatLength, xmm8, xmm9, Value);              \
    688       TestMovssXmmXmmFloatLength(FloatLength, xmm9, xmm10, Value);             \
    689       TestMovssXmmXmmFloatLength(FloatLength, xmm10, xmm11, Value);            \
    690       TestMovssXmmXmmFloatLength(FloatLength, xmm11, xmm12, Value);            \
    691       TestMovssXmmXmmFloatLength(FloatLength, xmm12, xmm13, Value);            \
    692       TestMovssXmmXmmFloatLength(FloatLength, xmm13, xmm14, Value);            \
    693       TestMovssXmmXmmFloatLength(FloatLength, xmm14, xmm15, Value);            \
    694       TestMovssXmmXmmFloatLength(FloatLength, xmm15, xmm0, Value);             \
    695     }                                                                          \
    696   } while (0)
    697 
    698   TestMovssXmmXmm(32);
    699   TestMovssXmmXmm(64);
    700 
    701 #undef TestMovssXmmXmm
    702 #undef TestMovssXmmXmmType
    703 }
    704 
    705 TEST_F(AssemblerX8664Test, MovdToXmm) {
    706 #define TestMovdXmmReg32(Src, Dst, Value)                                      \
    707   do {                                                                         \
    708     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    709     static constexpr char TestString[] = "(" #Src ", " #Dst ")";               \
    710     const uint32_t T0 = allocateQword();                                       \
    711     const uint64_t V0 = 0xFFFFFFFF00000000ull;                                 \
    712                                                                                \
    713     __ mov(IceType_i32, Encoded_GPR_##Src(), Immediate(Value));                \
    714     __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T0));              \
    715     __ movd(IceType_i32, Encoded_Xmm_##Dst(), Encoded_GPR_##Src());            \
    716                                                                                \
    717     AssembledTest test = assemble();                                           \
    718                                                                                \
    719     test.setQwordTo(T0, V0);                                                   \
    720     test.run();                                                                \
    721                                                                                \
    722     ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is "       \
    723                                            << Value;                           \
    724     reset();                                                                   \
    725   } while (0)
    726 
    727 #define TestMovdXmmReg64(Src, Dst, Value)                                      \
    728   do {                                                                         \
    729     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    730     static constexpr char TestString[] = "(" #Src ", " #Dst ")";               \
    731     const uint32_t T0 = allocateQword();                                       \
    732     const uint64_t V0 = 0xFFFFFFFF00000000ull;                                 \
    733     const uint64_t Expected = (static_cast<uint64_t>(Value) << 32) | (Value);  \
    734                                                                                \
    735     __ movabs(Encoded_GPR_##Src(), Expected);                                  \
    736     __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T0));              \
    737     __ movd(IceType_i64, Encoded_Xmm_##Dst(), Encoded_GPR_##Src());            \
    738                                                                                \
    739     AssembledTest test = assemble();                                           \
    740                                                                                \
    741     test.setQwordTo(T0, V0);                                                   \
    742     test.run();                                                                \
    743                                                                                \
    744     ASSERT_EQ(Expected, test.Dst<uint64_t>()) << TestString << " value is "    \
    745                                               << Value;                        \
    746     reset();                                                                   \
    747   } while (0)
    748 
    749 #define TestMovdXmmReg(Src, Dst, Value)                                        \
    750   do {                                                                         \
    751     TestMovdXmmReg32(Src, Dst, Value);                                         \
    752     TestMovdXmmReg64(Src, Dst, Value);                                         \
    753   } while (0)
    754 
    755 #define TestMovdXmmAddr32(Dst, Value)                                          \
    756   do {                                                                         \
    757     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    758     static constexpr char TestString[] = "(" #Dst ", Addr)";                   \
    759     const uint32_t T0 = allocateQword();                                       \
    760     const uint32_t V0 = Value;                                                 \
    761     const uint32_t T1 = allocateQword();                                       \
    762     const uint64_t V1 = 0xFFFFFFFF00000000ull;                                 \
    763                                                                                \
    764     __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T1));              \
    765     __ movd(IceType_i32, Encoded_Xmm_##Dst(), dwordAddress(T0));               \
    766                                                                                \
    767     AssembledTest test = assemble();                                           \
    768                                                                                \
    769     test.setDwordTo(T0, V0);                                                   \
    770     test.setQwordTo(T1, V1);                                                   \
    771     test.run();                                                                \
    772                                                                                \
    773     ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is "       \
    774                                            << Value;                           \
    775     reset();                                                                   \
    776   } while (0)
    777 
    778 #define TestMovdXmmAddr64(Dst, Value)                                          \
    779   do {                                                                         \
    780     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    781     static constexpr char TestString[] = "(" #Dst ", Addr)";                   \
    782     const uint32_t T0 = allocateQword();                                       \
    783     const uint32_t V0 = (static_cast<uint64_t>(Value) << 32) | (Value);        \
    784     const uint32_t T1 = allocateQword();                                       \
    785     const uint64_t V1 = 0xFFFFFFFF00000000ull;                                 \
    786                                                                                \
    787     __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T1));              \
    788     __ movd(IceType_i64, Encoded_Xmm_##Dst(), dwordAddress(T0));               \
    789                                                                                \
    790     AssembledTest test = assemble();                                           \
    791                                                                                \
    792     test.setDwordTo(T0, V0);                                                   \
    793     test.setQwordTo(T1, V1);                                                   \
    794     test.run();                                                                \
    795                                                                                \
    796     ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is "       \
    797                                            << Value;                           \
    798     reset();                                                                   \
    799   } while (0)
    800 
    801 #define TestMovdXmmAddr(Dst, Value)                                            \
    802   do {                                                                         \
    803     TestMovdXmmAddr32(Dst, Value);                                             \
    804     TestMovdXmmAddr64(Dst, Value);                                             \
    805   } while (0)
    806 
    807 #define TestMovd(Dst)                                                          \
    808   do {                                                                         \
    809     for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {   \
    810       TestMovdXmmReg(r1, Dst, Value);                                          \
    811       TestMovdXmmReg(r2, Dst, Value);                                          \
    812       TestMovdXmmReg(r3, Dst, Value);                                          \
    813       TestMovdXmmReg(r4, Dst, Value);                                          \
    814       TestMovdXmmReg(r5, Dst, Value);                                          \
    815       TestMovdXmmReg(r6, Dst, Value);                                          \
    816       TestMovdXmmReg(r7, Dst, Value);                                          \
    817       TestMovdXmmReg(r8, Dst, Value);                                          \
    818       TestMovdXmmReg(r10, Dst, Value);                                         \
    819       TestMovdXmmReg(r11, Dst, Value);                                         \
    820       TestMovdXmmReg(r12, Dst, Value);                                         \
    821       TestMovdXmmReg(r13, Dst, Value);                                         \
    822       TestMovdXmmReg(r14, Dst, Value);                                         \
    823       TestMovdXmmReg(r15, Dst, Value);                                         \
    824       TestMovdXmmAddr(Dst, Value);                                             \
    825     }                                                                          \
    826   } while (0)
    827 
    828   TestMovd(xmm0);
    829   TestMovd(xmm1);
    830   TestMovd(xmm2);
    831   TestMovd(xmm3);
    832   TestMovd(xmm4);
    833   TestMovd(xmm5);
    834   TestMovd(xmm6);
    835   TestMovd(xmm7);
    836   TestMovd(xmm8);
    837   TestMovd(xmm9);
    838   TestMovd(xmm10);
    839   TestMovd(xmm11);
    840   TestMovd(xmm12);
    841   TestMovd(xmm13);
    842   TestMovd(xmm14);
    843   TestMovd(xmm15);
    844 
    845 #undef TestMovd
    846 #undef TestMovdXmmAddr
    847 #undef TestMovdXmmAddr64
    848 #undef TestMovdXmmAddr32
    849 #undef TestMovdXmmReg
    850 #undef TestMovdXmmReg64
    851 #undef TestMovdXmmReg32
    852 }
    853 
    854 TEST_F(AssemblerX8664Test, MovdFromXmm) {
    855 #define TestMovdRegXmm32(Src, Dst, Value)                                      \
    856   do {                                                                         \
    857     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    858     static constexpr char TestString[] = "(" #Src ", " #Dst ")";               \
    859     const uint32_t T0 = allocateDword();                                       \
    860     const uint32_t V0 = Value;                                                 \
    861                                                                                \
    862     __ movss(IceType_f64, Encoded_Xmm_##Src(), dwordAddress(T0));              \
    863     __ movd(IceType_i32, Encoded_GPR_##Dst(), Encoded_Xmm_##Src());            \
    864                                                                                \
    865     AssembledTest test = assemble();                                           \
    866                                                                                \
    867     test.setDwordTo(T0, V0);                                                   \
    868     test.run();                                                                \
    869                                                                                \
    870     ASSERT_EQ(Value, test.contentsOfDword(T0)) << TestString << " value is "   \
    871                                                << Value;                       \
    872     reset();                                                                   \
    873   } while (0)
    874 
    875 #define TestMovdRegXmm64(Src, Dst, Value)                                      \
    876   do {                                                                         \
    877     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    878     static constexpr char TestString[] = "(" #Src ", " #Dst ")";               \
    879     const uint32_t T0 = allocateDword();                                       \
    880     const uint64_t V0 = (static_cast<uint64_t>(Value) << 32) | (Value);        \
    881                                                                                \
    882     __ movss(IceType_f64, Encoded_Xmm_##Src(), dwordAddress(T0));              \
    883     __ movd(IceType_i64, Encoded_GPR_##Dst(), Encoded_Xmm_##Src());            \
    884                                                                                \
    885     AssembledTest test = assemble();                                           \
    886                                                                                \
    887     test.setQwordTo(T0, V0);                                                   \
    888     test.run();                                                                \
    889                                                                                \
    890     ASSERT_EQ(V0, test.contentsOfQword(T0)) << TestString << " value is "      \
    891                                             << Value;                          \
    892     reset();                                                                   \
    893   } while (0)
    894 
    895 #define TestMovdRegXmm(Src, Dst, Value)                                        \
    896   do {                                                                         \
    897     TestMovdRegXmm32(Src, Dst, Value);                                         \
    898     TestMovdRegXmm64(Src, Dst, Value);                                         \
    899   } while (0)
    900 
    901 #define TestMovdAddrXmm32(Src, Value)                                          \
    902   do {                                                                         \
    903     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    904     static constexpr char TestString[] = "(" #Src ", Addr)";                   \
    905     const uint32_t T0 = allocateDword();                                       \
    906     const uint32_t V0 = Value;                                                 \
    907     const uint32_t T1 = allocateDword();                                       \
    908     const uint32_t V1 = ~(Value);                                              \
    909                                                                                \
    910     __ movss(IceType_f64, Encoded_Xmm_##Src(), dwordAddress(T0));              \
    911     __ movd(IceType_i32, dwordAddress(T1), Encoded_Xmm_##Src());               \
    912                                                                                \
    913     AssembledTest test = assemble();                                           \
    914                                                                                \
    915     test.setDwordTo(T0, V0);                                                   \
    916     test.setDwordTo(T1, V1);                                                   \
    917     test.run();                                                                \
    918                                                                                \
    919     ASSERT_EQ(Value, test.contentsOfDword(T1)) << TestString << " value is "   \
    920                                                << Value;                       \
    921     reset();                                                                   \
    922   } while (0)
    923 
    924 #define TestMovdAddrXmm64(Src, Value)                                          \
    925   do {                                                                         \
    926     assert(((Value)&0xFFFFFFFF) == (Value));                                   \
    927     static constexpr char TestString[] = "(" #Src ", Addr)";                   \
    928     const uint32_t T0 = allocateQword();                                       \
    929     const uint64_t V0 = (static_cast<uint64_t>(Value) << 32) | Value;          \
    930     const uint32_t T1 = allocateQword();                                       \
    931     const uint64_t V1 = ~V0;                                                   \
    932                                                                                \
    933     __ movss(IceType_f64, Encoded_Xmm_##Src(), dwordAddress(T0));              \
    934     __ movd(IceType_i64, dwordAddress(T1), Encoded_Xmm_##Src());               \
    935                                                                                \
    936     AssembledTest test = assemble();                                           \
    937                                                                                \
    938     test.setQwordTo(T0, V0);                                                   \
    939     test.setQwordTo(T1, V1);                                                   \
    940     test.run();                                                                \
    941                                                                                \
    942     ASSERT_EQ(V0, test.contentsOfQword(T1)) << TestString << " value is "      \
    943                                             << Value;                          \
    944     reset();                                                                   \
    945   } while (0)
    946 
    947 #define TestMovdAddrXmm(Src, Value)                                            \
    948   do {                                                                         \
    949     TestMovdAddrXmm32(Src, Value);                                             \
    950     TestMovdAddrXmm64(Src, Value);                                             \
    951   } while (0)
    952 
    953 #define TestMovd(Src)                                                          \
    954   do {                                                                         \
    955     for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {   \
    956       TestMovdRegXmm(Src, r1, Value);                                          \
    957       TestMovdRegXmm(Src, r2, Value);                                          \
    958       TestMovdRegXmm(Src, r3, Value);                                          \
    959       TestMovdRegXmm(Src, r4, Value);                                          \
    960       TestMovdRegXmm(Src, r5, Value);                                          \
    961       TestMovdRegXmm(Src, r6, Value);                                          \
    962       TestMovdRegXmm(Src, r7, Value);                                          \
    963       TestMovdRegXmm(Src, r8, Value);                                          \
    964       TestMovdRegXmm(Src, r10, Value);                                         \
    965       TestMovdRegXmm(Src, r11, Value);                                         \
    966       TestMovdRegXmm(Src, r12, Value);                                         \
    967       TestMovdRegXmm(Src, r13, Value);                                         \
    968       TestMovdRegXmm(Src, r14, Value);                                         \
    969       TestMovdRegXmm(Src, r15, Value);                                         \
    970       TestMovdAddrXmm(Src, Value);                                             \
    971     }                                                                          \
    972   } while (0)
    973 
    974   TestMovd(xmm0);
    975   TestMovd(xmm1);
    976   TestMovd(xmm2);
    977   TestMovd(xmm3);
    978   TestMovd(xmm4);
    979   TestMovd(xmm5);
    980   TestMovd(xmm6);
    981   TestMovd(xmm7);
    982   TestMovd(xmm8);
    983   TestMovd(xmm9);
    984   TestMovd(xmm10);
    985   TestMovd(xmm11);
    986   TestMovd(xmm12);
    987   TestMovd(xmm13);
    988   TestMovd(xmm14);
    989   TestMovd(xmm15);
    990 
    991 #undef TestMovd
    992 #undef TestMovdAddrXmm
    993 #undef TestMovdAddrXmm64
    994 #undef TestMovdAddrXmm32
    995 #undef TestMovdRegXmm
    996 #undef TestMovdRegXmm64
    997 #undef TestMovdRegXmm32
    998 }
    999 
   1000 TEST_F(AssemblerX8664Test, MovqXmmAddr) {
   1001 #define TestMovd(Dst, Value)                                                   \
   1002   do {                                                                         \
   1003     static constexpr char TestString[] = "(" #Dst ", Addr)";                   \
   1004     const uint32_t T0 = allocateQword();                                       \
   1005     const uint64_t V0 = Value;                                                 \
   1006     const uint32_t T1 = allocateQword();                                       \
   1007     const uint64_t V1 = ~(Value);                                              \
   1008                                                                                \
   1009     __ movss(IceType_f64, Encoded_Xmm_##Dst(), dwordAddress(T1));              \
   1010     __ movq(Encoded_Xmm_##Dst(), dwordAddress(T0));                            \
   1011                                                                                \
   1012     AssembledTest test = assemble();                                           \
   1013                                                                                \
   1014     test.setQwordTo(T0, V0);                                                   \
   1015     test.setQwordTo(T1, V1);                                                   \
   1016     test.run();                                                                \
   1017                                                                                \
   1018     ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is "       \
   1019                                            << Value;                           \
   1020     reset();                                                                   \
   1021   } while (0)
   1022 
   1023   for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {
   1024     TestMovd(xmm0, Value);
   1025     TestMovd(xmm1, Value);
   1026     TestMovd(xmm2, Value);
   1027     TestMovd(xmm3, Value);
   1028     TestMovd(xmm4, Value);
   1029     TestMovd(xmm5, Value);
   1030     TestMovd(xmm6, Value);
   1031     TestMovd(xmm7, Value);
   1032     TestMovd(xmm8, Value);
   1033     TestMovd(xmm9, Value);
   1034     TestMovd(xmm10, Value);
   1035     TestMovd(xmm11, Value);
   1036     TestMovd(xmm12, Value);
   1037     TestMovd(xmm13, Value);
   1038     TestMovd(xmm14, Value);
   1039     TestMovd(xmm15, Value);
   1040   }
   1041 
   1042 #undef TestMovd
   1043 }
   1044 
   1045 TEST_F(AssemblerX8664Test, MovqAddrXmm) {
   1046 #define TestMovd(Dst, Value)                                                   \
   1047   do {                                                                         \
   1048     static constexpr char TestString[] = "(" #Dst ", Addr)";                   \
   1049     const uint32_t T0 = allocateQword();                                       \
   1050     const uint64_t V0 = Value;                                                 \
   1051     const uint32_t T1 = allocateQword();                                       \
   1052     const uint64_t V1 = ~(Value);                                              \
   1053                                                                                \
   1054     __ movq(Encoded_Xmm_##Dst(), dwordAddress(T0));                            \
   1055     __ movq(dwordAddress(T1), Encoded_Xmm_##Dst());                            \
   1056                                                                                \
   1057     AssembledTest test = assemble();                                           \
   1058                                                                                \
   1059     test.setQwordTo(T0, V0);                                                   \
   1060     test.setQwordTo(T1, V1);                                                   \
   1061     test.run();                                                                \
   1062                                                                                \
   1063     ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is "       \
   1064                                            << Value;                           \
   1065     reset();                                                                   \
   1066   } while (0)
   1067 
   1068   for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {
   1069     TestMovd(xmm0, Value);
   1070     TestMovd(xmm1, Value);
   1071     TestMovd(xmm2, Value);
   1072     TestMovd(xmm3, Value);
   1073     TestMovd(xmm4, Value);
   1074     TestMovd(xmm5, Value);
   1075     TestMovd(xmm6, Value);
   1076     TestMovd(xmm7, Value);
   1077     TestMovd(xmm8, Value);
   1078     TestMovd(xmm9, Value);
   1079     TestMovd(xmm10, Value);
   1080     TestMovd(xmm11, Value);
   1081     TestMovd(xmm12, Value);
   1082     TestMovd(xmm13, Value);
   1083     TestMovd(xmm14, Value);
   1084     TestMovd(xmm15, Value);
   1085   }
   1086 
   1087 #undef TestMovd
   1088 }
   1089 
   1090 TEST_F(AssemblerX8664Test, MovqXmmXmm) {
   1091 #define TestMovd(Src, Dst, Value)                                              \
   1092   do {                                                                         \
   1093     static constexpr char TestString[] = "(" #Src ", " #Dst ")";               \
   1094     const uint32_t T0 = allocateQword();                                       \
   1095     const uint64_t V0 = Value;                                                 \
   1096     const uint32_t T1 = allocateQword();                                       \
   1097     const uint64_t V1 = ~(Value);                                              \
   1098                                                                                \
   1099     __ movq(Encoded_Xmm_##Src(), dwordAddress(T0));                            \
   1100     __ movq(Encoded_Xmm_##Dst(), dwordAddress(T1));                            \
   1101     __ movq(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src());                         \
   1102                                                                                \
   1103     AssembledTest test = assemble();                                           \
   1104                                                                                \
   1105     test.setQwordTo(T0, V0);                                                   \
   1106     test.setQwordTo(T1, V1);                                                   \
   1107     test.run();                                                                \
   1108                                                                                \
   1109     ASSERT_EQ(Value, test.Dst<uint64_t>()) << TestString << " value is "       \
   1110                                            << Value;                           \
   1111     reset();                                                                   \
   1112   } while (0)
   1113 
   1114   for (uint32_t Value : {0u, 1u, 0x7FFFFFFFu, 0x80000000u, 0xFFFFFFFFu}) {
   1115     TestMovd(xmm0, xmm1, Value);
   1116     TestMovd(xmm1, xmm2, Value);
   1117     TestMovd(xmm2, xmm3, Value);
   1118     TestMovd(xmm3, xmm4, Value);
   1119     TestMovd(xmm4, xmm5, Value);
   1120     TestMovd(xmm5, xmm6, Value);
   1121     TestMovd(xmm6, xmm7, Value);
   1122     TestMovd(xmm7, xmm8, Value);
   1123     TestMovd(xmm8, xmm9, Value);
   1124     TestMovd(xmm9, xmm10, Value);
   1125     TestMovd(xmm10, xmm11, Value);
   1126     TestMovd(xmm11, xmm12, Value);
   1127     TestMovd(xmm12, xmm13, Value);
   1128     TestMovd(xmm13, xmm14, Value);
   1129     TestMovd(xmm14, xmm15, Value);
   1130     TestMovd(xmm15, xmm0, Value);
   1131   }
   1132 
   1133 #undef TestMovd
   1134 }
   1135 
   1136 TEST_F(AssemblerX8664Test, MovupsXmmAddr) {
   1137 #define TestMovups(Dst)                                                        \
   1138   do {                                                                         \
   1139     static constexpr char TestString[] = "(" #Dst ")";                         \
   1140     const uint32_t T0 = allocateDqword();                                      \
   1141     const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(),       \
   1142                     std::numeric_limits<float>::infinity());                   \
   1143                                                                                \
   1144     __ movups(Encoded_Xmm_##Dst(), dwordAddress(T0));                          \
   1145                                                                                \
   1146     AssembledTest test = assemble();                                           \
   1147     test.setDqwordTo(T0, V0);                                                  \
   1148     test.run();                                                                \
   1149                                                                                \
   1150     ASSERT_EQ(V0, test.Dst<Dqword>()) << TestString;                           \
   1151     reset();                                                                   \
   1152   } while (0)
   1153 
   1154   TestMovups(xmm0);
   1155   TestMovups(xmm1);
   1156   TestMovups(xmm2);
   1157   TestMovups(xmm3);
   1158   TestMovups(xmm4);
   1159   TestMovups(xmm5);
   1160   TestMovups(xmm6);
   1161   TestMovups(xmm7);
   1162   TestMovups(xmm8);
   1163   TestMovups(xmm9);
   1164   TestMovups(xmm10);
   1165   TestMovups(xmm11);
   1166   TestMovups(xmm12);
   1167   TestMovups(xmm13);
   1168   TestMovups(xmm14);
   1169   TestMovups(xmm15);
   1170 
   1171 #undef TestMovups
   1172 }
   1173 
   1174 TEST_F(AssemblerX8664Test, MovupsAddrXmm) {
   1175 #define TestMovups(Src)                                                        \
   1176   do {                                                                         \
   1177     static constexpr char TestString[] = "(" #Src ")";                         \
   1178     const uint32_t T0 = allocateDqword();                                      \
   1179     const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(),       \
   1180                     std::numeric_limits<float>::infinity());                   \
   1181     const uint32_t T1 = allocateDqword();                                      \
   1182     const Dqword V1(0.0, 0.0, 0.0, 0.0);                                       \
   1183                                                                                \
   1184     __ movups(Encoded_Xmm_##Src(), dwordAddress(T0));                          \
   1185     __ movups(dwordAddress(T1), Encoded_Xmm_##Src());                          \
   1186                                                                                \
   1187     AssembledTest test = assemble();                                           \
   1188     test.setDqwordTo(T0, V0);                                                  \
   1189     test.setDqwordTo(T1, V1);                                                  \
   1190     test.run();                                                                \
   1191                                                                                \
   1192     ASSERT_EQ(V0, test.contentsOfDqword(T1)) << TestString;                    \
   1193     reset();                                                                   \
   1194   } while (0)
   1195 
   1196   TestMovups(xmm0);
   1197   TestMovups(xmm1);
   1198   TestMovups(xmm2);
   1199   TestMovups(xmm3);
   1200   TestMovups(xmm4);
   1201   TestMovups(xmm5);
   1202   TestMovups(xmm6);
   1203   TestMovups(xmm7);
   1204   TestMovups(xmm8);
   1205   TestMovups(xmm9);
   1206   TestMovups(xmm10);
   1207   TestMovups(xmm11);
   1208   TestMovups(xmm12);
   1209   TestMovups(xmm13);
   1210   TestMovups(xmm14);
   1211   TestMovups(xmm15);
   1212 
   1213 #undef TestMovups
   1214 }
   1215 
   1216 TEST_F(AssemblerX8664Test, MovupsXmmXmm) {
   1217 #define TestMovups(Dst, Src)                                                   \
   1218   do {                                                                         \
   1219     static constexpr char TestString[] = "(" #Dst ", " #Src ")";               \
   1220     const uint32_t T0 = allocateDqword();                                      \
   1221     const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(),       \
   1222                     std::numeric_limits<float>::infinity());                   \
   1223     const uint32_t T1 = allocateDqword();                                      \
   1224     const Dqword V1(0.0, 0.0, 0.0, 0.0);                                       \
   1225                                                                                \
   1226     __ movups(Encoded_Xmm_##Src(), dwordAddress(T0));                          \
   1227     __ movups(Encoded_Xmm_##Dst(), dwordAddress(T1));                          \
   1228     __ movups(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src());                       \
   1229                                                                                \
   1230     AssembledTest test = assemble();                                           \
   1231     test.setDqwordTo(T0, V0);                                                  \
   1232     test.setDqwordTo(T1, V1);                                                  \
   1233     test.run();                                                                \
   1234                                                                                \
   1235     ASSERT_EQ(V0, test.Dst<Dqword>()) << TestString;                           \
   1236     reset();                                                                   \
   1237   } while (0)
   1238 
   1239   TestMovups(xmm0, xmm1);
   1240   TestMovups(xmm1, xmm2);
   1241   TestMovups(xmm2, xmm3);
   1242   TestMovups(xmm3, xmm4);
   1243   TestMovups(xmm4, xmm5);
   1244   TestMovups(xmm5, xmm6);
   1245   TestMovups(xmm6, xmm7);
   1246   TestMovups(xmm7, xmm8);
   1247   TestMovups(xmm8, xmm9);
   1248   TestMovups(xmm9, xmm10);
   1249   TestMovups(xmm10, xmm11);
   1250   TestMovups(xmm11, xmm12);
   1251   TestMovups(xmm12, xmm13);
   1252   TestMovups(xmm13, xmm14);
   1253   TestMovups(xmm14, xmm15);
   1254   TestMovups(xmm15, xmm0);
   1255 
   1256 #undef TestMovups
   1257 }
   1258 
   1259 TEST_F(AssemblerX8664Test, MovapsXmmXmm) {
   1260 #define TestMovaps(Dst, Src)                                                   \
   1261   do {                                                                         \
   1262     static constexpr char TestString[] = "(" #Dst ", " #Src ")";               \
   1263     const uint32_t T0 = allocateDqword();                                      \
   1264     const Dqword V0(1.0f, -1.0, std::numeric_limits<float>::quiet_NaN(),       \
   1265                     std::numeric_limits<float>::infinity());                   \
   1266     const uint32_t T1 = allocateDqword();                                      \
   1267     const Dqword V1(0.0, 0.0, 0.0, 0.0);                                       \
   1268                                                                                \
   1269     __ movups(Encoded_Xmm_##Src(), dwordAddress(T0));                          \
   1270     __ movups(Encoded_Xmm_##Dst(), dwordAddress(T1));                          \
   1271     __ movaps(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src());                       \
   1272                                                                                \
   1273     AssembledTest test = assemble();                                           \
   1274     test.setDqwordTo(T0, V0);                                                  \
   1275     test.setDqwordTo(T1, V1);                                                  \
   1276     test.run();                                                                \
   1277                                                                                \
   1278     ASSERT_EQ(V0, test.Dst<Dqword>()) << TestString;                           \
   1279     reset();                                                                   \
   1280   } while (0)
   1281 
   1282   TestMovaps(xmm0, xmm1);
   1283   TestMovaps(xmm1, xmm2);
   1284   TestMovaps(xmm2, xmm3);
   1285   TestMovaps(xmm3, xmm4);
   1286   TestMovaps(xmm4, xmm5);
   1287   TestMovaps(xmm5, xmm6);
   1288   TestMovaps(xmm6, xmm7);
   1289   TestMovaps(xmm7, xmm8);
   1290   TestMovaps(xmm8, xmm9);
   1291   TestMovaps(xmm9, xmm10);
   1292   TestMovaps(xmm10, xmm11);
   1293   TestMovaps(xmm11, xmm12);
   1294   TestMovaps(xmm12, xmm13);
   1295   TestMovaps(xmm13, xmm14);
   1296   TestMovaps(xmm14, xmm15);
   1297   TestMovaps(xmm15, xmm0);
   1298 
   1299 #undef TestMovaps
   1300 }
   1301 
   1302 TEST_F(AssemblerX8664Test, Movhlps_Movlhps) {
   1303 #define TestImplSingle(Dst, Src, Inst, Expect)                                 \
   1304   do {                                                                         \
   1305     static constexpr char TestString[] = "(" #Dst ", " #Src ", " #Inst ")";    \
   1306     const uint32_t T0 = allocateDqword();                                      \
   1307     const Dqword V0(uint64_t(0xAAAAAAAABBBBBBBBull),                           \
   1308                     uint64_t(0xCCCCCCCCDDDDDDDDull));                          \
   1309     const uint32_t T1 = allocateDqword();                                      \
   1310     const Dqword V1(uint64_t(0xEEEEEEEEFFFFFFFFull),                           \
   1311                     uint64_t(0x9999999988888888ull));                          \
   1312                                                                                \
   1313     __ movups(Encoded_Xmm_##Dst(), dwordAddress(T0));                          \
   1314     __ movups(Encoded_Xmm_##Src(), dwordAddress(T1));                          \
   1315     __ Inst(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src());                         \
   1316                                                                                \
   1317     AssembledTest test = assemble();                                           \
   1318     test.setDqwordTo(T0, V0);                                                  \
   1319     test.setDqwordTo(T1, V1);                                                  \
   1320     test.run();                                                                \
   1321                                                                                \
   1322     ASSERT_EQ(Dqword Expect, test.Dst<Dqword>()) << TestString;                \
   1323     reset();                                                                   \
   1324   } while (0)
   1325 
   1326 #define TestImpl(Dst, Src)                                                     \
   1327   do {                                                                         \
   1328     TestImplSingle(Dst, Src, movhlps, (uint64_t(0x9999999988888888ull),        \
   1329                                        uint64_t(0xCCCCCCCCDDDDDDDDull)));      \
   1330     TestImplSingle(Dst, Src, movlhps, (uint64_t(0xAAAAAAAABBBBBBBBull),        \
   1331                                        uint64_t(0xEEEEEEEEFFFFFFFFull)));      \
   1332   } while (0)
   1333 
   1334   TestImpl(xmm0, xmm1);
   1335   TestImpl(xmm1, xmm2);
   1336   TestImpl(xmm2, xmm3);
   1337   TestImpl(xmm3, xmm4);
   1338   TestImpl(xmm4, xmm5);
   1339   TestImpl(xmm5, xmm6);
   1340   TestImpl(xmm6, xmm7);
   1341   TestImpl(xmm7, xmm8);
   1342   TestImpl(xmm8, xmm9);
   1343   TestImpl(xmm9, xmm10);
   1344   TestImpl(xmm10, xmm11);
   1345   TestImpl(xmm11, xmm12);
   1346   TestImpl(xmm12, xmm13);
   1347   TestImpl(xmm13, xmm14);
   1348   TestImpl(xmm14, xmm15);
   1349   TestImpl(xmm15, xmm0);
   1350 
   1351 #undef TestImpl
   1352 #undef TestImplSingle
   1353 }
   1354 
   1355 TEST_F(AssemblerX8664Test, Movmsk) {
   1356 #define TestMovmskGPRXmm(GPR, Src, Value1, Expected, Inst)                     \
   1357   do {                                                                         \
   1358     static constexpr char TestString[] =                                       \
   1359         "(" #GPR ", " #Src ", " #Value1 ", " #Expected ", " #Inst ")";         \
   1360     const uint32_t T0 = allocateDqword();                                      \
   1361     const Dqword V0 Value1;                                                    \
   1362                                                                                \
   1363     __ movups(Encoded_Xmm_##Src(), dwordAddress(T0));                          \
   1364     __ Inst(IceType_v4f32, Encoded_GPR_##GPR(), Encoded_Xmm_##Src());          \
   1365                                                                                \
   1366     AssembledTest test = assemble();                                           \
   1367     test.setDqwordTo(T0, V0);                                                  \
   1368     test.run();                                                                \
   1369                                                                                \
   1370     ASSERT_EQ(Expected, test.GPR()) << TestString;                             \
   1371     reset();                                                                   \
   1372   } while (0)
   1373 
   1374 #define TestMovmsk(GPR, Src)                                                   \
   1375   do {                                                                         \
   1376     TestMovmskGPRXmm(GPR, Src, (-1.0, 1.0, -1.0, 1.0), 0x05ul, movmsk);        \
   1377   } while (0)
   1378 
   1379   TestMovmsk(r1, xmm0);
   1380   TestMovmsk(r2, xmm1);
   1381   TestMovmsk(r3, xmm2);
   1382   TestMovmsk(r4, xmm3);
   1383   TestMovmsk(r5, xmm4);
   1384   TestMovmsk(r6, xmm5);
   1385   TestMovmsk(r7, xmm6);
   1386   TestMovmsk(r8, xmm7);
   1387   TestMovmsk(r10, xmm8);
   1388   TestMovmsk(r11, xmm9);
   1389   TestMovmsk(r12, xmm10);
   1390   TestMovmsk(r13, xmm11);
   1391   TestMovmsk(r14, xmm12);
   1392   TestMovmsk(r15, xmm13);
   1393   TestMovmsk(r1, xmm14);
   1394   TestMovmsk(r2, xmm15);
   1395 
   1396 #undef TestMovmskGPRXmm
   1397 #undef TestMovmsk
   1398 }
   1399 
   1400 TEST_F(AssemblerX8664Test, Pmovsxdq) {
   1401 #define TestPmovsxdqXmmXmm(Dst, Src, Value1)                                   \
   1402   do {                                                                         \
   1403     static constexpr char TestString[] = "(" #Dst ", " #Src ", " #Value1 ")";  \
   1404     const uint32_t T0 = allocateDqword();                                      \
   1405     const Dqword V0 Value1;                                                    \
   1406     const uint32_t T1 = allocateDqword();                                      \
   1407     const Dqword V1(uint64_t(0), uint64_t(0));                                 \
   1408                                                                                \
   1409     __ movups(Encoded_Xmm_##Src(), dwordAddress(T0));                          \
   1410     __ movups(Encoded_Xmm_##Dst(), dwordAddress(T1));                          \
   1411     __ pmovsxdq(Encoded_Xmm_##Dst(), Encoded_Xmm_##Src());                     \
   1412                                                                                \
   1413     AssembledTest test = assemble();                                           \
   1414     test.setDqwordTo(T0, V0);                                                  \
   1415     test.setDqwordTo(T1, V1);                                                  \
   1416     test.run();                                                                \
   1417                                                                                \
   1418     const Dqword Expected(uint64_t(V0.I32[0]), uint64_t(V0.I32[1]));           \
   1419     ASSERT_EQ(Expected, test.Dst<Dqword>()) << TestString;                     \
   1420     reset();                                                                   \
   1421   } while (0)
   1422 
   1423 #define TestPmovsxdq(Dst, Src)                                                 \
   1424   do {                                                                         \
   1425     TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x700000007FFFFFFFull),             \
   1426                                   uint64_t(0xAAAAAAAAEEEEEEEEull)));           \
   1427     TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x800000007FFFFFFFull),             \
   1428                                   uint64_t(0xAAAAAAAAEEEEEEEEull)));           \
   1429     TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x70000000FFFFFFFFull),             \
   1430                                   uint64_t(0xAAAAAAAAEEEEEEEEull)));           \
   1431     TestPmovsxdqXmmXmm(Dst, Src, (uint64_t(0x80000000FFFFFFFFull),             \
   1432                                   uint64_t(0xAAAAAAAAEEEEEEEEull)));           \
   1433   } while (0)
   1434 
   1435   TestPmovsxdq(xmm0, xmm1);
   1436   TestPmovsxdq(xmm1, xmm2);
   1437   TestPmovsxdq(xmm2, xmm3);
   1438   TestPmovsxdq(xmm3, xmm4);
   1439   TestPmovsxdq(xmm4, xmm5);
   1440   TestPmovsxdq(xmm5, xmm6);
   1441   TestPmovsxdq(xmm6, xmm7);
   1442   TestPmovsxdq(xmm7, xmm8);
   1443   TestPmovsxdq(xmm8, xmm9);
   1444   TestPmovsxdq(xmm9, xmm10);
   1445   TestPmovsxdq(xmm10, xmm11);
   1446   TestPmovsxdq(xmm11, xmm12);
   1447   TestPmovsxdq(xmm12, xmm13);
   1448   TestPmovsxdq(xmm13, xmm14);
   1449   TestPmovsxdq(xmm14, xmm15);
   1450   TestPmovsxdq(xmm15, xmm0);
   1451 
   1452 #undef TestPmovsxdq
   1453 #undef TestPmovsxdqXmmXmm
   1454 }
   1455 
   1456 } // end of anonymous namespace
   1457 } // end of namespace Test
   1458 } // end of namespace X8664
   1459 } // end of namespace Ice
   1460