Home | History | Annotate | Download | only in AssemblerX8632
      1 //===- subzero/unittest/AssemblerX8632/X87.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 "AssemblerX8632/TestUtil.h"
     10 
     11 namespace Ice {
     12 namespace X8632 {
     13 namespace Test {
     14 namespace {
     15 
     16 TEST_F(AssemblerX8632LowLevelTest, Fld) {
     17   __ fld(IceType_f32,
     18          Address(GPRRegister::Encoded_Reg_ebp, 1, AssemblerFixup::NoFixup));
     19   __ fld(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000,
     20                               AssemblerFixup::NoFixup));
     21 
     22   constexpr size_t ByteCount = 9;
     23   ASSERT_EQ(ByteCount, codeBytesSize());
     24 
     25   constexpr uint8_t Fld32Opcode = 0xd9;
     26   constexpr uint8_t Fld32ModRM = (/*mod*/ 1 << 6) | (/*reg*/ 0 << 3) |
     27                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
     28   constexpr uint8_t Fld64Opcode = 0xdd;
     29   constexpr uint8_t Fld64ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 0 << 3) |
     30                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
     31   verifyBytes<ByteCount>(codeBytes(), Fld32Opcode, Fld32ModRM, 0x01,
     32                          Fld64Opcode, Fld64ModRM, 0x00, 0x00, 0x01, 0x00);
     33 }
     34 
     35 TEST_F(AssemblerX8632LowLevelTest, FstpAddr) {
     36   __ fstp(IceType_f32,
     37           Address(GPRRegister::Encoded_Reg_ebp, 1, AssemblerFixup::NoFixup));
     38   __ fstp(IceType_f64, Address(GPRRegister::Encoded_Reg_ebp, 0x10000,
     39                                AssemblerFixup::NoFixup));
     40 
     41   constexpr size_t ByteCount = 9;
     42   ASSERT_EQ(ByteCount, codeBytesSize());
     43 
     44   constexpr uint8_t Fld32Opcode = 0xd9;
     45   constexpr uint8_t Fld32ModRM = (/*mod*/ 1 << 6) | (/*reg*/ 3 << 3) |
     46                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
     47   constexpr uint8_t Fld64Opcode = 0xdd;
     48   constexpr uint8_t Fld64ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 3 << 3) |
     49                                  (/*rm*/ GPRRegister::Encoded_Reg_ebp);
     50   verifyBytes<ByteCount>(codeBytes(), Fld32Opcode, Fld32ModRM, 0x01,
     51                          Fld64Opcode, Fld64ModRM, 0x00, 0x00, 0x01, 0x00);
     52 }
     53 
     54 TEST_F(AssemblerX8632LowLevelTest, Fincstp) {
     55   __ fincstp();
     56 
     57   constexpr size_t ByteCount = 2;
     58   ASSERT_EQ(ByteCount, codeBytesSize());
     59 
     60   verifyBytes<ByteCount>(codeBytes(), 0xD9, 0XF7);
     61 }
     62 
     63 TEST_F(AssemblerX8632LowLevelTest, FnstcwAddr) {
     64   __ fnstcw(
     65       Address(GPRRegister::Encoded_Reg_ebp, 0x12345, AssemblerFixup::NoFixup));
     66 
     67   constexpr size_t ByteCount = 6;
     68   ASSERT_EQ(ByteCount, codeBytesSize());
     69 
     70   constexpr uint8_t Opcode = 0xd9;
     71   constexpr uint8_t ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 7 << 3) |
     72                             (/*rm*/ GPRRegister::Encoded_Reg_ebp);
     73   verifyBytes<ByteCount>(codeBytes(), Opcode, ModRM, 0x45, 0x23, 0x01, 0x00);
     74 }
     75 
     76 TEST_F(AssemblerX8632LowLevelTest, FldcwAddr) {
     77   __ fldcw(
     78       Address(GPRRegister::Encoded_Reg_ebp, 0x12345, AssemblerFixup::NoFixup));
     79 
     80   constexpr size_t ByteCount = 6;
     81   ASSERT_EQ(ByteCount, codeBytesSize());
     82 
     83   constexpr uint8_t Opcode = 0xd9;
     84   constexpr uint8_t ModRM = (/*mod*/ 2 << 6) | (/*reg*/ 5 << 3) |
     85                             (/*rm*/ GPRRegister::Encoded_Reg_ebp);
     86   verifyBytes<ByteCount>(codeBytes(), Opcode, ModRM, 0x45, 0x23, 0x01, 0x00);
     87 }
     88 
     89 TEST_F(AssemblerX8632Test, FstpSt) {
     90 #define TestFstpSt(Size, MemorySize, Type)                                     \
     91   do {                                                                         \
     92     const uint32_t T1 = allocate##MemorySize();                                \
     93     const Type OldValue1 = -1.0f;                                              \
     94     const uint32_t T2 = allocate##MemorySize();                                \
     95     const Type OldValue2 = -2.0f;                                              \
     96     const uint32_t T3 = allocate##MemorySize();                                \
     97     const Type OldValue3 = -3.0f;                                              \
     98     const uint32_t T4 = allocate##MemorySize();                                \
     99     const Type OldValue4 = -4.0f;                                              \
    100     const uint32_t T5 = allocate##MemorySize();                                \
    101     const Type OldValue5 = -5.0f;                                              \
    102     const uint32_t T6 = allocate##MemorySize();                                \
    103     const Type OldValue6 = -6.0f;                                              \
    104     const uint32_t T7 = allocate##MemorySize();                                \
    105     const Type OldValue7 = -7.0f;                                              \
    106                                                                                \
    107     const uint32_t N7 = allocate##MemorySize();                                \
    108     constexpr Type NewValue7 = 777.77f;                                        \
    109     const uint32_t N6 = allocate##MemorySize();                                \
    110     constexpr Type NewValue6 = 666.66f;                                        \
    111     const uint32_t N5 = allocate##MemorySize();                                \
    112     constexpr Type NewValue5 = 555.55f;                                        \
    113     const uint32_t N4 = allocate##MemorySize();                                \
    114     constexpr Type NewValue4 = 444.44f;                                        \
    115     const uint32_t N3 = allocate##MemorySize();                                \
    116     constexpr Type NewValue3 = 333.33f;                                        \
    117     const uint32_t N2 = allocate##MemorySize();                                \
    118     constexpr Type NewValue2 = 222.22f;                                        \
    119     const uint32_t N1 = allocate##MemorySize();                                \
    120     constexpr Type NewValue1 = 111.11f;                                        \
    121                                                                                \
    122     __ fincstp();                                                              \
    123     __ fincstp();                                                              \
    124     __ fincstp();                                                              \
    125     __ fincstp();                                                              \
    126     __ fincstp();                                                              \
    127     __ fincstp();                                                              \
    128     __ fincstp();                                                              \
    129                                                                                \
    130     __ fld(IceType_f##Size, dwordAddress(N7));                                 \
    131     __ fstp(X87STRegister::Encoded_X87ST_7);                                   \
    132     __ fld(IceType_f##Size, dwordAddress(N6));                                 \
    133     __ fstp(X87STRegister::Encoded_X87ST_6);                                   \
    134     __ fld(IceType_f##Size, dwordAddress(N5));                                 \
    135     __ fstp(X87STRegister::Encoded_X87ST_5);                                   \
    136     __ fld(IceType_f##Size, dwordAddress(N4));                                 \
    137     __ fstp(X87STRegister::Encoded_X87ST_4);                                   \
    138     __ fld(IceType_f##Size, dwordAddress(N3));                                 \
    139     __ fstp(X87STRegister::Encoded_X87ST_3);                                   \
    140     __ fld(IceType_f##Size, dwordAddress(N2));                                 \
    141     __ fstp(X87STRegister::Encoded_X87ST_2);                                   \
    142     __ fld(IceType_f##Size, dwordAddress(N1));                                 \
    143     __ fstp(X87STRegister::Encoded_X87ST_1);                                   \
    144                                                                                \
    145     __ fstp(IceType_f##Size, dwordAddress(T1));                                \
    146     __ fstp(IceType_f##Size, dwordAddress(T2));                                \
    147     __ fstp(IceType_f##Size, dwordAddress(T3));                                \
    148     __ fstp(IceType_f##Size, dwordAddress(T4));                                \
    149     __ fstp(IceType_f##Size, dwordAddress(T5));                                \
    150     __ fstp(IceType_f##Size, dwordAddress(T6));                                \
    151     __ fstp(IceType_f##Size, dwordAddress(T7));                                \
    152                                                                                \
    153     AssembledTest test = assemble();                                           \
    154     test.set##MemorySize##To(T1, OldValue1);                                   \
    155     test.set##MemorySize##To(N1, NewValue1);                                   \
    156     test.set##MemorySize##To(T2, OldValue2);                                   \
    157     test.set##MemorySize##To(N2, NewValue2);                                   \
    158     test.set##MemorySize##To(T3, OldValue3);                                   \
    159     test.set##MemorySize##To(N3, NewValue3);                                   \
    160     test.set##MemorySize##To(T4, OldValue4);                                   \
    161     test.set##MemorySize##To(N4, NewValue4);                                   \
    162     test.set##MemorySize##To(T5, OldValue5);                                   \
    163     test.set##MemorySize##To(N5, NewValue5);                                   \
    164     test.set##MemorySize##To(T6, OldValue6);                                   \
    165     test.set##MemorySize##To(N6, NewValue6);                                   \
    166     test.set##MemorySize##To(T7, OldValue7);                                   \
    167     test.set##MemorySize##To(N7, NewValue7);                                   \
    168                                                                                \
    169     test.run();                                                                \
    170                                                                                \
    171     ASSERT_FLOAT_EQ(NewValue1, test.contentsOf##MemorySize<Type>(T1))          \
    172         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    173     ASSERT_FLOAT_EQ(NewValue1, test.contentsOf##MemorySize<Type>(N1))          \
    174         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    175     ASSERT_FLOAT_EQ(NewValue2, test.contentsOf##MemorySize<Type>(T2))          \
    176         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    177     ASSERT_FLOAT_EQ(NewValue2, test.contentsOf##MemorySize<Type>(N2))          \
    178         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    179     ASSERT_FLOAT_EQ(NewValue3, test.contentsOf##MemorySize<Type>(T3))          \
    180         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    181     ASSERT_FLOAT_EQ(NewValue3, test.contentsOf##MemorySize<Type>(N3))          \
    182         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    183     ASSERT_FLOAT_EQ(NewValue4, test.contentsOf##MemorySize<Type>(T4))          \
    184         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    185     ASSERT_FLOAT_EQ(NewValue4, test.contentsOf##MemorySize<Type>(N4))          \
    186         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    187     ASSERT_FLOAT_EQ(NewValue5, test.contentsOf##MemorySize<Type>(T5))          \
    188         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    189     ASSERT_FLOAT_EQ(NewValue5, test.contentsOf##MemorySize<Type>(N5))          \
    190         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    191     ASSERT_FLOAT_EQ(NewValue6, test.contentsOf##MemorySize<Type>(T6))          \
    192         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    193     ASSERT_FLOAT_EQ(NewValue6, test.contentsOf##MemorySize<Type>(N6))          \
    194         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    195     ASSERT_FLOAT_EQ(NewValue7, test.contentsOf##MemorySize<Type>(T7))          \
    196         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    197     ASSERT_FLOAT_EQ(NewValue7, test.contentsOf##MemorySize<Type>(N7))          \
    198         << "(" #Size ", " #MemorySize ", " #Type ")";                          \
    199                                                                                \
    200     reset();                                                                   \
    201   } while (0)
    202 
    203   TestFstpSt(32, Dword, float);
    204   TestFstpSt(64, Qword, double);
    205 
    206 #undef TestFstpSt
    207 }
    208 
    209 TEST_F(AssemblerX8632Test, Fild) {
    210 #define TestFild(OperandType, Size, MemorySize, FpType, IntType)               \
    211   do {                                                                         \
    212     const uint32_t T0 = allocate##MemorySize();                                \
    213     constexpr IntType V0 = 0x1234;                                             \
    214                                                                                \
    215     __ fild##OperandType(dwordAddress(T0));                                    \
    216     __ fstp(IceType_f##Size, dwordAddress(T0));                                \
    217                                                                                \
    218     AssembledTest test = assemble();                                           \
    219                                                                                \
    220     test.set##MemorySize##To(T0, V0);                                          \
    221     test.run();                                                                \
    222                                                                                \
    223     ASSERT_FLOAT_EQ(static_cast<FpType>(V0),                                   \
    224                     test.contentsOf##MemorySize<FpType>(T0))                   \
    225         << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType           \
    226            ", " #IntType ")";                                                  \
    227                                                                                \
    228     reset();                                                                   \
    229   } while (0)
    230 
    231   TestFild(s, 32, Dword, float, uint32_t);
    232   TestFild(l, 64, Qword, double, uint64_t);
    233 #undef TestFild
    234 }
    235 
    236 TEST_F(AssemblerX8632Test, Fistp) {
    237 #define TestFistp(OperandType, Size, MemorySize, FpType, IntType)              \
    238   do {                                                                         \
    239     const uint32_t T0 = allocate##MemorySize();                                \
    240     constexpr IntType V0 = 0x1234;                                             \
    241     const uint32_t T1 = allocate##MemorySize();                                \
    242     constexpr IntType V1 = 0xFFFF;                                             \
    243                                                                                \
    244     __ fild##OperandType(dwordAddress(T0));                                    \
    245     __ fistp##OperandType(dwordAddress(T1));                                   \
    246                                                                                \
    247     AssembledTest test = assemble();                                           \
    248                                                                                \
    249     test.set##MemorySize##To(T0, V0);                                          \
    250     test.set##MemorySize##To(T1, V1);                                          \
    251     test.run();                                                                \
    252                                                                                \
    253     ASSERT_EQ(static_cast<IntType>(V0),                                        \
    254               test.contentsOf##MemorySize<IntType>(T0))                        \
    255         << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType           \
    256            ", " #IntType ")";                                                  \
    257     ASSERT_EQ(static_cast<IntType>(V0),                                        \
    258               test.contentsOf##MemorySize<IntType>(T1))                        \
    259         << "(" #OperandType ", " #Size ", " #MemorySize ", " #FpType           \
    260            ", " #IntType ")";                                                  \
    261                                                                                \
    262     reset();                                                                   \
    263   } while (0)
    264 
    265   TestFistp(s, 32, Dword, float, uint32_t);
    266   TestFistp(l, 64, Qword, double, uint64_t);
    267 #undef TestFistp
    268 }
    269 
    270 } // end of anonymous namespace
    271 } // end of namespace Test
    272 } // end of namespace X8632
    273 } // end of namespace Ice
    274