| OLD | NEW | 
|---|
| 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// | 1 //===- subzero/src/IceAssemblerX86BaseImpl.h - base x86 assembler -*- C++ -*-=// | 
| 2 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 2 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
| 3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a | 
| 4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. | 
| 5 // | 5 // | 
| 6 // Modified by the Subzero authors. | 6 // Modified by the Subzero authors. | 
| 7 // | 7 // | 
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// | 
| 9 // | 9 // | 
| 10 //                        The Subzero Code Generator | 10 //                        The Subzero Code Generator | 
| (...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1061     emitUint8(0x73); | 1061     emitUint8(0x73); | 
| 1062   } else { | 1062   } else { | 
| 1063     assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); | 1063     assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); | 
| 1064     emitUint8(0x72); | 1064     emitUint8(0x72); | 
| 1065   } | 1065   } | 
| 1066   emitRegisterOperand(2, gprEncoding(dst)); | 1066   emitRegisterOperand(2, gprEncoding(dst)); | 
| 1067   emitUint8(imm.value() & 0xFF); | 1067   emitUint8(imm.value() & 0xFF); | 
| 1068 } | 1068 } | 
| 1069 | 1069 | 
| 1070 // {add,sub,mul,div}ps are given a Ty parameter for consistency with | 1070 // {add,sub,mul,div}ps are given a Ty parameter for consistency with | 
| 1071 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows | 1071 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows addpd, etc., | 
| 1072 // addpd, etc., we can use the Ty parameter to decide on adding | 1072 // we can use the Ty parameter to decide on adding a 0x66 prefix. | 
| 1073 // a 0x66 prefix. |  | 
| 1074 template <class Machine> | 1073 template <class Machine> | 
| 1075 void AssemblerX86Base<Machine>::addps(Type /* Ty */, | 1074 void AssemblerX86Base<Machine>::addps(Type /* Ty */, | 
| 1076                                       typename Traits::XmmRegister dst, | 1075                                       typename Traits::XmmRegister dst, | 
| 1077                                       typename Traits::XmmRegister src) { | 1076                                       typename Traits::XmmRegister src) { | 
| 1078   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1077   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 
| 1079   emitRexRB(RexTypeIrrelevant, dst, src); | 1078   emitRexRB(RexTypeIrrelevant, dst, src); | 
| 1080   emitUint8(0x0F); | 1079   emitUint8(0x0F); | 
| 1081   emitUint8(0x58); | 1080   emitUint8(0x58); | 
| 1082   emitXmmRegisterOperand(dst, src); | 1081   emitXmmRegisterOperand(dst, src); | 
| 1083 } | 1082 } | 
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1829     emitUint8(0x0F); | 1828     emitUint8(0x0F); | 
| 1830     emitUint8(0xC5); | 1829     emitUint8(0xC5); | 
| 1831     emitXmmRegisterOperand(dst, src); | 1830     emitXmmRegisterOperand(dst, src); | 
| 1832     emitUint8(imm.value()); | 1831     emitUint8(imm.value()); | 
| 1833   } else { | 1832   } else { | 
| 1834     emitUint8(0x66); | 1833     emitUint8(0x66); | 
| 1835     emitRexRB(Ty, src, dst); | 1834     emitRexRB(Ty, src, dst); | 
| 1836     emitUint8(0x0F); | 1835     emitUint8(0x0F); | 
| 1837     emitUint8(0x3A); | 1836     emitUint8(0x3A); | 
| 1838     emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16); | 1837     emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16); | 
| 1839     // SSE 4.1 versions are "MRI" because dst can be mem, while | 1838     // SSE 4.1 versions are "MRI" because dst can be mem, while pextrw (SSE2) | 
| 1840     // pextrw (SSE2) is RMI because dst must be reg. | 1839     // is RMI because dst must be reg. | 
| 1841     emitXmmRegisterOperand(src, dst); | 1840     emitXmmRegisterOperand(src, dst); | 
| 1842     emitUint8(imm.value()); | 1841     emitUint8(imm.value()); | 
| 1843   } | 1842   } | 
| 1844 } | 1843 } | 
| 1845 | 1844 | 
| 1846 template <class Machine> | 1845 template <class Machine> | 
| 1847 void AssemblerX86Base<Machine>::pmovsxdq(typename Traits::XmmRegister dst, | 1846 void AssemblerX86Base<Machine>::pmovsxdq(typename Traits::XmmRegister dst, | 
| 1848                                          typename Traits::XmmRegister src) { | 1847                                          typename Traits::XmmRegister src) { | 
| 1849   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1848   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 
| 1850   emitUint8(0x66); | 1849   emitUint8(0x66); | 
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2140     emitUint8(0x84); | 2139     emitUint8(0x84); | 
| 2141   else | 2140   else | 
| 2142     emitUint8(0x85); | 2141     emitUint8(0x85); | 
| 2143   emitOperand(gprEncoding(reg), addr); | 2142   emitOperand(gprEncoding(reg), addr); | 
| 2144 } | 2143 } | 
| 2145 | 2144 | 
| 2146 template <class Machine> | 2145 template <class Machine> | 
| 2147 void AssemblerX86Base<Machine>::test(Type Ty, typename Traits::GPRRegister reg, | 2146 void AssemblerX86Base<Machine>::test(Type Ty, typename Traits::GPRRegister reg, | 
| 2148                                      const Immediate &immediate) { | 2147                                      const Immediate &immediate) { | 
| 2149   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2148   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 
| 2150   // For registers that have a byte variant (EAX, EBX, ECX, and EDX) | 2149   // For registers that have a byte variant (EAX, EBX, ECX, and EDX) we only | 
| 2151   // we only test the byte register to keep the encoding short. | 2150   // test the byte register to keep the encoding short. This is legal even if | 
| 2152   // This is legal even if the register had high bits set since | 2151   // the register had high bits set since this only sets flags registers based | 
| 2153   // this only sets flags registers based on the "AND" of the two operands, | 2152   // on the "AND" of the two operands, and the immediate had zeros at those | 
| 2154   // and the immediate had zeros at those high bits. | 2153   // high bits. | 
| 2155   if (immediate.is_uint8() && reg <= Traits::Last8BitGPR) { | 2154   if (immediate.is_uint8() && reg <= Traits::Last8BitGPR) { | 
| 2156     // Use zero-extended 8-bit immediate. | 2155     // Use zero-extended 8-bit immediate. | 
| 2157     emitRexB(Ty, reg); | 2156     emitRexB(Ty, reg); | 
| 2158     if (reg == Traits::Encoded_Reg_Accumulator) { | 2157     if (reg == Traits::Encoded_Reg_Accumulator) { | 
| 2159       emitUint8(0xA8); | 2158       emitUint8(0xA8); | 
| 2160     } else { | 2159     } else { | 
| 2161       emitUint8(0xF6); | 2160       emitUint8(0xF6); | 
| 2162       emitUint8(0xC0 + gprEncoding(reg)); | 2161       emitUint8(0xC0 + gprEncoding(reg)); | 
| 2163     } | 2162     } | 
| 2164     emitUint8(immediate.value() & 0xFF); | 2163     emitUint8(immediate.value() & 0xFF); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 2176     emitRegisterOperand(0, gprEncoding(reg)); | 2175     emitRegisterOperand(0, gprEncoding(reg)); | 
| 2177     emitImmediate(Ty, immediate); | 2176     emitImmediate(Ty, immediate); | 
| 2178   } | 2177   } | 
| 2179 } | 2178 } | 
| 2180 | 2179 | 
| 2181 template <class Machine> | 2180 template <class Machine> | 
| 2182 void AssemblerX86Base<Machine>::test(Type Ty, | 2181 void AssemblerX86Base<Machine>::test(Type Ty, | 
| 2183                                      const typename Traits::Address &addr, | 2182                                      const typename Traits::Address &addr, | 
| 2184                                      const Immediate &immediate) { | 2183                                      const Immediate &immediate) { | 
| 2185   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2184   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 
| 2186   // If the immediate is short, we only test the byte addr to keep the | 2185   // If the immediate is short, we only test the byte addr to keep the encoding | 
| 2187   // encoding short. | 2186   // short. | 
| 2188   if (immediate.is_uint8()) { | 2187   if (immediate.is_uint8()) { | 
| 2189     // Use zero-extended 8-bit immediate. | 2188     // Use zero-extended 8-bit immediate. | 
| 2190     emitRex(Ty, addr, RexRegIrrelevant); | 2189     emitRex(Ty, addr, RexRegIrrelevant); | 
| 2191     emitUint8(0xF6); | 2190     emitUint8(0xF6); | 
| 2192     emitOperand(0, addr); | 2191     emitOperand(0, addr); | 
| 2193     emitUint8(immediate.value() & 0xFF); | 2192     emitUint8(immediate.value() & 0xFF); | 
| 2194   } else { | 2193   } else { | 
| 2195     if (Ty == IceType_i16) | 2194     if (Ty == IceType_i16) | 
| 2196       emitOperandSizeOverride(); | 2195       emitOperandSizeOverride(); | 
| 2197     emitRex(Ty, addr, RexRegIrrelevant); | 2196     emitRex(Ty, addr, RexRegIrrelevant); | 
| (...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3009   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3008   AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 
| 3010   if (label->isBound()) { | 3009   if (label->isBound()) { | 
| 3011     static const int kShortSize = 2; | 3010     static const int kShortSize = 2; | 
| 3012     static const int kLongSize = 6; | 3011     static const int kLongSize = 6; | 
| 3013     intptr_t offset = label->getPosition() - Buffer.size(); | 3012     intptr_t offset = label->getPosition() - Buffer.size(); | 
| 3014     assert(offset <= 0); | 3013     assert(offset <= 0); | 
| 3015     if (Utils::IsInt(8, offset - kShortSize)) { | 3014     if (Utils::IsInt(8, offset - kShortSize)) { | 
| 3016       // TODO(stichnot): Here and in jmp(), we may need to be more | 3015       // TODO(stichnot): Here and in jmp(), we may need to be more | 
| 3017       // conservative about the backward branch distance if the branch | 3016       // conservative about the backward branch distance if the branch | 
| 3018       // instruction is within a bundle_lock sequence, because the | 3017       // instruction is within a bundle_lock sequence, because the | 
| 3019       // distance may increase when padding is added.  This isn't an | 3018       // distance may increase when padding is added. This isn't an issue for | 
| 3020       // issue for branches outside a bundle_lock, because if padding | 3019       // branches outside a bundle_lock, because if padding is added, the retry | 
| 3021       // is added, the retry may change it to a long backward branch | 3020       // may change it to a long backward branch without affecting any of the | 
| 3022       // without affecting any of the bookkeeping. | 3021       // bookkeeping. | 
| 3023       emitUint8(0x70 + condition); | 3022       emitUint8(0x70 + condition); | 
| 3024       emitUint8((offset - kShortSize) & 0xFF); | 3023       emitUint8((offset - kShortSize) & 0xFF); | 
| 3025     } else { | 3024     } else { | 
| 3026       emitUint8(0x0F); | 3025       emitUint8(0x0F); | 
| 3027       emitUint8(0x80 + condition); | 3026       emitUint8(0x80 + condition); | 
| 3028       emitInt32(offset - kLongSize); | 3027       emitInt32(offset - kLongSize); | 
| 3029     } | 3028     } | 
| 3030   } else if (near) { | 3029   } else if (near) { | 
| 3031     emitUint8(0x70 + condition); | 3030     emitUint8(0x70 + condition); | 
| 3032     emitNearLabelLink(label); | 3031     emitNearLabelLink(label); | 
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3397   (void)shifter; | 3396   (void)shifter; | 
| 3398   if (Ty == IceType_i16) | 3397   if (Ty == IceType_i16) | 
| 3399     emitOperandSizeOverride(); | 3398     emitOperandSizeOverride(); | 
| 3400   emitRexB(Ty, operand.rm()); | 3399   emitRexB(Ty, operand.rm()); | 
| 3401   emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3400   emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 
| 3402   emitOperand(rm, operand); | 3401   emitOperand(rm, operand); | 
| 3403 } | 3402 } | 
| 3404 | 3403 | 
| 3405 } // end of namespace X86Internal | 3404 } // end of namespace X86Internal | 
| 3406 } // end of namespace Ice | 3405 } // end of namespace Ice | 
| OLD | NEW | 
|---|