| OLD | NEW |
| 1 //===- subzero/unittest/AssemblerX8664/GPRArith.cpp -----------------------===// | 1 //===- subzero/unittest/AssemblerX8664/GPRArith.cpp -----------------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 #include "AssemblerX8664/TestUtil.h" | 9 #include "AssemblerX8664/TestUtil.h" |
| 10 | 10 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 105 |
| 106 #undef TestImpl | 106 #undef TestImpl |
| 107 #undef TestSetCC | 107 #undef TestSetCC |
| 108 } | 108 } |
| 109 | 109 |
| 110 TEST_F(AssemblerX8664Test, Lea) { | 110 TEST_F(AssemblerX8664Test, Lea) { |
| 111 #define TestLeaBaseDisp(Base, BaseValue, Disp, Dst) \ | 111 #define TestLeaBaseDisp(Base, BaseValue, Disp, Dst) \ |
| 112 do { \ | 112 do { \ |
| 113 static constexpr char TestString[] = \ | 113 static constexpr char TestString[] = \ |
| 114 "(" #Base ", " #BaseValue ", " #Dst ")"; \ | 114 "(" #Base ", " #BaseValue ", " #Dst ")"; \ |
| 115 static constexpr AssemblerFixup *Fixup = nullptr; \ |
| 115 if (Encoded_GPR_##Base() != Encoded_GPR_esp() && \ | 116 if (Encoded_GPR_##Base() != Encoded_GPR_esp() && \ |
| 116 Encoded_GPR_##Base() != Encoded_GPR_r9()) { \ | 117 Encoded_GPR_##Base() != Encoded_GPR_r9()) { \ |
| 117 __ mov(IceType_i32, Encoded_GPR_##Base(), Immediate(BaseValue)); \ | 118 __ mov(IceType_i32, Encoded_GPR_##Base(), Immediate(BaseValue)); \ |
| 118 } \ | 119 } \ |
| 119 __ lea(IceType_i32, Encoded_GPR_##Dst(), \ | 120 __ lea(IceType_i32, Encoded_GPR_##Dst(), \ |
| 120 Address(Encoded_GPR_##Base(), Disp)); \ | 121 Address(Encoded_GPR_##Base(), Disp, Fixup)); \ |
| 121 AssembledTest test = assemble(); \ | 122 AssembledTest test = assemble(); \ |
| 122 test.run(); \ | 123 test.run(); \ |
| 123 ASSERT_EQ(test.Base##d() + (Disp), test.Dst##d()) \ | 124 ASSERT_EQ(test.Base##d() + (Disp), test.Dst##d()) \ |
| 124 << TestString << " with Disp " << Disp; \ | 125 << TestString << " with Disp " << Disp; \ |
| 125 reset(); \ | 126 reset(); \ |
| 126 } while (0) | 127 } while (0) |
| 127 | 128 |
| 128 #define TestLeaIndex32bitDisp(Index, IndexValue, Disp, Dst0, Dst1, Dst2, Dst3) \ | 129 #define TestLeaIndex32bitDisp(Index, IndexValue, Disp, Dst0, Dst1, Dst2, Dst3) \ |
| 129 do { \ | 130 do { \ |
| 130 static constexpr char TestString[] = \ | 131 static constexpr char TestString[] = \ |
| 131 "(" #Index ", " #IndexValue ", " #Dst0 ", " #Dst1 ", " #Dst2 \ | 132 "(" #Index ", " #IndexValue ", " #Dst0 ", " #Dst1 ", " #Dst2 \ |
| 132 ", " #Dst3 ")"; \ | 133 ", " #Dst3 ")"; \ |
| 134 static constexpr AssemblerFixup *Fixup = nullptr; \ |
| 133 if (Encoded_GPR_##Index() != Encoded_GPR_r9()) { \ | 135 if (Encoded_GPR_##Index() != Encoded_GPR_r9()) { \ |
| 134 __ mov(IceType_i32, Encoded_GPR_##Index(), Immediate(IndexValue)); \ | 136 __ mov(IceType_i32, Encoded_GPR_##Index(), Immediate(IndexValue)); \ |
| 135 } \ | 137 } \ |
| 136 __ lea(IceType_i32, Encoded_GPR_##Dst0(), \ | 138 __ lea(IceType_i32, Encoded_GPR_##Dst0(), \ |
| 137 Address(Encoded_GPR_##Index(), Traits::TIMES_1, Disp)); \ | 139 Address(Encoded_GPR_##Index(), Traits::TIMES_1, Disp, Fixup)); \ |
| 138 __ lea(IceType_i32, Encoded_GPR_##Dst1(), \ | 140 __ lea(IceType_i32, Encoded_GPR_##Dst1(), \ |
| 139 Address(Encoded_GPR_##Index(), Traits::TIMES_2, Disp)); \ | 141 Address(Encoded_GPR_##Index(), Traits::TIMES_2, Disp, Fixup)); \ |
| 140 __ lea(IceType_i32, Encoded_GPR_##Dst2(), \ | 142 __ lea(IceType_i32, Encoded_GPR_##Dst2(), \ |
| 141 Address(Encoded_GPR_##Index(), Traits::TIMES_4, Disp)); \ | 143 Address(Encoded_GPR_##Index(), Traits::TIMES_4, Disp, Fixup)); \ |
| 142 __ lea(IceType_i32, Encoded_GPR_##Dst3(), \ | 144 __ lea(IceType_i32, Encoded_GPR_##Dst3(), \ |
| 143 Address(Encoded_GPR_##Index(), Traits::TIMES_8, Disp)); \ | 145 Address(Encoded_GPR_##Index(), Traits::TIMES_8, Disp, Fixup)); \ |
| 144 AssembledTest test = assemble(); \ | 146 AssembledTest test = assemble(); \ |
| 145 test.run(); \ | 147 test.run(); \ |
| 146 ASSERT_EQ((test.Index##d() << Traits::TIMES_1) + (Disp), test.Dst0##d()) \ | 148 ASSERT_EQ((test.Index##d() << Traits::TIMES_1) + (Disp), test.Dst0##d()) \ |
| 147 << TestString << " " << Disp; \ | 149 << TestString << " " << Disp; \ |
| 148 ASSERT_EQ((test.Index##d() << Traits::TIMES_2) + (Disp), test.Dst1##d()) \ | 150 ASSERT_EQ((test.Index##d() << Traits::TIMES_2) + (Disp), test.Dst1##d()) \ |
| 149 << TestString << " " << Disp; \ | 151 << TestString << " " << Disp; \ |
| 150 ASSERT_EQ((test.Index##d() << Traits::TIMES_4) + (Disp), test.Dst2##d()) \ | 152 ASSERT_EQ((test.Index##d() << Traits::TIMES_4) + (Disp), test.Dst2##d()) \ |
| 151 << TestString << " " << Disp; \ | 153 << TestString << " " << Disp; \ |
| 152 ASSERT_EQ((test.Index##d() << Traits::TIMES_8) + (Disp), test.Dst3##d()) \ | 154 ASSERT_EQ((test.Index##d() << Traits::TIMES_8) + (Disp), test.Dst3##d()) \ |
| 153 << TestString << " " << Disp; \ | 155 << TestString << " " << Disp; \ |
| 154 reset(); \ | 156 reset(); \ |
| 155 } while (0) | 157 } while (0) |
| 156 | 158 |
| 157 #define TestLeaBaseIndexDisp(Base, BaseValue, Index, IndexValue, Disp, Dst0, \ | 159 #define TestLeaBaseIndexDisp(Base, BaseValue, Index, IndexValue, Disp, Dst0, \ |
| 158 Dst1, Dst2, Dst3) \ | 160 Dst1, Dst2, Dst3) \ |
| 159 do { \ | 161 do { \ |
| 160 static constexpr char TestString[] = \ | 162 static constexpr char TestString[] = \ |
| 161 "(" #Base ", " #BaseValue ", " #Index ", " #IndexValue ", " #Dst0 \ | 163 "(" #Base ", " #BaseValue ", " #Index ", " #IndexValue ", " #Dst0 \ |
| 162 ", " #Dst1 ", " #Dst2 ", " #Dst3 ")"; \ | 164 ", " #Dst1 ", " #Dst2 ", " #Dst3 ")"; \ |
| 165 static constexpr AssemblerFixup *Fixup = nullptr; \ |
| 163 if (Encoded_GPR_##Base() != Encoded_GPR_esp() && \ | 166 if (Encoded_GPR_##Base() != Encoded_GPR_esp() && \ |
| 164 Encoded_GPR_##Base() != Encoded_GPR_r9()) { \ | 167 Encoded_GPR_##Base() != Encoded_GPR_r9()) { \ |
| 165 __ mov(IceType_i32, Encoded_GPR_##Base(), Immediate(BaseValue)); \ | 168 __ mov(IceType_i32, Encoded_GPR_##Base(), Immediate(BaseValue)); \ |
| 166 } \ | 169 } \ |
| 167 \ | 170 \ |
| 168 if (Encoded_GPR_##Index() != Encoded_GPR_r9()) { \ | 171 if (Encoded_GPR_##Index() != Encoded_GPR_r9()) { \ |
| 169 __ mov(IceType_i32, Encoded_GPR_##Index(), Immediate(IndexValue)); \ | 172 __ mov(IceType_i32, Encoded_GPR_##Index(), Immediate(IndexValue)); \ |
| 170 } \ | 173 } \ |
| 171 \ | 174 \ |
| 172 __ lea(IceType_i32, Encoded_GPR_##Dst0(), \ | 175 __ lea(IceType_i32, Encoded_GPR_##Dst0(), \ |
| 173 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ | 176 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ |
| 174 Traits::TIMES_1, Disp)); \ | 177 Traits::TIMES_1, Disp, Fixup)); \ |
| 175 __ lea(IceType_i32, Encoded_GPR_##Dst1(), \ | 178 __ lea(IceType_i32, Encoded_GPR_##Dst1(), \ |
| 176 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ | 179 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ |
| 177 Traits::TIMES_2, Disp)); \ | 180 Traits::TIMES_2, Disp, Fixup)); \ |
| 178 __ lea(IceType_i32, Encoded_GPR_##Dst2(), \ | 181 __ lea(IceType_i32, Encoded_GPR_##Dst2(), \ |
| 179 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ | 182 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ |
| 180 Traits::TIMES_4, Disp)); \ | 183 Traits::TIMES_4, Disp, Fixup)); \ |
| 181 __ lea(IceType_i32, Encoded_GPR_##Dst3(), \ | 184 __ lea(IceType_i32, Encoded_GPR_##Dst3(), \ |
| 182 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ | 185 Address(Encoded_GPR_##Base(), Encoded_GPR_##Index(), \ |
| 183 Traits::TIMES_8, Disp)); \ | 186 Traits::TIMES_8, Disp, Fixup)); \ |
| 184 AssembledTest test = assemble(); \ | 187 AssembledTest test = assemble(); \ |
| 185 test.run(); \ | 188 test.run(); \ |
| 186 uint32_t ExpectedIndexValue = test.Index(); \ | 189 uint32_t ExpectedIndexValue = test.Index(); \ |
| 187 if (Encoded_GPR_##Index() == Encoded_GPR_esp()) { \ | 190 if (Encoded_GPR_##Index() == Encoded_GPR_esp()) { \ |
| 188 ExpectedIndexValue = 0; \ | 191 ExpectedIndexValue = 0; \ |
| 189 } \ | 192 } \ |
| 190 ASSERT_EQ(test.Base##d() + (ExpectedIndexValue << Traits::TIMES_1) + \ | 193 ASSERT_EQ(test.Base##d() + (ExpectedIndexValue << Traits::TIMES_1) + \ |
| 191 (Disp), \ | 194 (Disp), \ |
| 192 test.Dst0##d()) \ | 195 test.Dst0##d()) \ |
| 193 << TestString << " " << Disp; \ | 196 << TestString << " " << Disp; \ |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // by the assembler has different meanings in x86-32 and x86-64. | 318 // by the assembler has different meanings in x86-32 and x86-64. |
| 316 #undef TestLeaBaseIndexDisp | 319 #undef TestLeaBaseIndexDisp |
| 317 #undef TestLeaScaled32bitDisp | 320 #undef TestLeaScaled32bitDisp |
| 318 #undef TestLeaBaseDisp | 321 #undef TestLeaBaseDisp |
| 319 } | 322 } |
| 320 | 323 |
| 321 TEST_F(AssemblerX8664LowLevelTest, LeaAbsolute) { | 324 TEST_F(AssemblerX8664LowLevelTest, LeaAbsolute) { |
| 322 #define TestLeaAbsolute(Dst, Value) \ | 325 #define TestLeaAbsolute(Dst, Value) \ |
| 323 do { \ | 326 do { \ |
| 324 static constexpr char TestString[] = "(" #Dst ", " #Value ")"; \ | 327 static constexpr char TestString[] = "(" #Dst ", " #Value ")"; \ |
| 325 __ lea(IceType_i32, GPRRegister::Encoded_Reg_##Dst, \ | 328 static constexpr AssemblerFixup *Fixup = nullptr; \ |
| 326 Address(Address::ABSOLUTE, Value)); \ | 329 __ lea(IceType_i32, GPRRegister::Encoded_Reg_##Dst, Address(Value, Fixup));\ |
| 327 static constexpr uint32_t ByteCount = 6; \ | 330 static constexpr uint32_t ByteCount = 6; \ |
| 328 ASSERT_EQ(ByteCount, codeBytesSize()) << TestString; \ | 331 ASSERT_EQ(ByteCount, codeBytesSize()) << TestString; \ |
| 329 static constexpr uint8_t Opcode = 0x8D; \ | 332 static constexpr uint8_t Opcode = 0x8D; \ |
| 330 static constexpr uint8_t ModRM = \ | 333 static constexpr uint8_t ModRM = \ |
| 331 /*mod=*/0x00 | /*reg*/ (GPRRegister::Encoded_Reg_##Dst << 3) | \ | 334 /*mod=*/0x00 | /*reg*/ (GPRRegister::Encoded_Reg_##Dst << 3) | \ |
| 332 /*rm*/ GPRRegister::Encoded_Reg_ebp; \ | 335 /*rm*/ GPRRegister::Encoded_Reg_ebp; \ |
| 333 ASSERT_TRUE(verifyBytes<ByteCount>( \ | 336 ASSERT_TRUE(verifyBytes<ByteCount>( \ |
| 334 codeBytes(), Opcode, ModRM, (Value)&0xFF, (Value >> 8) & 0xFF, \ | 337 codeBytes(), Opcode, ModRM, (Value)&0xFF, (Value >> 8) & 0xFF, \ |
| 335 (Value >> 16) & 0xFF, (Value >> 24) & 0xFF)); \ | 338 (Value >> 16) & 0xFF, (Value >> 24) & 0xFF)); \ |
| 336 reset(); \ | 339 reset(); \ |
| (...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1896 #undef TestImplValue | 1899 #undef TestImplValue |
| 1897 #undef TestImplSize | 1900 #undef TestImplSize |
| 1898 #undef TestImplRegAddr | 1901 #undef TestImplRegAddr |
| 1899 #undef TestImplRegReg | 1902 #undef TestImplRegReg |
| 1900 } | 1903 } |
| 1901 | 1904 |
| 1902 } // end of anonymous namespace | 1905 } // end of anonymous namespace |
| 1903 } // end of namespace Test | 1906 } // end of namespace Test |
| 1904 } // end of namespace X8664 | 1907 } // end of namespace X8664 |
| 1905 } // end of namespace Ice | 1908 } // end of namespace Ice |
| OLD | NEW |