| 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 |
| 11 // | 11 // |
| 12 // This file is distributed under the University of Illinois Open Source | 12 // This file is distributed under the University of Illinois Open Source |
| 13 // License. See LICENSE.TXT for details. | 13 // License. See LICENSE.TXT for details. |
| 14 // | 14 // |
| 15 //===----------------------------------------------------------------------===// | 15 //===----------------------------------------------------------------------===// |
| 16 // | 16 // |
| 17 /// \file | 17 /// \file |
| 18 /// \brief Implements the AssemblerX86Base template class, which is the base | 18 /// \brief Implements the AssemblerX86Base template class, which is the base |
| 19 /// Assembler class for X86 assemblers. | 19 /// Assembler class for X86 assemblers. |
| 20 // | 20 // |
| 21 //===----------------------------------------------------------------------===// | 21 //===----------------------------------------------------------------------===// |
| 22 | 22 |
| 23 #include "IceAssemblerX86Base.h" | 23 #include "IceAssemblerX86Base.h" |
| 24 | 24 |
| 25 #include "IceCfg.h" | 25 #include "IceCfg.h" |
| 26 #include "IceCfgNode.h" | 26 #include "IceCfgNode.h" |
| 27 #include "IceOperand.h" | 27 #include "IceOperand.h" |
| 28 | 28 |
| 29 namespace Ice { | 29 namespace Ice { |
| 30 namespace X86Internal { | 30 namespace X86NAMESPACE { |
| 31 | 31 |
| 32 template <class Machine> | 32 template <typename TraitsType> |
| 33 AssemblerX86Base<Machine>::~AssemblerX86Base<Machine>() { | 33 AssemblerX86Base<TraitsType>::~AssemblerX86Base() { |
| 34 if (BuildDefs::asserts()) { | 34 if (BuildDefs::asserts()) { |
| 35 for (const Label *Label : CfgNodeLabels) { | 35 for (const Label *Label : CfgNodeLabels) { |
| 36 Label->finalCheck(); | 36 Label->finalCheck(); |
| 37 } | 37 } |
| 38 for (const Label *Label : LocalLabels) { | 38 for (const Label *Label : LocalLabels) { |
| 39 Label->finalCheck(); | 39 Label->finalCheck(); |
| 40 } | 40 } |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 | 43 |
| 44 template <class Machine> void AssemblerX86Base<Machine>::alignFunction() { | 44 template <typename TraitsType> |
| 45 void AssemblerX86Base<TraitsType>::alignFunction() { |
| 45 const SizeT Align = 1 << getBundleAlignLog2Bytes(); | 46 const SizeT Align = 1 << getBundleAlignLog2Bytes(); |
| 46 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); | 47 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); |
| 47 constexpr SizeT HltSize = 1; | 48 constexpr SizeT HltSize = 1; |
| 48 while (BytesNeeded > 0) { | 49 while (BytesNeeded > 0) { |
| 49 hlt(); | 50 hlt(); |
| 50 BytesNeeded -= HltSize; | 51 BytesNeeded -= HltSize; |
| 51 } | 52 } |
| 52 } | 53 } |
| 53 | 54 |
| 54 template <class Machine> | 55 template <typename TraitsType> |
| 55 Label *AssemblerX86Base<Machine>::getOrCreateLabel(SizeT Number, | 56 typename AssemblerX86Base<TraitsType>::Label * |
| 56 LabelVector &Labels) { | 57 AssemblerX86Base<TraitsType>::getOrCreateLabel(SizeT Number, |
| 58 LabelVector &Labels) { |
| 57 Label *L = nullptr; | 59 Label *L = nullptr; |
| 58 if (Number == Labels.size()) { | 60 if (Number == Labels.size()) { |
| 59 L = new (this->allocate<Label>()) Label(); | 61 L = new (this->allocate<Label>()) Label(); |
| 60 Labels.push_back(L); | 62 Labels.push_back(L); |
| 61 return L; | 63 return L; |
| 62 } | 64 } |
| 63 if (Number > Labels.size()) { | 65 if (Number > Labels.size()) { |
| 64 Labels.resize(Number + 1); | 66 Labels.resize(Number + 1); |
| 65 } | 67 } |
| 66 L = Labels[Number]; | 68 L = Labels[Number]; |
| 67 if (!L) { | 69 if (!L) { |
| 68 L = new (this->allocate<Label>()) Label(); | 70 L = new (this->allocate<Label>()) Label(); |
| 69 Labels[Number] = L; | 71 Labels[Number] = L; |
| 70 } | 72 } |
| 71 return L; | 73 return L; |
| 72 } | 74 } |
| 73 | 75 |
| 74 template <class Machine> | 76 template <typename TraitsType> |
| 75 Ice::Label *AssemblerX86Base<Machine>::getCfgNodeLabel(SizeT NodeNumber) { | 77 Ice::Label *AssemblerX86Base<TraitsType>::getCfgNodeLabel(SizeT NodeNumber) { |
| 76 assert(NodeNumber < CfgNodeLabels.size()); | 78 assert(NodeNumber < CfgNodeLabels.size()); |
| 77 return CfgNodeLabels[NodeNumber]; | 79 return CfgNodeLabels[NodeNumber]; |
| 78 } | 80 } |
| 79 | 81 |
| 80 template <class Machine> | 82 template <typename TraitsType> |
| 81 Label *AssemblerX86Base<Machine>::getOrCreateCfgNodeLabel(SizeT NodeNumber) { | 83 typename AssemblerX86Base<TraitsType>::Label * |
| 84 AssemblerX86Base<TraitsType>::getOrCreateCfgNodeLabel(SizeT NodeNumber) { |
| 82 return getOrCreateLabel(NodeNumber, CfgNodeLabels); | 85 return getOrCreateLabel(NodeNumber, CfgNodeLabels); |
| 83 } | 86 } |
| 84 | 87 |
| 85 template <class Machine> | 88 template <typename TraitsType> |
| 86 Label *AssemblerX86Base<Machine>::getOrCreateLocalLabel(SizeT Number) { | 89 typename AssemblerX86Base<TraitsType>::Label * |
| 90 AssemblerX86Base<TraitsType>::getOrCreateLocalLabel(SizeT Number) { |
| 87 return getOrCreateLabel(Number, LocalLabels); | 91 return getOrCreateLabel(Number, LocalLabels); |
| 88 } | 92 } |
| 89 | 93 |
| 90 template <class Machine> | 94 template <typename TraitsType> |
| 91 void AssemblerX86Base<Machine>::bindCfgNodeLabel(const CfgNode *Node) { | 95 void AssemblerX86Base<TraitsType>::bindCfgNodeLabel(const CfgNode *Node) { |
| 92 assert(!getPreliminary()); | 96 assert(!getPreliminary()); |
| 93 Label *L = getOrCreateCfgNodeLabel(Node->getIndex()); | 97 Label *L = getOrCreateCfgNodeLabel(Node->getIndex()); |
| 94 this->bind(L); | 98 this->bind(L); |
| 95 } | 99 } |
| 96 | 100 |
| 97 template <class Machine> | 101 template <typename TraitsType> |
| 98 void AssemblerX86Base<Machine>::bindLocalLabel(SizeT Number) { | 102 void AssemblerX86Base<TraitsType>::bindLocalLabel(SizeT Number) { |
| 99 Label *L = getOrCreateLocalLabel(Number); | 103 Label *L = getOrCreateLocalLabel(Number); |
| 100 if (!getPreliminary()) | 104 if (!getPreliminary()) |
| 101 this->bind(L); | 105 this->bind(L); |
| 102 } | 106 } |
| 103 | 107 |
| 104 template <class Machine> | 108 template <typename TraitsType> |
| 105 void AssemblerX86Base<Machine>::call(typename Traits::GPRRegister reg) { | 109 void AssemblerX86Base<TraitsType>::call(GPRRegister reg) { |
| 106 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 110 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 107 emitRexB(RexTypeIrrelevant, reg); | 111 emitRexB(RexTypeIrrelevant, reg); |
| 108 emitUint8(0xFF); | 112 emitUint8(0xFF); |
| 109 emitRegisterOperand(2, gprEncoding(reg)); | 113 emitRegisterOperand(2, gprEncoding(reg)); |
| 110 } | 114 } |
| 111 | 115 |
| 112 template <class Machine> | 116 template <typename TraitsType> |
| 113 void AssemblerX86Base<Machine>::call(const typename Traits::Address &address) { | 117 void AssemblerX86Base<TraitsType>::call(const Address &address) { |
| 114 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 118 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 115 emitAddrSizeOverridePrefix(); | 119 emitAddrSizeOverridePrefix(); |
| 116 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); | 120 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); |
| 117 emitUint8(0xFF); | 121 emitUint8(0xFF); |
| 118 emitOperand(2, address); | 122 emitOperand(2, address); |
| 119 } | 123 } |
| 120 | 124 |
| 121 template <class Machine> | 125 template <typename TraitsType> |
| 122 void AssemblerX86Base<Machine>::call(const ConstantRelocatable *label) { | 126 void AssemblerX86Base<TraitsType>::call(const ConstantRelocatable *label) { |
| 123 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 127 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 124 intptr_t call_start = Buffer.getPosition(); | 128 intptr_t call_start = Buffer.getPosition(); |
| 125 emitUint8(0xE8); | 129 emitUint8(0xE8); |
| 126 emitFixup(this->createFixup(Traits::PcRelFixup, label)); | 130 emitFixup(this->createFixup(Traits::PcRelFixup, label)); |
| 127 emitInt32(-4); | 131 emitInt32(-4); |
| 128 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); | 132 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); |
| 129 (void)call_start; | 133 (void)call_start; |
| 130 } | 134 } |
| 131 | 135 |
| 132 template <class Machine> | 136 template <typename TraitsType> |
| 133 void AssemblerX86Base<Machine>::call(const Immediate &abs_address) { | 137 void AssemblerX86Base<TraitsType>::call(const Immediate &abs_address) { |
| 134 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 138 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 135 intptr_t call_start = Buffer.getPosition(); | 139 intptr_t call_start = Buffer.getPosition(); |
| 136 emitUint8(0xE8); | 140 emitUint8(0xE8); |
| 137 emitFixup(this->createFixup(Traits::PcRelFixup, AssemblerFixup::NullSymbol)); | 141 emitFixup(this->createFixup(Traits::PcRelFixup, AssemblerFixup::NullSymbol)); |
| 138 emitInt32(abs_address.value() - 4); | 142 emitInt32(abs_address.value() - 4); |
| 139 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); | 143 assert((Buffer.getPosition() - call_start) == kCallExternalLabelSize); |
| 140 (void)call_start; | 144 (void)call_start; |
| 141 } | 145 } |
| 142 | 146 |
| 143 template <class Machine> | 147 template <typename TraitsType> |
| 144 void AssemblerX86Base<Machine>::pushl(typename Traits::GPRRegister reg) { | 148 void AssemblerX86Base<TraitsType>::pushl(GPRRegister reg) { |
| 145 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 149 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 146 emitRexB(RexTypeIrrelevant, reg); | 150 emitRexB(RexTypeIrrelevant, reg); |
| 147 emitUint8(0x50 + gprEncoding(reg)); | 151 emitUint8(0x50 + gprEncoding(reg)); |
| 148 } | 152 } |
| 149 | 153 |
| 150 template <class Machine> | 154 template <typename TraitsType> |
| 151 void AssemblerX86Base<Machine>::popl(typename Traits::GPRRegister reg) { | 155 void AssemblerX86Base<TraitsType>::popl(GPRRegister reg) { |
| 152 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 156 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 153 // Any type that would not force a REX prefix to be emitted can be provided | 157 // Any type that would not force a REX prefix to be emitted can be provided |
| 154 // here. | 158 // here. |
| 155 emitRexB(RexTypeIrrelevant, reg); | 159 emitRexB(RexTypeIrrelevant, reg); |
| 156 emitUint8(0x58 + gprEncoding(reg)); | 160 emitUint8(0x58 + gprEncoding(reg)); |
| 157 } | 161 } |
| 158 | 162 |
| 159 template <class Machine> | 163 template <typename TraitsType> |
| 160 void AssemblerX86Base<Machine>::popl(const typename Traits::Address &address) { | 164 void AssemblerX86Base<TraitsType>::popl(const Address &address) { |
| 161 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 165 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 162 emitAddrSizeOverridePrefix(); | 166 emitAddrSizeOverridePrefix(); |
| 163 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); | 167 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); |
| 164 emitUint8(0x8F); | 168 emitUint8(0x8F); |
| 165 emitOperand(0, address); | 169 emitOperand(0, address); |
| 166 } | 170 } |
| 167 | 171 |
| 168 template <class Machine> | 172 template <typename TraitsType> |
| 169 template <typename, typename> | 173 template <typename, typename> |
| 170 void AssemblerX86Base<Machine>::pushal() { | 174 void AssemblerX86Base<TraitsType>::pushal() { |
| 171 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 175 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 172 emitUint8(0x60); | 176 emitUint8(0x60); |
| 173 } | 177 } |
| 174 | 178 |
| 175 template <class Machine> | 179 template <typename TraitsType> |
| 176 template <typename, typename> | 180 template <typename, typename> |
| 177 void AssemblerX86Base<Machine>::popal() { | 181 void AssemblerX86Base<TraitsType>::popal() { |
| 178 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 182 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 179 emitUint8(0x61); | 183 emitUint8(0x61); |
| 180 } | 184 } |
| 181 | 185 |
| 182 template <class Machine> | 186 template <typename TraitsType> |
| 183 void AssemblerX86Base<Machine>::setcc(typename Traits::Cond::BrCond condition, | 187 void AssemblerX86Base<TraitsType>::setcc(BrCond condition, ByteRegister dst) { |
| 184 typename Traits::ByteRegister dst) { | |
| 185 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 188 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 186 emitRexB(IceType_i8, dst); | 189 emitRexB(IceType_i8, dst); |
| 187 emitUint8(0x0F); | 190 emitUint8(0x0F); |
| 188 emitUint8(0x90 + condition); | 191 emitUint8(0x90 + condition); |
| 189 emitUint8(0xC0 + gprEncoding(dst)); | 192 emitUint8(0xC0 + gprEncoding(dst)); |
| 190 } | 193 } |
| 191 | 194 |
| 192 template <class Machine> | 195 template <typename TraitsType> |
| 193 void AssemblerX86Base<Machine>::setcc(typename Traits::Cond::BrCond condition, | 196 void AssemblerX86Base<TraitsType>::setcc(BrCond condition, |
| 194 const typename Traits::Address &address) { | 197 const Address &address) { |
| 195 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 198 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 196 emitAddrSizeOverridePrefix(); | 199 emitAddrSizeOverridePrefix(); |
| 197 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); | 200 emitRex(RexTypeIrrelevant, address, RexRegIrrelevant); |
| 198 emitUint8(0x0F); | 201 emitUint8(0x0F); |
| 199 emitUint8(0x90 + condition); | 202 emitUint8(0x90 + condition); |
| 200 emitOperand(0, address); | 203 emitOperand(0, address); |
| 201 } | 204 } |
| 202 | 205 |
| 203 template <class Machine> | 206 template <typename TraitsType> |
| 204 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, | 207 void AssemblerX86Base<TraitsType>::mov(Type Ty, GPRRegister dst, |
| 205 const Immediate &imm) { | 208 const Immediate &imm) { |
| 206 assert(Ty != IceType_i64 && "i64 not supported yet."); | 209 assert(Ty != IceType_i64 && "i64 not supported yet."); |
| 207 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 210 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 208 if (Ty == IceType_i16) | 211 if (Ty == IceType_i16) |
| 209 emitOperandSizeOverride(); | 212 emitOperandSizeOverride(); |
| 210 emitRexB(Ty, dst); | 213 emitRexB(Ty, dst); |
| 211 if (isByteSizedType(Ty)) { | 214 if (isByteSizedType(Ty)) { |
| 212 emitUint8(0xB0 + gprEncoding(dst)); | 215 emitUint8(0xB0 + gprEncoding(dst)); |
| 213 emitUint8(imm.value() & 0xFF); | 216 emitUint8(imm.value() & 0xFF); |
| 214 } else { | 217 } else { |
| 215 // TODO(jpp): When removing the assertion above ensure that in x86-64 we | 218 // TODO(jpp): When removing the assertion above ensure that in x86-64 we |
| 216 // emit a 64-bit immediate. | 219 // emit a 64-bit immediate. |
| 217 emitUint8(0xB8 + gprEncoding(dst)); | 220 emitUint8(0xB8 + gprEncoding(dst)); |
| 218 emitImmediate(Ty, imm); | 221 emitImmediate(Ty, imm); |
| 219 } | 222 } |
| 220 } | 223 } |
| 221 | 224 |
| 222 template <class Machine> | 225 template <typename TraitsType> |
| 223 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, | 226 void AssemblerX86Base<TraitsType>::mov(Type Ty, GPRRegister dst, |
| 224 typename Traits::GPRRegister src) { | 227 GPRRegister src) { |
| 225 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 228 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 226 if (Ty == IceType_i16) | 229 if (Ty == IceType_i16) |
| 227 emitOperandSizeOverride(); | 230 emitOperandSizeOverride(); |
| 228 emitRexRB(Ty, src, dst); | 231 emitRexRB(Ty, src, dst); |
| 229 if (isByteSizedType(Ty)) { | 232 if (isByteSizedType(Ty)) { |
| 230 emitUint8(0x88); | 233 emitUint8(0x88); |
| 231 } else { | 234 } else { |
| 232 emitUint8(0x89); | 235 emitUint8(0x89); |
| 233 } | 236 } |
| 234 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 237 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 235 } | 238 } |
| 236 | 239 |
| 237 template <class Machine> | 240 template <typename TraitsType> |
| 238 void AssemblerX86Base<Machine>::mov(Type Ty, typename Traits::GPRRegister dst, | 241 void AssemblerX86Base<TraitsType>::mov(Type Ty, GPRRegister dst, |
| 239 const typename Traits::Address &src) { | 242 const Address &src) { |
| 240 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 243 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 241 if (Ty == IceType_i16) | 244 if (Ty == IceType_i16) |
| 242 emitOperandSizeOverride(); | 245 emitOperandSizeOverride(); |
| 243 emitAddrSizeOverridePrefix(); | 246 emitAddrSizeOverridePrefix(); |
| 244 emitRex(Ty, src, dst); | 247 emitRex(Ty, src, dst); |
| 245 if (isByteSizedType(Ty)) { | 248 if (isByteSizedType(Ty)) { |
| 246 emitUint8(0x8A); | 249 emitUint8(0x8A); |
| 247 } else { | 250 } else { |
| 248 emitUint8(0x8B); | 251 emitUint8(0x8B); |
| 249 } | 252 } |
| 250 emitOperand(gprEncoding(dst), src); | 253 emitOperand(gprEncoding(dst), src); |
| 251 } | 254 } |
| 252 | 255 |
| 253 template <class Machine> | 256 template <typename TraitsType> |
| 254 void AssemblerX86Base<Machine>::mov(Type Ty, | 257 void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst, |
| 255 const typename Traits::Address &dst, | 258 GPRRegister src) { |
| 256 typename Traits::GPRRegister src) { | |
| 257 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 259 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 258 if (Ty == IceType_i16) | 260 if (Ty == IceType_i16) |
| 259 emitOperandSizeOverride(); | 261 emitOperandSizeOverride(); |
| 260 emitAddrSizeOverridePrefix(); | 262 emitAddrSizeOverridePrefix(); |
| 261 emitRex(Ty, dst, src); | 263 emitRex(Ty, dst, src); |
| 262 if (isByteSizedType(Ty)) { | 264 if (isByteSizedType(Ty)) { |
| 263 emitUint8(0x88); | 265 emitUint8(0x88); |
| 264 } else { | 266 } else { |
| 265 emitUint8(0x89); | 267 emitUint8(0x89); |
| 266 } | 268 } |
| 267 emitOperand(gprEncoding(src), dst); | 269 emitOperand(gprEncoding(src), dst); |
| 268 } | 270 } |
| 269 | 271 |
| 270 template <class Machine> | 272 template <typename TraitsType> |
| 271 void AssemblerX86Base<Machine>::mov(Type Ty, | 273 void AssemblerX86Base<TraitsType>::mov(Type Ty, const Address &dst, |
| 272 const typename Traits::Address &dst, | 274 const Immediate &imm) { |
| 273 const Immediate &imm) { | |
| 274 assert(Ty != IceType_i64 && "i64 not supported yet."); | 275 assert(Ty != IceType_i64 && "i64 not supported yet."); |
| 275 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 276 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 276 if (Ty == IceType_i16) | 277 if (Ty == IceType_i16) |
| 277 emitOperandSizeOverride(); | 278 emitOperandSizeOverride(); |
| 278 emitAddrSizeOverridePrefix(); | 279 emitAddrSizeOverridePrefix(); |
| 279 emitRex(Ty, dst, RexRegIrrelevant); | 280 emitRex(Ty, dst, RexRegIrrelevant); |
| 280 if (isByteSizedType(Ty)) { | 281 if (isByteSizedType(Ty)) { |
| 281 emitUint8(0xC6); | 282 emitUint8(0xC6); |
| 282 emitOperand(0, dst); | 283 emitOperand(0, dst); |
| 283 emitUint8(imm.value() & 0xFF); | 284 emitUint8(imm.value() & 0xFF); |
| 284 } else { | 285 } else { |
| 285 emitUint8(0xC7); | 286 emitUint8(0xC7); |
| 286 emitOperand(0, dst); | 287 emitOperand(0, dst); |
| 287 emitImmediate(Ty, imm); | 288 emitImmediate(Ty, imm); |
| 288 } | 289 } |
| 289 } | 290 } |
| 290 | 291 |
| 291 template <class Machine> | 292 template <typename TraitsType> |
| 292 template <typename T> | 293 template <typename T> |
| 293 typename std::enable_if<T::Is64Bit, void>::type | 294 typename std::enable_if<T::Is64Bit, void>::type |
| 294 AssemblerX86Base<Machine>::movabs(const typename Traits::GPRRegister Dst, | 295 AssemblerX86Base<TraitsType>::movabs(const GPRRegister Dst, uint64_t Imm64) { |
| 295 uint64_t Imm64) { | |
| 296 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 296 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 297 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0; | 297 const bool NeedsRexW = (Imm64 & ~0xFFFFFFFFull) != 0; |
| 298 const Type RexType = NeedsRexW ? RexTypeForceRexW : RexTypeIrrelevant; | 298 const Type RexType = NeedsRexW ? RexTypeForceRexW : RexTypeIrrelevant; |
| 299 emitRexB(RexType, Dst); | 299 emitRexB(RexType, Dst); |
| 300 emitUint8(0xB8 | gprEncoding(Dst)); | 300 emitUint8(0xB8 | gprEncoding(Dst)); |
| 301 // When emitting Imm64, we don't have to mask out the upper 32 bits for | 301 // When emitting Imm64, we don't have to mask out the upper 32 bits for |
| 302 // emitInt32 will/should only emit a 32-bit constant. In reality, we are | 302 // emitInt32 will/should only emit a 32-bit constant. In reality, we are |
| 303 // paranoid, so we go ahead an mask the upper bits out anyway. | 303 // paranoid, so we go ahead an mask the upper bits out anyway. |
| 304 emitInt32(Imm64 & 0xFFFFFFFF); | 304 emitInt32(Imm64 & 0xFFFFFFFF); |
| 305 if (NeedsRexW) | 305 if (NeedsRexW) |
| 306 emitInt32((Imm64 >> 32) & 0xFFFFFFFF); | 306 emitInt32((Imm64 >> 32) & 0xFFFFFFFF); |
| 307 } | 307 } |
| 308 | 308 |
| 309 template <class Machine> | 309 template <typename TraitsType> |
| 310 void AssemblerX86Base<Machine>::movzx(Type SrcTy, | 310 void AssemblerX86Base<TraitsType>::movzx(Type SrcTy, GPRRegister dst, |
| 311 typename Traits::GPRRegister dst, | 311 GPRRegister src) { |
| 312 typename Traits::GPRRegister src) { | |
| 313 if (Traits::Is64Bit && SrcTy == IceType_i32) { | 312 if (Traits::Is64Bit && SrcTy == IceType_i32) { |
| 314 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit | 313 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit |
| 315 // operand to 64-bit. | 314 // operand to 64-bit. |
| 316 mov(IceType_i32, dst, src); | 315 mov(IceType_i32, dst, src); |
| 317 return; | 316 return; |
| 318 } | 317 } |
| 319 | 318 |
| 320 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 319 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 321 bool ByteSized = isByteSizedType(SrcTy); | 320 bool ByteSized = isByteSizedType(SrcTy); |
| 322 assert(ByteSized || SrcTy == IceType_i16); | 321 assert(ByteSized || SrcTy == IceType_i16); |
| 323 emitRexRB(RexTypeIrrelevant, dst, SrcTy, src); | 322 emitRexRB(RexTypeIrrelevant, dst, SrcTy, src); |
| 324 emitUint8(0x0F); | 323 emitUint8(0x0F); |
| 325 emitUint8(ByteSized ? 0xB6 : 0xB7); | 324 emitUint8(ByteSized ? 0xB6 : 0xB7); |
| 326 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 325 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 327 } | 326 } |
| 328 | 327 |
| 329 template <class Machine> | 328 template <typename TraitsType> |
| 330 void AssemblerX86Base<Machine>::movzx(Type SrcTy, | 329 void AssemblerX86Base<TraitsType>::movzx(Type SrcTy, GPRRegister dst, |
| 331 typename Traits::GPRRegister dst, | 330 const Address &src) { |
| 332 const typename Traits::Address &src) { | |
| 333 if (Traits::Is64Bit && SrcTy == IceType_i32) { | 331 if (Traits::Is64Bit && SrcTy == IceType_i32) { |
| 334 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit | 332 // 32-bit mov clears the upper 32 bits, hence zero-extending the 32-bit |
| 335 // operand to 64-bit. | 333 // operand to 64-bit. |
| 336 mov(IceType_i32, dst, src); | 334 mov(IceType_i32, dst, src); |
| 337 return; | 335 return; |
| 338 } | 336 } |
| 339 | 337 |
| 340 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 338 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 341 bool ByteSized = isByteSizedType(SrcTy); | 339 bool ByteSized = isByteSizedType(SrcTy); |
| 342 assert(ByteSized || SrcTy == IceType_i16); | 340 assert(ByteSized || SrcTy == IceType_i16); |
| 343 emitAddrSizeOverridePrefix(); | 341 emitAddrSizeOverridePrefix(); |
| 344 emitRex(SrcTy, src, RexTypeIrrelevant, dst); | 342 emitRex(SrcTy, src, RexTypeIrrelevant, dst); |
| 345 emitUint8(0x0F); | 343 emitUint8(0x0F); |
| 346 emitUint8(ByteSized ? 0xB6 : 0xB7); | 344 emitUint8(ByteSized ? 0xB6 : 0xB7); |
| 347 emitOperand(gprEncoding(dst), src); | 345 emitOperand(gprEncoding(dst), src); |
| 348 } | 346 } |
| 349 | 347 |
| 350 template <class Machine> | 348 template <typename TraitsType> |
| 351 void AssemblerX86Base<Machine>::movsx(Type SrcTy, | 349 void AssemblerX86Base<TraitsType>::movsx(Type SrcTy, GPRRegister dst, |
| 352 typename Traits::GPRRegister dst, | 350 GPRRegister src) { |
| 353 typename Traits::GPRRegister src) { | |
| 354 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 351 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 355 bool ByteSized = isByteSizedType(SrcTy); | 352 bool ByteSized = isByteSizedType(SrcTy); |
| 356 emitRexRB(RexTypeForceRexW, dst, SrcTy, src); | 353 emitRexRB(RexTypeForceRexW, dst, SrcTy, src); |
| 357 if (ByteSized || SrcTy == IceType_i16) { | 354 if (ByteSized || SrcTy == IceType_i16) { |
| 358 emitUint8(0x0F); | 355 emitUint8(0x0F); |
| 359 emitUint8(ByteSized ? 0xBE : 0xBF); | 356 emitUint8(ByteSized ? 0xBE : 0xBF); |
| 360 } else { | 357 } else { |
| 361 assert(Traits::Is64Bit && SrcTy == IceType_i32); | 358 assert(Traits::Is64Bit && SrcTy == IceType_i32); |
| 362 emitUint8(0x63); | 359 emitUint8(0x63); |
| 363 } | 360 } |
| 364 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 361 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 365 } | 362 } |
| 366 | 363 |
| 367 template <class Machine> | 364 template <typename TraitsType> |
| 368 void AssemblerX86Base<Machine>::movsx(Type SrcTy, | 365 void AssemblerX86Base<TraitsType>::movsx(Type SrcTy, GPRRegister dst, |
| 369 typename Traits::GPRRegister dst, | 366 const Address &src) { |
| 370 const typename Traits::Address &src) { | |
| 371 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 367 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 372 bool ByteSized = isByteSizedType(SrcTy); | 368 bool ByteSized = isByteSizedType(SrcTy); |
| 373 emitAddrSizeOverridePrefix(); | 369 emitAddrSizeOverridePrefix(); |
| 374 emitRex(SrcTy, src, RexTypeForceRexW, dst); | 370 emitRex(SrcTy, src, RexTypeForceRexW, dst); |
| 375 if (ByteSized || SrcTy == IceType_i16) { | 371 if (ByteSized || SrcTy == IceType_i16) { |
| 376 emitUint8(0x0F); | 372 emitUint8(0x0F); |
| 377 emitUint8(ByteSized ? 0xBE : 0xBF); | 373 emitUint8(ByteSized ? 0xBE : 0xBF); |
| 378 } else { | 374 } else { |
| 379 assert(Traits::Is64Bit && SrcTy == IceType_i32); | 375 assert(Traits::Is64Bit && SrcTy == IceType_i32); |
| 380 emitUint8(0x63); | 376 emitUint8(0x63); |
| 381 } | 377 } |
| 382 emitOperand(gprEncoding(dst), src); | 378 emitOperand(gprEncoding(dst), src); |
| 383 } | 379 } |
| 384 | 380 |
| 385 template <class Machine> | 381 template <typename TraitsType> |
| 386 void AssemblerX86Base<Machine>::lea(Type Ty, typename Traits::GPRRegister dst, | 382 void AssemblerX86Base<TraitsType>::lea(Type Ty, GPRRegister dst, |
| 387 const typename Traits::Address &src) { | 383 const Address &src) { |
| 388 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 384 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 389 assert(Ty == IceType_i16 || Ty == IceType_i32); | 385 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 390 if (Ty == IceType_i16) | 386 if (Ty == IceType_i16) |
| 391 emitOperandSizeOverride(); | 387 emitOperandSizeOverride(); |
| 392 emitAddrSizeOverridePrefix(); | 388 emitAddrSizeOverridePrefix(); |
| 393 emitRex(Ty, src, dst); | 389 emitRex(Ty, src, dst); |
| 394 emitUint8(0x8D); | 390 emitUint8(0x8D); |
| 395 emitOperand(gprEncoding(dst), src); | 391 emitOperand(gprEncoding(dst), src); |
| 396 } | 392 } |
| 397 | 393 |
| 398 template <class Machine> | 394 template <typename TraitsType> |
| 399 void AssemblerX86Base<Machine>::cmov(Type Ty, | 395 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst, |
| 400 typename Traits::Cond::BrCond cond, | 396 GPRRegister src) { |
| 401 typename Traits::GPRRegister dst, | |
| 402 typename Traits::GPRRegister src) { | |
| 403 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 397 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 404 if (Ty == IceType_i16) | 398 if (Ty == IceType_i16) |
| 405 emitOperandSizeOverride(); | 399 emitOperandSizeOverride(); |
| 406 else | 400 else |
| 407 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); | 401 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); |
| 408 emitRexRB(Ty, dst, src); | 402 emitRexRB(Ty, dst, src); |
| 409 emitUint8(0x0F); | 403 emitUint8(0x0F); |
| 410 emitUint8(0x40 + cond); | 404 emitUint8(0x40 + cond); |
| 411 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 405 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 412 } | 406 } |
| 413 | 407 |
| 414 template <class Machine> | 408 template <typename TraitsType> |
| 415 void AssemblerX86Base<Machine>::cmov(Type Ty, | 409 void AssemblerX86Base<TraitsType>::cmov(Type Ty, BrCond cond, GPRRegister dst, |
| 416 typename Traits::Cond::BrCond cond, | 410 const Address &src) { |
| 417 typename Traits::GPRRegister dst, | |
| 418 const typename Traits::Address &src) { | |
| 419 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 411 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 420 if (Ty == IceType_i16) | 412 if (Ty == IceType_i16) |
| 421 emitOperandSizeOverride(); | 413 emitOperandSizeOverride(); |
| 422 else | 414 else |
| 423 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); | 415 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); |
| 424 emitAddrSizeOverridePrefix(); | 416 emitAddrSizeOverridePrefix(); |
| 425 emitRex(Ty, src, dst); | 417 emitRex(Ty, src, dst); |
| 426 emitUint8(0x0F); | 418 emitUint8(0x0F); |
| 427 emitUint8(0x40 + cond); | 419 emitUint8(0x40 + cond); |
| 428 emitOperand(gprEncoding(dst), src); | 420 emitOperand(gprEncoding(dst), src); |
| 429 } | 421 } |
| 430 | 422 |
| 431 template <class Machine> void AssemblerX86Base<Machine>::rep_movsb() { | 423 template <typename TraitsType> void AssemblerX86Base<TraitsType>::rep_movsb() { |
| 432 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 424 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 433 emitUint8(0xF3); | 425 emitUint8(0xF3); |
| 434 emitUint8(0xA4); | 426 emitUint8(0xA4); |
| 435 } | 427 } |
| 436 | 428 |
| 437 template <class Machine> | 429 template <typename TraitsType> |
| 438 void AssemblerX86Base<Machine>::movss(Type Ty, typename Traits::XmmRegister dst, | 430 void AssemblerX86Base<TraitsType>::movss(Type Ty, XmmRegister dst, |
| 439 const typename Traits::Address &src) { | 431 const Address &src) { |
| 440 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 432 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 441 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 433 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 442 emitAddrSizeOverridePrefix(); | 434 emitAddrSizeOverridePrefix(); |
| 443 emitRex(RexTypeIrrelevant, src, dst); | 435 emitRex(RexTypeIrrelevant, src, dst); |
| 444 emitUint8(0x0F); | 436 emitUint8(0x0F); |
| 445 emitUint8(0x10); | 437 emitUint8(0x10); |
| 446 emitOperand(gprEncoding(dst), src); | 438 emitOperand(gprEncoding(dst), src); |
| 447 } | 439 } |
| 448 | 440 |
| 449 template <class Machine> | 441 template <typename TraitsType> |
| 450 void AssemblerX86Base<Machine>::movss(Type Ty, | 442 void AssemblerX86Base<TraitsType>::movss(Type Ty, const Address &dst, |
| 451 const typename Traits::Address &dst, | 443 XmmRegister src) { |
| 452 typename Traits::XmmRegister src) { | |
| 453 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 444 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 454 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 445 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 455 emitAddrSizeOverridePrefix(); | 446 emitAddrSizeOverridePrefix(); |
| 456 emitRex(RexTypeIrrelevant, dst, src); | 447 emitRex(RexTypeIrrelevant, dst, src); |
| 457 emitUint8(0x0F); | 448 emitUint8(0x0F); |
| 458 emitUint8(0x11); | 449 emitUint8(0x11); |
| 459 emitOperand(gprEncoding(src), dst); | 450 emitOperand(gprEncoding(src), dst); |
| 460 } | 451 } |
| 461 | 452 |
| 462 template <class Machine> | 453 template <typename TraitsType> |
| 463 void AssemblerX86Base<Machine>::movss(Type Ty, typename Traits::XmmRegister dst, | 454 void AssemblerX86Base<TraitsType>::movss(Type Ty, XmmRegister dst, |
| 464 typename Traits::XmmRegister src) { | 455 XmmRegister src) { |
| 465 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 456 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 466 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 457 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 467 emitRexRB(RexTypeIrrelevant, src, dst); | 458 emitRexRB(RexTypeIrrelevant, src, dst); |
| 468 emitUint8(0x0F); | 459 emitUint8(0x0F); |
| 469 emitUint8(0x11); | 460 emitUint8(0x11); |
| 470 emitXmmRegisterOperand(src, dst); | 461 emitXmmRegisterOperand(src, dst); |
| 471 } | 462 } |
| 472 | 463 |
| 473 template <class Machine> | 464 template <typename TraitsType> |
| 474 void AssemblerX86Base<Machine>::movd(Type SrcTy, | 465 void AssemblerX86Base<TraitsType>::movd(Type SrcTy, XmmRegister dst, |
| 475 typename Traits::XmmRegister dst, | 466 GPRRegister src) { |
| 476 typename Traits::GPRRegister src) { | |
| 477 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 467 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 478 emitUint8(0x66); | 468 emitUint8(0x66); |
| 479 emitRexRB(SrcTy, dst, src); | 469 emitRexRB(SrcTy, dst, src); |
| 480 emitUint8(0x0F); | 470 emitUint8(0x0F); |
| 481 emitUint8(0x6E); | 471 emitUint8(0x6E); |
| 482 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 472 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 483 } | 473 } |
| 484 | 474 |
| 485 template <class Machine> | 475 template <typename TraitsType> |
| 486 void AssemblerX86Base<Machine>::movd(Type SrcTy, | 476 void AssemblerX86Base<TraitsType>::movd(Type SrcTy, XmmRegister dst, |
| 487 typename Traits::XmmRegister dst, | 477 const Address &src) { |
| 488 const typename Traits::Address &src) { | |
| 489 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 478 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 490 emitUint8(0x66); | 479 emitUint8(0x66); |
| 491 emitAddrSizeOverridePrefix(); | 480 emitAddrSizeOverridePrefix(); |
| 492 emitRex(SrcTy, src, dst); | 481 emitRex(SrcTy, src, dst); |
| 493 emitUint8(0x0F); | 482 emitUint8(0x0F); |
| 494 emitUint8(0x6E); | 483 emitUint8(0x6E); |
| 495 emitOperand(gprEncoding(dst), src); | 484 emitOperand(gprEncoding(dst), src); |
| 496 } | 485 } |
| 497 | 486 |
| 498 template <class Machine> | 487 template <typename TraitsType> |
| 499 void AssemblerX86Base<Machine>::movd(Type DestTy, | 488 void AssemblerX86Base<TraitsType>::movd(Type DestTy, GPRRegister dst, |
| 500 typename Traits::GPRRegister dst, | 489 XmmRegister src) { |
| 501 typename Traits::XmmRegister src) { | |
| 502 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 490 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 503 emitUint8(0x66); | 491 emitUint8(0x66); |
| 504 emitRexRB(DestTy, src, dst); | 492 emitRexRB(DestTy, src, dst); |
| 505 emitUint8(0x0F); | 493 emitUint8(0x0F); |
| 506 emitUint8(0x7E); | 494 emitUint8(0x7E); |
| 507 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 495 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 508 } | 496 } |
| 509 | 497 |
| 510 template <class Machine> | 498 template <typename TraitsType> |
| 511 void AssemblerX86Base<Machine>::movd(Type DestTy, | 499 void AssemblerX86Base<TraitsType>::movd(Type DestTy, const Address &dst, |
| 512 const typename Traits::Address &dst, | 500 XmmRegister src) { |
| 513 typename Traits::XmmRegister src) { | |
| 514 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 501 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 515 emitUint8(0x66); | 502 emitUint8(0x66); |
| 516 emitAddrSizeOverridePrefix(); | 503 emitAddrSizeOverridePrefix(); |
| 517 emitRex(DestTy, dst, src); | 504 emitRex(DestTy, dst, src); |
| 518 emitUint8(0x0F); | 505 emitUint8(0x0F); |
| 519 emitUint8(0x7E); | 506 emitUint8(0x7E); |
| 520 emitOperand(gprEncoding(src), dst); | 507 emitOperand(gprEncoding(src), dst); |
| 521 } | 508 } |
| 522 | 509 |
| 523 template <class Machine> | 510 template <typename TraitsType> |
| 524 void AssemblerX86Base<Machine>::movq(typename Traits::XmmRegister dst, | 511 void AssemblerX86Base<TraitsType>::movq(XmmRegister dst, XmmRegister src) { |
| 525 typename Traits::XmmRegister src) { | |
| 526 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 512 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 527 emitUint8(0xF3); | 513 emitUint8(0xF3); |
| 528 emitRexRB(RexTypeIrrelevant, dst, src); | 514 emitRexRB(RexTypeIrrelevant, dst, src); |
| 529 emitUint8(0x0F); | 515 emitUint8(0x0F); |
| 530 emitUint8(0x7E); | 516 emitUint8(0x7E); |
| 531 emitXmmRegisterOperand(dst, src); | 517 emitXmmRegisterOperand(dst, src); |
| 532 } | 518 } |
| 533 | 519 |
| 534 template <class Machine> | 520 template <typename TraitsType> |
| 535 void AssemblerX86Base<Machine>::movq(const typename Traits::Address &dst, | 521 void AssemblerX86Base<TraitsType>::movq(const Address &dst, XmmRegister src) { |
| 536 typename Traits::XmmRegister src) { | |
| 537 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 522 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 538 emitUint8(0x66); | 523 emitUint8(0x66); |
| 539 emitAddrSizeOverridePrefix(); | 524 emitAddrSizeOverridePrefix(); |
| 540 emitRex(RexTypeIrrelevant, dst, src); | 525 emitRex(RexTypeIrrelevant, dst, src); |
| 541 emitUint8(0x0F); | 526 emitUint8(0x0F); |
| 542 emitUint8(0xD6); | 527 emitUint8(0xD6); |
| 543 emitOperand(gprEncoding(src), dst); | 528 emitOperand(gprEncoding(src), dst); |
| 544 } | 529 } |
| 545 | 530 |
| 546 template <class Machine> | 531 template <typename TraitsType> |
| 547 void AssemblerX86Base<Machine>::movq(typename Traits::XmmRegister dst, | 532 void AssemblerX86Base<TraitsType>::movq(XmmRegister dst, const Address &src) { |
| 548 const typename Traits::Address &src) { | |
| 549 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 533 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 550 emitUint8(0xF3); | 534 emitUint8(0xF3); |
| 551 emitAddrSizeOverridePrefix(); | 535 emitAddrSizeOverridePrefix(); |
| 552 emitRex(RexTypeIrrelevant, src, dst); | 536 emitRex(RexTypeIrrelevant, src, dst); |
| 553 emitUint8(0x0F); | 537 emitUint8(0x0F); |
| 554 emitUint8(0x7E); | 538 emitUint8(0x7E); |
| 555 emitOperand(gprEncoding(dst), src); | 539 emitOperand(gprEncoding(dst), src); |
| 556 } | 540 } |
| 557 | 541 |
| 558 template <class Machine> | 542 template <typename TraitsType> |
| 559 void AssemblerX86Base<Machine>::addss(Type Ty, typename Traits::XmmRegister dst, | 543 void AssemblerX86Base<TraitsType>::addss(Type Ty, XmmRegister dst, |
| 560 typename Traits::XmmRegister src) { | 544 XmmRegister src) { |
| 561 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 545 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 562 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 546 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 563 emitRexRB(RexTypeIrrelevant, dst, src); | 547 emitRexRB(RexTypeIrrelevant, dst, src); |
| 564 emitUint8(0x0F); | 548 emitUint8(0x0F); |
| 565 emitUint8(0x58); | 549 emitUint8(0x58); |
| 566 emitXmmRegisterOperand(dst, src); | 550 emitXmmRegisterOperand(dst, src); |
| 567 } | 551 } |
| 568 | 552 |
| 569 template <class Machine> | 553 template <typename TraitsType> |
| 570 void AssemblerX86Base<Machine>::addss(Type Ty, typename Traits::XmmRegister dst, | 554 void AssemblerX86Base<TraitsType>::addss(Type Ty, XmmRegister dst, |
| 571 const typename Traits::Address &src) { | 555 const Address &src) { |
| 572 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 556 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 573 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 557 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 574 emitAddrSizeOverridePrefix(); | 558 emitAddrSizeOverridePrefix(); |
| 575 emitRex(RexTypeIrrelevant, src, dst); | 559 emitRex(RexTypeIrrelevant, src, dst); |
| 576 emitUint8(0x0F); | 560 emitUint8(0x0F); |
| 577 emitUint8(0x58); | 561 emitUint8(0x58); |
| 578 emitOperand(gprEncoding(dst), src); | 562 emitOperand(gprEncoding(dst), src); |
| 579 } | 563 } |
| 580 | 564 |
| 581 template <class Machine> | 565 template <typename TraitsType> |
| 582 void AssemblerX86Base<Machine>::subss(Type Ty, typename Traits::XmmRegister dst, | 566 void AssemblerX86Base<TraitsType>::subss(Type Ty, XmmRegister dst, |
| 583 typename Traits::XmmRegister src) { | 567 XmmRegister src) { |
| 584 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 568 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 585 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 569 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 586 emitRexRB(RexTypeIrrelevant, dst, src); | 570 emitRexRB(RexTypeIrrelevant, dst, src); |
| 587 emitUint8(0x0F); | 571 emitUint8(0x0F); |
| 588 emitUint8(0x5C); | 572 emitUint8(0x5C); |
| 589 emitXmmRegisterOperand(dst, src); | 573 emitXmmRegisterOperand(dst, src); |
| 590 } | 574 } |
| 591 | 575 |
| 592 template <class Machine> | 576 template <typename TraitsType> |
| 593 void AssemblerX86Base<Machine>::subss(Type Ty, typename Traits::XmmRegister dst, | 577 void AssemblerX86Base<TraitsType>::subss(Type Ty, XmmRegister dst, |
| 594 const typename Traits::Address &src) { | 578 const Address &src) { |
| 595 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 579 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 596 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 580 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 597 emitAddrSizeOverridePrefix(); | 581 emitAddrSizeOverridePrefix(); |
| 598 emitRex(RexTypeIrrelevant, src, dst); | 582 emitRex(RexTypeIrrelevant, src, dst); |
| 599 emitUint8(0x0F); | 583 emitUint8(0x0F); |
| 600 emitUint8(0x5C); | 584 emitUint8(0x5C); |
| 601 emitOperand(gprEncoding(dst), src); | 585 emitOperand(gprEncoding(dst), src); |
| 602 } | 586 } |
| 603 | 587 |
| 604 template <class Machine> | 588 template <typename TraitsType> |
| 605 void AssemblerX86Base<Machine>::mulss(Type Ty, typename Traits::XmmRegister dst, | 589 void AssemblerX86Base<TraitsType>::mulss(Type Ty, XmmRegister dst, |
| 606 typename Traits::XmmRegister src) { | 590 XmmRegister src) { |
| 607 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 591 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 608 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 592 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 609 emitRexRB(RexTypeIrrelevant, dst, src); | 593 emitRexRB(RexTypeIrrelevant, dst, src); |
| 610 emitUint8(0x0F); | 594 emitUint8(0x0F); |
| 611 emitUint8(0x59); | 595 emitUint8(0x59); |
| 612 emitXmmRegisterOperand(dst, src); | 596 emitXmmRegisterOperand(dst, src); |
| 613 } | 597 } |
| 614 | 598 |
| 615 template <class Machine> | 599 template <typename TraitsType> |
| 616 void AssemblerX86Base<Machine>::mulss(Type Ty, typename Traits::XmmRegister dst, | 600 void AssemblerX86Base<TraitsType>::mulss(Type Ty, XmmRegister dst, |
| 617 const typename Traits::Address &src) { | 601 const Address &src) { |
| 618 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 602 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 619 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 603 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 620 emitAddrSizeOverridePrefix(); | 604 emitAddrSizeOverridePrefix(); |
| 621 emitRex(RexTypeIrrelevant, src, dst); | 605 emitRex(RexTypeIrrelevant, src, dst); |
| 622 emitUint8(0x0F); | 606 emitUint8(0x0F); |
| 623 emitUint8(0x59); | 607 emitUint8(0x59); |
| 624 emitOperand(gprEncoding(dst), src); | 608 emitOperand(gprEncoding(dst), src); |
| 625 } | 609 } |
| 626 | 610 |
| 627 template <class Machine> | 611 template <typename TraitsType> |
| 628 void AssemblerX86Base<Machine>::divss(Type Ty, typename Traits::XmmRegister dst, | 612 void AssemblerX86Base<TraitsType>::divss(Type Ty, XmmRegister dst, |
| 629 typename Traits::XmmRegister src) { | 613 XmmRegister src) { |
| 630 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 614 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 631 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 615 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 632 emitRexRB(RexTypeIrrelevant, dst, src); | 616 emitRexRB(RexTypeIrrelevant, dst, src); |
| 633 emitUint8(0x0F); | 617 emitUint8(0x0F); |
| 634 emitUint8(0x5E); | 618 emitUint8(0x5E); |
| 635 emitXmmRegisterOperand(dst, src); | 619 emitXmmRegisterOperand(dst, src); |
| 636 } | 620 } |
| 637 | 621 |
| 638 template <class Machine> | 622 template <typename TraitsType> |
| 639 void AssemblerX86Base<Machine>::divss(Type Ty, typename Traits::XmmRegister dst, | 623 void AssemblerX86Base<TraitsType>::divss(Type Ty, XmmRegister dst, |
| 640 const typename Traits::Address &src) { | 624 const Address &src) { |
| 641 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 625 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 642 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 626 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 643 emitAddrSizeOverridePrefix(); | 627 emitAddrSizeOverridePrefix(); |
| 644 emitRex(RexTypeIrrelevant, src, dst); | 628 emitRex(RexTypeIrrelevant, src, dst); |
| 645 emitUint8(0x0F); | 629 emitUint8(0x0F); |
| 646 emitUint8(0x5E); | 630 emitUint8(0x5E); |
| 647 emitOperand(gprEncoding(dst), src); | 631 emitOperand(gprEncoding(dst), src); |
| 648 } | 632 } |
| 649 | 633 |
| 650 template <class Machine> | 634 template <typename TraitsType> |
| 651 template <typename T, typename> | 635 template <typename T, typename> |
| 652 void AssemblerX86Base<Machine>::fld(Type Ty, const typename T::Address &src) { | 636 void AssemblerX86Base<TraitsType>::fld(Type Ty, |
| 637 const typename T::Address &src) { |
| 653 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 638 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 654 emitAddrSizeOverridePrefix(); | 639 emitAddrSizeOverridePrefix(); |
| 655 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD); | 640 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD); |
| 656 emitOperand(0, src); | 641 emitOperand(0, src); |
| 657 } | 642 } |
| 658 | 643 |
| 659 template <class Machine> | 644 template <typename TraitsType> |
| 660 template <typename T, typename> | 645 template <typename T, typename> |
| 661 void AssemblerX86Base<Machine>::fstp(Type Ty, const typename T::Address &dst) { | 646 void AssemblerX86Base<TraitsType>::fstp(Type Ty, |
| 647 const typename T::Address &dst) { |
| 662 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 648 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 663 emitAddrSizeOverridePrefix(); | 649 emitAddrSizeOverridePrefix(); |
| 664 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD); | 650 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xD9 : 0xDD); |
| 665 emitOperand(3, dst); | 651 emitOperand(3, dst); |
| 666 } | 652 } |
| 667 | 653 |
| 668 template <class Machine> | 654 template <typename TraitsType> |
| 669 template <typename T, typename> | 655 template <typename T, typename> |
| 670 void AssemblerX86Base<Machine>::fstp(typename T::X87STRegister st) { | 656 void AssemblerX86Base<TraitsType>::fstp(typename T::X87STRegister st) { |
| 671 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 657 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 672 emitUint8(0xDD); | 658 emitUint8(0xDD); |
| 673 emitUint8(0xD8 + st); | 659 emitUint8(0xD8 + st); |
| 674 } | 660 } |
| 675 | 661 |
| 676 template <class Machine> | 662 template <typename TraitsType> |
| 677 void AssemblerX86Base<Machine>::movaps(typename Traits::XmmRegister dst, | 663 void AssemblerX86Base<TraitsType>::movaps(XmmRegister dst, XmmRegister src) { |
| 678 typename Traits::XmmRegister src) { | |
| 679 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 664 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 680 emitRexRB(RexTypeIrrelevant, dst, src); | 665 emitRexRB(RexTypeIrrelevant, dst, src); |
| 681 emitUint8(0x0F); | 666 emitUint8(0x0F); |
| 682 emitUint8(0x28); | 667 emitUint8(0x28); |
| 683 emitXmmRegisterOperand(dst, src); | 668 emitXmmRegisterOperand(dst, src); |
| 684 } | 669 } |
| 685 | 670 |
| 686 template <class Machine> | 671 template <typename TraitsType> |
| 687 void AssemblerX86Base<Machine>::movups(typename Traits::XmmRegister dst, | 672 void AssemblerX86Base<TraitsType>::movups(XmmRegister dst, XmmRegister src) { |
| 688 typename Traits::XmmRegister src) { | |
| 689 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 673 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 690 emitRexRB(RexTypeIrrelevant, dst, src); | 674 emitRexRB(RexTypeIrrelevant, dst, src); |
| 691 emitUint8(0x0F); | 675 emitUint8(0x0F); |
| 692 emitUint8(0x10); | 676 emitUint8(0x10); |
| 693 emitXmmRegisterOperand(dst, src); | 677 emitXmmRegisterOperand(dst, src); |
| 694 } | 678 } |
| 695 | 679 |
| 696 template <class Machine> | 680 template <typename TraitsType> |
| 697 void AssemblerX86Base<Machine>::movups(typename Traits::XmmRegister dst, | 681 void AssemblerX86Base<TraitsType>::movups(XmmRegister dst, const Address &src) { |
| 698 const typename Traits::Address &src) { | |
| 699 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 682 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 700 emitAddrSizeOverridePrefix(); | 683 emitAddrSizeOverridePrefix(); |
| 701 emitRex(RexTypeIrrelevant, src, dst); | 684 emitRex(RexTypeIrrelevant, src, dst); |
| 702 emitUint8(0x0F); | 685 emitUint8(0x0F); |
| 703 emitUint8(0x10); | 686 emitUint8(0x10); |
| 704 emitOperand(gprEncoding(dst), src); | 687 emitOperand(gprEncoding(dst), src); |
| 705 } | 688 } |
| 706 | 689 |
| 707 template <class Machine> | 690 template <typename TraitsType> |
| 708 void AssemblerX86Base<Machine>::movups(const typename Traits::Address &dst, | 691 void AssemblerX86Base<TraitsType>::movups(const Address &dst, XmmRegister src) { |
| 709 typename Traits::XmmRegister src) { | |
| 710 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 692 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 711 emitAddrSizeOverridePrefix(); | 693 emitAddrSizeOverridePrefix(); |
| 712 emitRex(RexTypeIrrelevant, dst, src); | 694 emitRex(RexTypeIrrelevant, dst, src); |
| 713 emitUint8(0x0F); | 695 emitUint8(0x0F); |
| 714 emitUint8(0x11); | 696 emitUint8(0x11); |
| 715 emitOperand(gprEncoding(src), dst); | 697 emitOperand(gprEncoding(src), dst); |
| 716 } | 698 } |
| 717 | 699 |
| 718 template <class Machine> | 700 template <typename TraitsType> |
| 719 void AssemblerX86Base<Machine>::padd(Type Ty, typename Traits::XmmRegister dst, | 701 void AssemblerX86Base<TraitsType>::padd(Type Ty, XmmRegister dst, |
| 720 typename Traits::XmmRegister src) { | 702 XmmRegister src) { |
| 721 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 703 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 722 emitUint8(0x66); | 704 emitUint8(0x66); |
| 723 emitRexRB(RexTypeIrrelevant, dst, src); | 705 emitRexRB(RexTypeIrrelevant, dst, src); |
| 724 emitUint8(0x0F); | 706 emitUint8(0x0F); |
| 725 if (isByteSizedArithType(Ty)) { | 707 if (isByteSizedArithType(Ty)) { |
| 726 emitUint8(0xFC); | 708 emitUint8(0xFC); |
| 727 } else if (Ty == IceType_i16) { | 709 } else if (Ty == IceType_i16) { |
| 728 emitUint8(0xFD); | 710 emitUint8(0xFD); |
| 729 } else { | 711 } else { |
| 730 emitUint8(0xFE); | 712 emitUint8(0xFE); |
| 731 } | 713 } |
| 732 emitXmmRegisterOperand(dst, src); | 714 emitXmmRegisterOperand(dst, src); |
| 733 } | 715 } |
| 734 | 716 |
| 735 template <class Machine> | 717 template <typename TraitsType> |
| 736 void AssemblerX86Base<Machine>::padd(Type Ty, typename Traits::XmmRegister dst, | 718 void AssemblerX86Base<TraitsType>::padd(Type Ty, XmmRegister dst, |
| 737 const typename Traits::Address &src) { | 719 const Address &src) { |
| 738 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 720 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 739 emitUint8(0x66); | 721 emitUint8(0x66); |
| 740 emitAddrSizeOverridePrefix(); | 722 emitAddrSizeOverridePrefix(); |
| 741 emitRex(RexTypeIrrelevant, src, dst); | 723 emitRex(RexTypeIrrelevant, src, dst); |
| 742 emitUint8(0x0F); | 724 emitUint8(0x0F); |
| 743 if (isByteSizedArithType(Ty)) { | 725 if (isByteSizedArithType(Ty)) { |
| 744 emitUint8(0xFC); | 726 emitUint8(0xFC); |
| 745 } else if (Ty == IceType_i16) { | 727 } else if (Ty == IceType_i16) { |
| 746 emitUint8(0xFD); | 728 emitUint8(0xFD); |
| 747 } else { | 729 } else { |
| 748 emitUint8(0xFE); | 730 emitUint8(0xFE); |
| 749 } | 731 } |
| 750 emitOperand(gprEncoding(dst), src); | 732 emitOperand(gprEncoding(dst), src); |
| 751 } | 733 } |
| 752 | 734 |
| 753 template <class Machine> | 735 template <typename TraitsType> |
| 754 void AssemblerX86Base<Machine>::pand(Type /* Ty */, | 736 void AssemblerX86Base<TraitsType>::pand(Type /* Ty */, XmmRegister dst, |
| 755 typename Traits::XmmRegister dst, | 737 XmmRegister src) { |
| 756 typename Traits::XmmRegister src) { | |
| 757 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 738 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 758 emitUint8(0x66); | 739 emitUint8(0x66); |
| 759 emitRexRB(RexTypeIrrelevant, dst, src); | 740 emitRexRB(RexTypeIrrelevant, dst, src); |
| 760 emitUint8(0x0F); | 741 emitUint8(0x0F); |
| 761 emitUint8(0xDB); | 742 emitUint8(0xDB); |
| 762 emitXmmRegisterOperand(dst, src); | 743 emitXmmRegisterOperand(dst, src); |
| 763 } | 744 } |
| 764 | 745 |
| 765 template <class Machine> | 746 template <typename TraitsType> |
| 766 void AssemblerX86Base<Machine>::pand(Type /* Ty */, | 747 void AssemblerX86Base<TraitsType>::pand(Type /* Ty */, XmmRegister dst, |
| 767 typename Traits::XmmRegister dst, | 748 const Address &src) { |
| 768 const typename Traits::Address &src) { | |
| 769 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 749 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 770 emitUint8(0x66); | 750 emitUint8(0x66); |
| 771 emitAddrSizeOverridePrefix(); | 751 emitAddrSizeOverridePrefix(); |
| 772 emitRex(RexTypeIrrelevant, src, dst); | 752 emitRex(RexTypeIrrelevant, src, dst); |
| 773 emitUint8(0x0F); | 753 emitUint8(0x0F); |
| 774 emitUint8(0xDB); | 754 emitUint8(0xDB); |
| 775 emitOperand(gprEncoding(dst), src); | 755 emitOperand(gprEncoding(dst), src); |
| 776 } | 756 } |
| 777 | 757 |
| 778 template <class Machine> | 758 template <typename TraitsType> |
| 779 void AssemblerX86Base<Machine>::pandn(Type /* Ty */, | 759 void AssemblerX86Base<TraitsType>::pandn(Type /* Ty */, XmmRegister dst, |
| 780 typename Traits::XmmRegister dst, | 760 XmmRegister src) { |
| 781 typename Traits::XmmRegister src) { | |
| 782 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 761 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 783 emitUint8(0x66); | 762 emitUint8(0x66); |
| 784 emitRexRB(RexTypeIrrelevant, dst, src); | 763 emitRexRB(RexTypeIrrelevant, dst, src); |
| 785 emitUint8(0x0F); | 764 emitUint8(0x0F); |
| 786 emitUint8(0xDF); | 765 emitUint8(0xDF); |
| 787 emitXmmRegisterOperand(dst, src); | 766 emitXmmRegisterOperand(dst, src); |
| 788 } | 767 } |
| 789 | 768 |
| 790 template <class Machine> | 769 template <typename TraitsType> |
| 791 void AssemblerX86Base<Machine>::pandn(Type /* Ty */, | 770 void AssemblerX86Base<TraitsType>::pandn(Type /* Ty */, XmmRegister dst, |
| 792 typename Traits::XmmRegister dst, | 771 const Address &src) { |
| 793 const typename Traits::Address &src) { | |
| 794 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 772 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 795 emitUint8(0x66); | 773 emitUint8(0x66); |
| 796 emitAddrSizeOverridePrefix(); | 774 emitAddrSizeOverridePrefix(); |
| 797 emitRex(RexTypeIrrelevant, src, dst); | 775 emitRex(RexTypeIrrelevant, src, dst); |
| 798 emitUint8(0x0F); | 776 emitUint8(0x0F); |
| 799 emitUint8(0xDF); | 777 emitUint8(0xDF); |
| 800 emitOperand(gprEncoding(dst), src); | 778 emitOperand(gprEncoding(dst), src); |
| 801 } | 779 } |
| 802 | 780 |
| 803 template <class Machine> | 781 template <typename TraitsType> |
| 804 void AssemblerX86Base<Machine>::pmull(Type Ty, typename Traits::XmmRegister dst, | 782 void AssemblerX86Base<TraitsType>::pmull(Type Ty, XmmRegister dst, |
| 805 typename Traits::XmmRegister src) { | 783 XmmRegister src) { |
| 806 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 784 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 807 emitUint8(0x66); | 785 emitUint8(0x66); |
| 808 emitRexRB(RexTypeIrrelevant, dst, src); | 786 emitRexRB(RexTypeIrrelevant, dst, src); |
| 809 emitUint8(0x0F); | 787 emitUint8(0x0F); |
| 810 if (Ty == IceType_i16) { | 788 if (Ty == IceType_i16) { |
| 811 emitUint8(0xD5); | 789 emitUint8(0xD5); |
| 812 } else { | 790 } else { |
| 813 assert(Ty == IceType_i32); | 791 assert(Ty == IceType_i32); |
| 814 emitUint8(0x38); | 792 emitUint8(0x38); |
| 815 emitUint8(0x40); | 793 emitUint8(0x40); |
| 816 } | 794 } |
| 817 emitXmmRegisterOperand(dst, src); | 795 emitXmmRegisterOperand(dst, src); |
| 818 } | 796 } |
| 819 | 797 |
| 820 template <class Machine> | 798 template <typename TraitsType> |
| 821 void AssemblerX86Base<Machine>::pmull(Type Ty, typename Traits::XmmRegister dst, | 799 void AssemblerX86Base<TraitsType>::pmull(Type Ty, XmmRegister dst, |
| 822 const typename Traits::Address &src) { | 800 const Address &src) { |
| 823 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 801 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 824 emitUint8(0x66); | 802 emitUint8(0x66); |
| 825 emitAddrSizeOverridePrefix(); | 803 emitAddrSizeOverridePrefix(); |
| 826 emitRex(RexTypeIrrelevant, src, dst); | 804 emitRex(RexTypeIrrelevant, src, dst); |
| 827 emitUint8(0x0F); | 805 emitUint8(0x0F); |
| 828 if (Ty == IceType_i16) { | 806 if (Ty == IceType_i16) { |
| 829 emitUint8(0xD5); | 807 emitUint8(0xD5); |
| 830 } else { | 808 } else { |
| 831 assert(Ty == IceType_i32); | 809 assert(Ty == IceType_i32); |
| 832 emitUint8(0x38); | 810 emitUint8(0x38); |
| 833 emitUint8(0x40); | 811 emitUint8(0x40); |
| 834 } | 812 } |
| 835 emitOperand(gprEncoding(dst), src); | 813 emitOperand(gprEncoding(dst), src); |
| 836 } | 814 } |
| 837 | 815 |
| 838 template <class Machine> | 816 template <typename TraitsType> |
| 839 void AssemblerX86Base<Machine>::pmuludq(Type /* Ty */, | 817 void AssemblerX86Base<TraitsType>::pmuludq(Type /* Ty */, XmmRegister dst, |
| 840 typename Traits::XmmRegister dst, | 818 XmmRegister src) { |
| 841 typename Traits::XmmRegister src) { | |
| 842 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 819 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 843 emitUint8(0x66); | 820 emitUint8(0x66); |
| 844 emitRexRB(RexTypeIrrelevant, dst, src); | 821 emitRexRB(RexTypeIrrelevant, dst, src); |
| 845 emitUint8(0x0F); | 822 emitUint8(0x0F); |
| 846 emitUint8(0xF4); | 823 emitUint8(0xF4); |
| 847 emitXmmRegisterOperand(dst, src); | 824 emitXmmRegisterOperand(dst, src); |
| 848 } | 825 } |
| 849 | 826 |
| 850 template <class Machine> | 827 template <typename TraitsType> |
| 851 void AssemblerX86Base<Machine>::pmuludq(Type /* Ty */, | 828 void AssemblerX86Base<TraitsType>::pmuludq(Type /* Ty */, XmmRegister dst, |
| 852 typename Traits::XmmRegister dst, | 829 const Address &src) { |
| 853 const typename Traits::Address &src) { | |
| 854 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 830 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 855 emitUint8(0x66); | 831 emitUint8(0x66); |
| 856 emitAddrSizeOverridePrefix(); | 832 emitAddrSizeOverridePrefix(); |
| 857 emitRex(RexTypeIrrelevant, src, dst); | 833 emitRex(RexTypeIrrelevant, src, dst); |
| 858 emitUint8(0x0F); | 834 emitUint8(0x0F); |
| 859 emitUint8(0xF4); | 835 emitUint8(0xF4); |
| 860 emitOperand(gprEncoding(dst), src); | 836 emitOperand(gprEncoding(dst), src); |
| 861 } | 837 } |
| 862 | 838 |
| 863 template <class Machine> | 839 template <typename TraitsType> |
| 864 void AssemblerX86Base<Machine>::por(Type /* Ty */, | 840 void AssemblerX86Base<TraitsType>::por(Type /* Ty */, XmmRegister dst, |
| 865 typename Traits::XmmRegister dst, | 841 XmmRegister src) { |
| 866 typename Traits::XmmRegister src) { | |
| 867 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 842 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 868 emitUint8(0x66); | 843 emitUint8(0x66); |
| 869 emitRexRB(RexTypeIrrelevant, dst, src); | 844 emitRexRB(RexTypeIrrelevant, dst, src); |
| 870 emitUint8(0x0F); | 845 emitUint8(0x0F); |
| 871 emitUint8(0xEB); | 846 emitUint8(0xEB); |
| 872 emitXmmRegisterOperand(dst, src); | 847 emitXmmRegisterOperand(dst, src); |
| 873 } | 848 } |
| 874 | 849 |
| 875 template <class Machine> | 850 template <typename TraitsType> |
| 876 void AssemblerX86Base<Machine>::por(Type /* Ty */, | 851 void AssemblerX86Base<TraitsType>::por(Type /* Ty */, XmmRegister dst, |
| 877 typename Traits::XmmRegister dst, | 852 const Address &src) { |
| 878 const typename Traits::Address &src) { | |
| 879 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 853 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 880 emitUint8(0x66); | 854 emitUint8(0x66); |
| 881 emitAddrSizeOverridePrefix(); | 855 emitAddrSizeOverridePrefix(); |
| 882 emitRex(RexTypeIrrelevant, src, dst); | 856 emitRex(RexTypeIrrelevant, src, dst); |
| 883 emitUint8(0x0F); | 857 emitUint8(0x0F); |
| 884 emitUint8(0xEB); | 858 emitUint8(0xEB); |
| 885 emitOperand(gprEncoding(dst), src); | 859 emitOperand(gprEncoding(dst), src); |
| 886 } | 860 } |
| 887 | 861 |
| 888 template <class Machine> | 862 template <typename TraitsType> |
| 889 void AssemblerX86Base<Machine>::psub(Type Ty, typename Traits::XmmRegister dst, | 863 void AssemblerX86Base<TraitsType>::psub(Type Ty, XmmRegister dst, |
| 890 typename Traits::XmmRegister src) { | 864 XmmRegister src) { |
| 891 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 865 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 892 emitUint8(0x66); | 866 emitUint8(0x66); |
| 893 emitRexRB(RexTypeIrrelevant, dst, src); | 867 emitRexRB(RexTypeIrrelevant, dst, src); |
| 894 emitUint8(0x0F); | 868 emitUint8(0x0F); |
| 895 if (isByteSizedArithType(Ty)) { | 869 if (isByteSizedArithType(Ty)) { |
| 896 emitUint8(0xF8); | 870 emitUint8(0xF8); |
| 897 } else if (Ty == IceType_i16) { | 871 } else if (Ty == IceType_i16) { |
| 898 emitUint8(0xF9); | 872 emitUint8(0xF9); |
| 899 } else { | 873 } else { |
| 900 emitUint8(0xFA); | 874 emitUint8(0xFA); |
| 901 } | 875 } |
| 902 emitXmmRegisterOperand(dst, src); | 876 emitXmmRegisterOperand(dst, src); |
| 903 } | 877 } |
| 904 | 878 |
| 905 template <class Machine> | 879 template <typename TraitsType> |
| 906 void AssemblerX86Base<Machine>::psub(Type Ty, typename Traits::XmmRegister dst, | 880 void AssemblerX86Base<TraitsType>::psub(Type Ty, XmmRegister dst, |
| 907 const typename Traits::Address &src) { | 881 const Address &src) { |
| 908 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 882 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 909 emitUint8(0x66); | 883 emitUint8(0x66); |
| 910 emitAddrSizeOverridePrefix(); | 884 emitAddrSizeOverridePrefix(); |
| 911 emitRex(RexTypeIrrelevant, src, dst); | 885 emitRex(RexTypeIrrelevant, src, dst); |
| 912 emitUint8(0x0F); | 886 emitUint8(0x0F); |
| 913 if (isByteSizedArithType(Ty)) { | 887 if (isByteSizedArithType(Ty)) { |
| 914 emitUint8(0xF8); | 888 emitUint8(0xF8); |
| 915 } else if (Ty == IceType_i16) { | 889 } else if (Ty == IceType_i16) { |
| 916 emitUint8(0xF9); | 890 emitUint8(0xF9); |
| 917 } else { | 891 } else { |
| 918 emitUint8(0xFA); | 892 emitUint8(0xFA); |
| 919 } | 893 } |
| 920 emitOperand(gprEncoding(dst), src); | 894 emitOperand(gprEncoding(dst), src); |
| 921 } | 895 } |
| 922 | 896 |
| 923 template <class Machine> | 897 template <typename TraitsType> |
| 924 void AssemblerX86Base<Machine>::pxor(Type /* Ty */, | 898 void AssemblerX86Base<TraitsType>::pxor(Type /* Ty */, XmmRegister dst, |
| 925 typename Traits::XmmRegister dst, | 899 XmmRegister src) { |
| 926 typename Traits::XmmRegister src) { | |
| 927 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 900 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 928 emitUint8(0x66); | 901 emitUint8(0x66); |
| 929 emitRexRB(RexTypeIrrelevant, dst, src); | 902 emitRexRB(RexTypeIrrelevant, dst, src); |
| 930 emitUint8(0x0F); | 903 emitUint8(0x0F); |
| 931 emitUint8(0xEF); | 904 emitUint8(0xEF); |
| 932 emitXmmRegisterOperand(dst, src); | 905 emitXmmRegisterOperand(dst, src); |
| 933 } | 906 } |
| 934 | 907 |
| 935 template <class Machine> | 908 template <typename TraitsType> |
| 936 void AssemblerX86Base<Machine>::pxor(Type /* Ty */, | 909 void AssemblerX86Base<TraitsType>::pxor(Type /* Ty */, XmmRegister dst, |
| 937 typename Traits::XmmRegister dst, | 910 const Address &src) { |
| 938 const typename Traits::Address &src) { | |
| 939 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 911 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 940 emitUint8(0x66); | 912 emitUint8(0x66); |
| 941 emitAddrSizeOverridePrefix(); | 913 emitAddrSizeOverridePrefix(); |
| 942 emitRex(RexTypeIrrelevant, src, dst); | 914 emitRex(RexTypeIrrelevant, src, dst); |
| 943 emitUint8(0x0F); | 915 emitUint8(0x0F); |
| 944 emitUint8(0xEF); | 916 emitUint8(0xEF); |
| 945 emitOperand(gprEncoding(dst), src); | 917 emitOperand(gprEncoding(dst), src); |
| 946 } | 918 } |
| 947 | 919 |
| 948 template <class Machine> | 920 template <typename TraitsType> |
| 949 void AssemblerX86Base<Machine>::psll(Type Ty, typename Traits::XmmRegister dst, | 921 void AssemblerX86Base<TraitsType>::psll(Type Ty, XmmRegister dst, |
| 950 typename Traits::XmmRegister src) { | 922 XmmRegister src) { |
| 951 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 923 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 952 emitUint8(0x66); | 924 emitUint8(0x66); |
| 953 emitRexRB(RexTypeIrrelevant, dst, src); | 925 emitRexRB(RexTypeIrrelevant, dst, src); |
| 954 emitUint8(0x0F); | 926 emitUint8(0x0F); |
| 955 if (Ty == IceType_i16) { | 927 if (Ty == IceType_i16) { |
| 956 emitUint8(0xF1); | 928 emitUint8(0xF1); |
| 957 } else { | 929 } else { |
| 958 assert(Ty == IceType_i32); | 930 assert(Ty == IceType_i32); |
| 959 emitUint8(0xF2); | 931 emitUint8(0xF2); |
| 960 } | 932 } |
| 961 emitXmmRegisterOperand(dst, src); | 933 emitXmmRegisterOperand(dst, src); |
| 962 } | 934 } |
| 963 | 935 |
| 964 template <class Machine> | 936 template <typename TraitsType> |
| 965 void AssemblerX86Base<Machine>::psll(Type Ty, typename Traits::XmmRegister dst, | 937 void AssemblerX86Base<TraitsType>::psll(Type Ty, XmmRegister dst, |
| 966 const typename Traits::Address &src) { | 938 const Address &src) { |
| 967 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 939 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 968 emitUint8(0x66); | 940 emitUint8(0x66); |
| 969 emitAddrSizeOverridePrefix(); | 941 emitAddrSizeOverridePrefix(); |
| 970 emitRex(RexTypeIrrelevant, src, dst); | 942 emitRex(RexTypeIrrelevant, src, dst); |
| 971 emitUint8(0x0F); | 943 emitUint8(0x0F); |
| 972 if (Ty == IceType_i16) { | 944 if (Ty == IceType_i16) { |
| 973 emitUint8(0xF1); | 945 emitUint8(0xF1); |
| 974 } else { | 946 } else { |
| 975 assert(Ty == IceType_i32); | 947 assert(Ty == IceType_i32); |
| 976 emitUint8(0xF2); | 948 emitUint8(0xF2); |
| 977 } | 949 } |
| 978 emitOperand(gprEncoding(dst), src); | 950 emitOperand(gprEncoding(dst), src); |
| 979 } | 951 } |
| 980 | 952 |
| 981 template <class Machine> | 953 template <typename TraitsType> |
| 982 void AssemblerX86Base<Machine>::psll(Type Ty, typename Traits::XmmRegister dst, | 954 void AssemblerX86Base<TraitsType>::psll(Type Ty, XmmRegister dst, |
| 983 const Immediate &imm) { | 955 const Immediate &imm) { |
| 984 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 956 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 985 assert(imm.is_int8()); | 957 assert(imm.is_int8()); |
| 986 emitUint8(0x66); | 958 emitUint8(0x66); |
| 987 emitRexB(RexTypeIrrelevant, dst); | 959 emitRexB(RexTypeIrrelevant, dst); |
| 988 emitUint8(0x0F); | 960 emitUint8(0x0F); |
| 989 if (Ty == IceType_i16) { | 961 if (Ty == IceType_i16) { |
| 990 emitUint8(0x71); | 962 emitUint8(0x71); |
| 991 } else { | 963 } else { |
| 992 assert(Ty == IceType_i32); | 964 assert(Ty == IceType_i32); |
| 993 emitUint8(0x72); | 965 emitUint8(0x72); |
| 994 } | 966 } |
| 995 emitRegisterOperand(6, gprEncoding(dst)); | 967 emitRegisterOperand(6, gprEncoding(dst)); |
| 996 emitUint8(imm.value() & 0xFF); | 968 emitUint8(imm.value() & 0xFF); |
| 997 } | 969 } |
| 998 | 970 |
| 999 template <class Machine> | 971 template <typename TraitsType> |
| 1000 void AssemblerX86Base<Machine>::psra(Type Ty, typename Traits::XmmRegister dst, | 972 void AssemblerX86Base<TraitsType>::psra(Type Ty, XmmRegister dst, |
| 1001 typename Traits::XmmRegister src) { | 973 XmmRegister src) { |
| 1002 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 974 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1003 emitUint8(0x66); | 975 emitUint8(0x66); |
| 1004 emitRexRB(RexTypeIrrelevant, dst, src); | 976 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1005 emitUint8(0x0F); | 977 emitUint8(0x0F); |
| 1006 if (Ty == IceType_i16) { | 978 if (Ty == IceType_i16) { |
| 1007 emitUint8(0xE1); | 979 emitUint8(0xE1); |
| 1008 } else { | 980 } else { |
| 1009 assert(Ty == IceType_i32); | 981 assert(Ty == IceType_i32); |
| 1010 emitUint8(0xE2); | 982 emitUint8(0xE2); |
| 1011 } | 983 } |
| 1012 emitXmmRegisterOperand(dst, src); | 984 emitXmmRegisterOperand(dst, src); |
| 1013 } | 985 } |
| 1014 | 986 |
| 1015 template <class Machine> | 987 template <typename TraitsType> |
| 1016 void AssemblerX86Base<Machine>::psra(Type Ty, typename Traits::XmmRegister dst, | 988 void AssemblerX86Base<TraitsType>::psra(Type Ty, XmmRegister dst, |
| 1017 const typename Traits::Address &src) { | 989 const Address &src) { |
| 1018 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 990 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1019 emitUint8(0x66); | 991 emitUint8(0x66); |
| 1020 emitAddrSizeOverridePrefix(); | 992 emitAddrSizeOverridePrefix(); |
| 1021 emitRex(RexTypeIrrelevant, src, dst); | 993 emitRex(RexTypeIrrelevant, src, dst); |
| 1022 emitUint8(0x0F); | 994 emitUint8(0x0F); |
| 1023 if (Ty == IceType_i16) { | 995 if (Ty == IceType_i16) { |
| 1024 emitUint8(0xE1); | 996 emitUint8(0xE1); |
| 1025 } else { | 997 } else { |
| 1026 assert(Ty == IceType_i32); | 998 assert(Ty == IceType_i32); |
| 1027 emitUint8(0xE2); | 999 emitUint8(0xE2); |
| 1028 } | 1000 } |
| 1029 emitOperand(gprEncoding(dst), src); | 1001 emitOperand(gprEncoding(dst), src); |
| 1030 } | 1002 } |
| 1031 | 1003 |
| 1032 template <class Machine> | 1004 template <typename TraitsType> |
| 1033 void AssemblerX86Base<Machine>::psra(Type Ty, typename Traits::XmmRegister dst, | 1005 void AssemblerX86Base<TraitsType>::psra(Type Ty, XmmRegister dst, |
| 1034 const Immediate &imm) { | 1006 const Immediate &imm) { |
| 1035 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1007 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1036 assert(imm.is_int8()); | 1008 assert(imm.is_int8()); |
| 1037 emitUint8(0x66); | 1009 emitUint8(0x66); |
| 1038 emitRexB(RexTypeIrrelevant, dst); | 1010 emitRexB(RexTypeIrrelevant, dst); |
| 1039 emitUint8(0x0F); | 1011 emitUint8(0x0F); |
| 1040 if (Ty == IceType_i16) { | 1012 if (Ty == IceType_i16) { |
| 1041 emitUint8(0x71); | 1013 emitUint8(0x71); |
| 1042 } else { | 1014 } else { |
| 1043 assert(Ty == IceType_i32); | 1015 assert(Ty == IceType_i32); |
| 1044 emitUint8(0x72); | 1016 emitUint8(0x72); |
| 1045 } | 1017 } |
| 1046 emitRegisterOperand(4, gprEncoding(dst)); | 1018 emitRegisterOperand(4, gprEncoding(dst)); |
| 1047 emitUint8(imm.value() & 0xFF); | 1019 emitUint8(imm.value() & 0xFF); |
| 1048 } | 1020 } |
| 1049 | 1021 |
| 1050 template <class Machine> | 1022 template <typename TraitsType> |
| 1051 void AssemblerX86Base<Machine>::psrl(Type Ty, typename Traits::XmmRegister dst, | 1023 void AssemblerX86Base<TraitsType>::psrl(Type Ty, XmmRegister dst, |
| 1052 typename Traits::XmmRegister src) { | 1024 XmmRegister src) { |
| 1053 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1025 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1054 emitUint8(0x66); | 1026 emitUint8(0x66); |
| 1055 emitRexRB(RexTypeIrrelevant, dst, src); | 1027 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1056 emitUint8(0x0F); | 1028 emitUint8(0x0F); |
| 1057 if (Ty == IceType_i16) { | 1029 if (Ty == IceType_i16) { |
| 1058 emitUint8(0xD1); | 1030 emitUint8(0xD1); |
| 1059 } else if (Ty == IceType_f64) { | 1031 } else if (Ty == IceType_f64) { |
| 1060 emitUint8(0xD3); | 1032 emitUint8(0xD3); |
| 1061 } else { | 1033 } else { |
| 1062 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); | 1034 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); |
| 1063 emitUint8(0xD2); | 1035 emitUint8(0xD2); |
| 1064 } | 1036 } |
| 1065 emitXmmRegisterOperand(dst, src); | 1037 emitXmmRegisterOperand(dst, src); |
| 1066 } | 1038 } |
| 1067 | 1039 |
| 1068 template <class Machine> | 1040 template <typename TraitsType> |
| 1069 void AssemblerX86Base<Machine>::psrl(Type Ty, typename Traits::XmmRegister dst, | 1041 void AssemblerX86Base<TraitsType>::psrl(Type Ty, XmmRegister dst, |
| 1070 const typename Traits::Address &src) { | 1042 const Address &src) { |
| 1071 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1043 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1072 emitUint8(0x66); | 1044 emitUint8(0x66); |
| 1073 emitAddrSizeOverridePrefix(); | 1045 emitAddrSizeOverridePrefix(); |
| 1074 emitRex(RexTypeIrrelevant, src, dst); | 1046 emitRex(RexTypeIrrelevant, src, dst); |
| 1075 emitUint8(0x0F); | 1047 emitUint8(0x0F); |
| 1076 if (Ty == IceType_i16) { | 1048 if (Ty == IceType_i16) { |
| 1077 emitUint8(0xD1); | 1049 emitUint8(0xD1); |
| 1078 } else if (Ty == IceType_f64) { | 1050 } else if (Ty == IceType_f64) { |
| 1079 emitUint8(0xD3); | 1051 emitUint8(0xD3); |
| 1080 } else { | 1052 } else { |
| 1081 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); | 1053 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); |
| 1082 emitUint8(0xD2); | 1054 emitUint8(0xD2); |
| 1083 } | 1055 } |
| 1084 emitOperand(gprEncoding(dst), src); | 1056 emitOperand(gprEncoding(dst), src); |
| 1085 } | 1057 } |
| 1086 | 1058 |
| 1087 template <class Machine> | 1059 template <typename TraitsType> |
| 1088 void AssemblerX86Base<Machine>::psrl(Type Ty, typename Traits::XmmRegister dst, | 1060 void AssemblerX86Base<TraitsType>::psrl(Type Ty, XmmRegister dst, |
| 1089 const Immediate &imm) { | 1061 const Immediate &imm) { |
| 1090 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1062 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1091 assert(imm.is_int8()); | 1063 assert(imm.is_int8()); |
| 1092 emitUint8(0x66); | 1064 emitUint8(0x66); |
| 1093 emitRexB(RexTypeIrrelevant, dst); | 1065 emitRexB(RexTypeIrrelevant, dst); |
| 1094 emitUint8(0x0F); | 1066 emitUint8(0x0F); |
| 1095 if (Ty == IceType_i16) { | 1067 if (Ty == IceType_i16) { |
| 1096 emitUint8(0x71); | 1068 emitUint8(0x71); |
| 1097 } else if (Ty == IceType_f64) { | 1069 } else if (Ty == IceType_f64) { |
| 1098 emitUint8(0x73); | 1070 emitUint8(0x73); |
| 1099 } else { | 1071 } else { |
| 1100 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); | 1072 assert(Ty == IceType_i32 || Ty == IceType_f32 || Ty == IceType_v4f32); |
| 1101 emitUint8(0x72); | 1073 emitUint8(0x72); |
| 1102 } | 1074 } |
| 1103 emitRegisterOperand(2, gprEncoding(dst)); | 1075 emitRegisterOperand(2, gprEncoding(dst)); |
| 1104 emitUint8(imm.value() & 0xFF); | 1076 emitUint8(imm.value() & 0xFF); |
| 1105 } | 1077 } |
| 1106 | 1078 |
| 1107 // {add,sub,mul,div}ps are given a Ty parameter for consistency with | 1079 // {add,sub,mul,div}ps are given a Ty parameter for consistency with |
| 1108 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows addpd, etc., | 1080 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows addpd, etc., |
| 1109 // we can use the Ty parameter to decide on adding a 0x66 prefix. | 1081 // we can use the Ty parameter to decide on adding a 0x66 prefix. |
| 1110 template <class Machine> | 1082 template <typename TraitsType> |
| 1111 void AssemblerX86Base<Machine>::addps(Type /* Ty */, | 1083 void AssemblerX86Base<TraitsType>::addps(Type /* Ty */, XmmRegister dst, |
| 1112 typename Traits::XmmRegister dst, | 1084 XmmRegister src) { |
| 1113 typename Traits::XmmRegister src) { | |
| 1114 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1085 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1115 emitRexRB(RexTypeIrrelevant, dst, src); | 1086 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1116 emitUint8(0x0F); | 1087 emitUint8(0x0F); |
| 1117 emitUint8(0x58); | 1088 emitUint8(0x58); |
| 1118 emitXmmRegisterOperand(dst, src); | 1089 emitXmmRegisterOperand(dst, src); |
| 1119 } | 1090 } |
| 1120 | 1091 |
| 1121 template <class Machine> | 1092 template <typename TraitsType> |
| 1122 void AssemblerX86Base<Machine>::addps(Type /* Ty */, | 1093 void AssemblerX86Base<TraitsType>::addps(Type /* Ty */, XmmRegister dst, |
| 1123 typename Traits::XmmRegister dst, | 1094 const Address &src) { |
| 1124 const typename Traits::Address &src) { | |
| 1125 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1095 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1126 emitAddrSizeOverridePrefix(); | 1096 emitAddrSizeOverridePrefix(); |
| 1127 emitRex(RexTypeIrrelevant, src, dst); | 1097 emitRex(RexTypeIrrelevant, src, dst); |
| 1128 emitUint8(0x0F); | 1098 emitUint8(0x0F); |
| 1129 emitUint8(0x58); | 1099 emitUint8(0x58); |
| 1130 emitOperand(gprEncoding(dst), src); | 1100 emitOperand(gprEncoding(dst), src); |
| 1131 } | 1101 } |
| 1132 | 1102 |
| 1133 template <class Machine> | 1103 template <typename TraitsType> |
| 1134 void AssemblerX86Base<Machine>::subps(Type /* Ty */, | 1104 void AssemblerX86Base<TraitsType>::subps(Type /* Ty */, XmmRegister dst, |
| 1135 typename Traits::XmmRegister dst, | 1105 XmmRegister src) { |
| 1136 typename Traits::XmmRegister src) { | |
| 1137 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1106 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1138 emitRexRB(RexTypeIrrelevant, dst, src); | 1107 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1139 emitUint8(0x0F); | 1108 emitUint8(0x0F); |
| 1140 emitUint8(0x5C); | 1109 emitUint8(0x5C); |
| 1141 emitXmmRegisterOperand(dst, src); | 1110 emitXmmRegisterOperand(dst, src); |
| 1142 } | 1111 } |
| 1143 | 1112 |
| 1144 template <class Machine> | 1113 template <typename TraitsType> |
| 1145 void AssemblerX86Base<Machine>::subps(Type /* Ty */, | 1114 void AssemblerX86Base<TraitsType>::subps(Type /* Ty */, XmmRegister dst, |
| 1146 typename Traits::XmmRegister dst, | 1115 const Address &src) { |
| 1147 const typename Traits::Address &src) { | |
| 1148 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1116 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1149 emitAddrSizeOverridePrefix(); | 1117 emitAddrSizeOverridePrefix(); |
| 1150 emitRex(RexTypeIrrelevant, src, dst); | 1118 emitRex(RexTypeIrrelevant, src, dst); |
| 1151 emitUint8(0x0F); | 1119 emitUint8(0x0F); |
| 1152 emitUint8(0x5C); | 1120 emitUint8(0x5C); |
| 1153 emitOperand(gprEncoding(dst), src); | 1121 emitOperand(gprEncoding(dst), src); |
| 1154 } | 1122 } |
| 1155 | 1123 |
| 1156 template <class Machine> | 1124 template <typename TraitsType> |
| 1157 void AssemblerX86Base<Machine>::divps(Type /* Ty */, | 1125 void AssemblerX86Base<TraitsType>::divps(Type /* Ty */, XmmRegister dst, |
| 1158 typename Traits::XmmRegister dst, | 1126 XmmRegister src) { |
| 1159 typename Traits::XmmRegister src) { | |
| 1160 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1127 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1161 emitRexRB(RexTypeIrrelevant, dst, src); | 1128 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1162 emitUint8(0x0F); | 1129 emitUint8(0x0F); |
| 1163 emitUint8(0x5E); | 1130 emitUint8(0x5E); |
| 1164 emitXmmRegisterOperand(dst, src); | 1131 emitXmmRegisterOperand(dst, src); |
| 1165 } | 1132 } |
| 1166 | 1133 |
| 1167 template <class Machine> | 1134 template <typename TraitsType> |
| 1168 void AssemblerX86Base<Machine>::divps(Type /* Ty */, | 1135 void AssemblerX86Base<TraitsType>::divps(Type /* Ty */, XmmRegister dst, |
| 1169 typename Traits::XmmRegister dst, | 1136 const Address &src) { |
| 1170 const typename Traits::Address &src) { | |
| 1171 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1137 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1172 emitAddrSizeOverridePrefix(); | 1138 emitAddrSizeOverridePrefix(); |
| 1173 emitRex(RexTypeIrrelevant, src, dst); | 1139 emitRex(RexTypeIrrelevant, src, dst); |
| 1174 emitUint8(0x0F); | 1140 emitUint8(0x0F); |
| 1175 emitUint8(0x5E); | 1141 emitUint8(0x5E); |
| 1176 emitOperand(gprEncoding(dst), src); | 1142 emitOperand(gprEncoding(dst), src); |
| 1177 } | 1143 } |
| 1178 | 1144 |
| 1179 template <class Machine> | 1145 template <typename TraitsType> |
| 1180 void AssemblerX86Base<Machine>::mulps(Type /* Ty */, | 1146 void AssemblerX86Base<TraitsType>::mulps(Type /* Ty */, XmmRegister dst, |
| 1181 typename Traits::XmmRegister dst, | 1147 XmmRegister src) { |
| 1182 typename Traits::XmmRegister src) { | |
| 1183 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1148 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1184 emitRexRB(RexTypeIrrelevant, dst, src); | 1149 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1185 emitUint8(0x0F); | 1150 emitUint8(0x0F); |
| 1186 emitUint8(0x59); | 1151 emitUint8(0x59); |
| 1187 emitXmmRegisterOperand(dst, src); | 1152 emitXmmRegisterOperand(dst, src); |
| 1188 } | 1153 } |
| 1189 | 1154 |
| 1190 template <class Machine> | 1155 template <typename TraitsType> |
| 1191 void AssemblerX86Base<Machine>::mulps(Type /* Ty */, | 1156 void AssemblerX86Base<TraitsType>::mulps(Type /* Ty */, XmmRegister dst, |
| 1192 typename Traits::XmmRegister dst, | 1157 const Address &src) { |
| 1193 const typename Traits::Address &src) { | |
| 1194 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1158 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1195 emitAddrSizeOverridePrefix(); | 1159 emitAddrSizeOverridePrefix(); |
| 1196 emitRex(RexTypeIrrelevant, src, dst); | 1160 emitRex(RexTypeIrrelevant, src, dst); |
| 1197 emitUint8(0x0F); | 1161 emitUint8(0x0F); |
| 1198 emitUint8(0x59); | 1162 emitUint8(0x59); |
| 1199 emitOperand(gprEncoding(dst), src); | 1163 emitOperand(gprEncoding(dst), src); |
| 1200 } | 1164 } |
| 1201 | 1165 |
| 1202 template <class Machine> | 1166 template <typename TraitsType> |
| 1203 void AssemblerX86Base<Machine>::minps(Type Ty, typename Traits::XmmRegister dst, | 1167 void AssemblerX86Base<TraitsType>::minps(Type Ty, XmmRegister dst, |
| 1204 typename Traits::XmmRegister src) { | 1168 XmmRegister src) { |
| 1205 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1169 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1206 if (!isFloat32Asserting32Or64(Ty)) | 1170 if (!isFloat32Asserting32Or64(Ty)) |
| 1207 emitUint8(0x66); | 1171 emitUint8(0x66); |
| 1208 emitRexRB(RexTypeIrrelevant, dst, src); | 1172 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1209 emitUint8(0x0F); | 1173 emitUint8(0x0F); |
| 1210 emitUint8(0x5D); | 1174 emitUint8(0x5D); |
| 1211 emitXmmRegisterOperand(dst, src); | 1175 emitXmmRegisterOperand(dst, src); |
| 1212 } | 1176 } |
| 1213 | 1177 |
| 1214 template <class Machine> | 1178 template <typename TraitsType> |
| 1215 void AssemblerX86Base<Machine>::minps(Type Ty, typename Traits::XmmRegister dst, | 1179 void AssemblerX86Base<TraitsType>::minps(Type Ty, XmmRegister dst, |
| 1216 const typename Traits::Address &src) { | 1180 const Address &src) { |
| 1217 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1181 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1218 if (!isFloat32Asserting32Or64(Ty)) | 1182 if (!isFloat32Asserting32Or64(Ty)) |
| 1219 emitUint8(0x66); | 1183 emitUint8(0x66); |
| 1220 emitAddrSizeOverridePrefix(); | 1184 emitAddrSizeOverridePrefix(); |
| 1221 emitRex(RexTypeIrrelevant, src, dst); | 1185 emitRex(RexTypeIrrelevant, src, dst); |
| 1222 emitUint8(0x0F); | 1186 emitUint8(0x0F); |
| 1223 emitUint8(0x5D); | 1187 emitUint8(0x5D); |
| 1224 emitOperand(gprEncoding(dst), src); | 1188 emitOperand(gprEncoding(dst), src); |
| 1225 } | 1189 } |
| 1226 | 1190 |
| 1227 template <class Machine> | 1191 template <typename TraitsType> |
| 1228 void AssemblerX86Base<Machine>::minss(Type Ty, typename Traits::XmmRegister dst, | 1192 void AssemblerX86Base<TraitsType>::minss(Type Ty, XmmRegister dst, |
| 1229 typename Traits::XmmRegister src) { | 1193 XmmRegister src) { |
| 1230 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1194 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1231 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 1195 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 1232 emitRexRB(RexTypeIrrelevant, dst, src); | 1196 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1233 emitUint8(0x0F); | 1197 emitUint8(0x0F); |
| 1234 emitUint8(0x5D); | 1198 emitUint8(0x5D); |
| 1235 emitXmmRegisterOperand(dst, src); | 1199 emitXmmRegisterOperand(dst, src); |
| 1236 } | 1200 } |
| 1237 | 1201 |
| 1238 template <class Machine> | 1202 template <typename TraitsType> |
| 1239 void AssemblerX86Base<Machine>::minss(Type Ty, typename Traits::XmmRegister dst, | 1203 void AssemblerX86Base<TraitsType>::minss(Type Ty, XmmRegister dst, |
| 1240 const typename Traits::Address &src) { | 1204 const Address &src) { |
| 1241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1205 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1242 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 1206 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 1243 emitAddrSizeOverridePrefix(); | 1207 emitAddrSizeOverridePrefix(); |
| 1244 emitRex(RexTypeIrrelevant, src, dst); | 1208 emitRex(RexTypeIrrelevant, src, dst); |
| 1245 emitUint8(0x0F); | 1209 emitUint8(0x0F); |
| 1246 emitUint8(0x5D); | 1210 emitUint8(0x5D); |
| 1247 emitOperand(gprEncoding(dst), src); | 1211 emitOperand(gprEncoding(dst), src); |
| 1248 } | 1212 } |
| 1249 | 1213 |
| 1250 template <class Machine> | 1214 template <typename TraitsType> |
| 1251 void AssemblerX86Base<Machine>::maxps(Type Ty, typename Traits::XmmRegister dst, | 1215 void AssemblerX86Base<TraitsType>::maxps(Type Ty, XmmRegister dst, |
| 1252 typename Traits::XmmRegister src) { | 1216 XmmRegister src) { |
| 1253 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1217 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1254 if (!isFloat32Asserting32Or64(Ty)) | 1218 if (!isFloat32Asserting32Or64(Ty)) |
| 1255 emitUint8(0x66); | 1219 emitUint8(0x66); |
| 1256 emitRexRB(RexTypeIrrelevant, dst, src); | 1220 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1257 emitUint8(0x0F); | 1221 emitUint8(0x0F); |
| 1258 emitUint8(0x5F); | 1222 emitUint8(0x5F); |
| 1259 emitXmmRegisterOperand(dst, src); | 1223 emitXmmRegisterOperand(dst, src); |
| 1260 } | 1224 } |
| 1261 | 1225 |
| 1262 template <class Machine> | 1226 template <typename TraitsType> |
| 1263 void AssemblerX86Base<Machine>::maxps(Type Ty, typename Traits::XmmRegister dst, | 1227 void AssemblerX86Base<TraitsType>::maxps(Type Ty, XmmRegister dst, |
| 1264 const typename Traits::Address &src) { | 1228 const Address &src) { |
| 1265 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1229 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1266 if (!isFloat32Asserting32Or64(Ty)) | 1230 if (!isFloat32Asserting32Or64(Ty)) |
| 1267 emitUint8(0x66); | 1231 emitUint8(0x66); |
| 1268 emitAddrSizeOverridePrefix(); | 1232 emitAddrSizeOverridePrefix(); |
| 1269 emitRex(RexTypeIrrelevant, src, dst); | 1233 emitRex(RexTypeIrrelevant, src, dst); |
| 1270 emitUint8(0x0F); | 1234 emitUint8(0x0F); |
| 1271 emitUint8(0x5F); | 1235 emitUint8(0x5F); |
| 1272 emitOperand(gprEncoding(dst), src); | 1236 emitOperand(gprEncoding(dst), src); |
| 1273 } | 1237 } |
| 1274 | 1238 |
| 1275 template <class Machine> | 1239 template <typename TraitsType> |
| 1276 void AssemblerX86Base<Machine>::maxss(Type Ty, typename Traits::XmmRegister dst, | 1240 void AssemblerX86Base<TraitsType>::maxss(Type Ty, XmmRegister dst, |
| 1277 typename Traits::XmmRegister src) { | 1241 XmmRegister src) { |
| 1278 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1242 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1279 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 1243 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 1280 emitRexRB(RexTypeIrrelevant, dst, src); | 1244 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1281 emitUint8(0x0F); | 1245 emitUint8(0x0F); |
| 1282 emitUint8(0x5F); | 1246 emitUint8(0x5F); |
| 1283 emitXmmRegisterOperand(dst, src); | 1247 emitXmmRegisterOperand(dst, src); |
| 1284 } | 1248 } |
| 1285 | 1249 |
| 1286 template <class Machine> | 1250 template <typename TraitsType> |
| 1287 void AssemblerX86Base<Machine>::maxss(Type Ty, typename Traits::XmmRegister dst, | 1251 void AssemblerX86Base<TraitsType>::maxss(Type Ty, XmmRegister dst, |
| 1288 const typename Traits::Address &src) { | 1252 const Address &src) { |
| 1289 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1253 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1290 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 1254 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 1291 emitAddrSizeOverridePrefix(); | 1255 emitAddrSizeOverridePrefix(); |
| 1292 emitRex(RexTypeIrrelevant, src, dst); | 1256 emitRex(RexTypeIrrelevant, src, dst); |
| 1293 emitUint8(0x0F); | 1257 emitUint8(0x0F); |
| 1294 emitUint8(0x5F); | 1258 emitUint8(0x5F); |
| 1295 emitOperand(gprEncoding(dst), src); | 1259 emitOperand(gprEncoding(dst), src); |
| 1296 } | 1260 } |
| 1297 | 1261 |
| 1298 template <class Machine> | 1262 template <typename TraitsType> |
| 1299 void AssemblerX86Base<Machine>::andnps(Type Ty, | 1263 void AssemblerX86Base<TraitsType>::andnps(Type Ty, XmmRegister dst, |
| 1300 typename Traits::XmmRegister dst, | 1264 XmmRegister src) { |
| 1301 typename Traits::XmmRegister src) { | |
| 1302 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1265 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1303 if (!isFloat32Asserting32Or64(Ty)) | 1266 if (!isFloat32Asserting32Or64(Ty)) |
| 1304 emitUint8(0x66); | 1267 emitUint8(0x66); |
| 1305 emitRexRB(RexTypeIrrelevant, dst, src); | 1268 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1306 emitUint8(0x0F); | 1269 emitUint8(0x0F); |
| 1307 emitUint8(0x55); | 1270 emitUint8(0x55); |
| 1308 emitXmmRegisterOperand(dst, src); | 1271 emitXmmRegisterOperand(dst, src); |
| 1309 } | 1272 } |
| 1310 | 1273 |
| 1311 template <class Machine> | 1274 template <typename TraitsType> |
| 1312 void AssemblerX86Base<Machine>::andnps(Type Ty, | 1275 void AssemblerX86Base<TraitsType>::andnps(Type Ty, XmmRegister dst, |
| 1313 typename Traits::XmmRegister dst, | 1276 const Address &src) { |
| 1314 const typename Traits::Address &src) { | |
| 1315 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1277 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1316 if (!isFloat32Asserting32Or64(Ty)) | 1278 if (!isFloat32Asserting32Or64(Ty)) |
| 1317 emitUint8(0x66); | 1279 emitUint8(0x66); |
| 1318 emitAddrSizeOverridePrefix(); | 1280 emitAddrSizeOverridePrefix(); |
| 1319 emitRex(RexTypeIrrelevant, src, dst); | 1281 emitRex(RexTypeIrrelevant, src, dst); |
| 1320 emitUint8(0x0F); | 1282 emitUint8(0x0F); |
| 1321 emitUint8(0x55); | 1283 emitUint8(0x55); |
| 1322 emitOperand(gprEncoding(dst), src); | 1284 emitOperand(gprEncoding(dst), src); |
| 1323 } | 1285 } |
| 1324 | 1286 |
| 1325 template <class Machine> | 1287 template <typename TraitsType> |
| 1326 void AssemblerX86Base<Machine>::andps(Type Ty, typename Traits::XmmRegister dst, | 1288 void AssemblerX86Base<TraitsType>::andps(Type Ty, XmmRegister dst, |
| 1327 typename Traits::XmmRegister src) { | 1289 XmmRegister src) { |
| 1328 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1290 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1329 if (!isFloat32Asserting32Or64(Ty)) | 1291 if (!isFloat32Asserting32Or64(Ty)) |
| 1330 emitUint8(0x66); | 1292 emitUint8(0x66); |
| 1331 emitRexRB(RexTypeIrrelevant, dst, src); | 1293 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1332 emitUint8(0x0F); | 1294 emitUint8(0x0F); |
| 1333 emitUint8(0x54); | 1295 emitUint8(0x54); |
| 1334 emitXmmRegisterOperand(dst, src); | 1296 emitXmmRegisterOperand(dst, src); |
| 1335 } | 1297 } |
| 1336 | 1298 |
| 1337 template <class Machine> | 1299 template <typename TraitsType> |
| 1338 void AssemblerX86Base<Machine>::andps(Type Ty, typename Traits::XmmRegister dst, | 1300 void AssemblerX86Base<TraitsType>::andps(Type Ty, XmmRegister dst, |
| 1339 const typename Traits::Address &src) { | 1301 const Address &src) { |
| 1340 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1302 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1341 if (!isFloat32Asserting32Or64(Ty)) | 1303 if (!isFloat32Asserting32Or64(Ty)) |
| 1342 emitUint8(0x66); | 1304 emitUint8(0x66); |
| 1343 emitAddrSizeOverridePrefix(); | 1305 emitAddrSizeOverridePrefix(); |
| 1344 emitRex(RexTypeIrrelevant, src, dst); | 1306 emitRex(RexTypeIrrelevant, src, dst); |
| 1345 emitUint8(0x0F); | 1307 emitUint8(0x0F); |
| 1346 emitUint8(0x54); | 1308 emitUint8(0x54); |
| 1347 emitOperand(gprEncoding(dst), src); | 1309 emitOperand(gprEncoding(dst), src); |
| 1348 } | 1310 } |
| 1349 | 1311 |
| 1350 template <class Machine> | 1312 template <typename TraitsType> |
| 1351 void AssemblerX86Base<Machine>::orps(Type Ty, typename Traits::XmmRegister dst, | 1313 void AssemblerX86Base<TraitsType>::orps(Type Ty, XmmRegister dst, |
| 1352 typename Traits::XmmRegister src) { | 1314 XmmRegister src) { |
| 1353 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1315 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1354 if (!isFloat32Asserting32Or64(Ty)) | 1316 if (!isFloat32Asserting32Or64(Ty)) |
| 1355 emitUint8(0x66); | 1317 emitUint8(0x66); |
| 1356 emitRexRB(RexTypeIrrelevant, dst, src); | 1318 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1357 emitUint8(0x0F); | 1319 emitUint8(0x0F); |
| 1358 emitUint8(0x56); | 1320 emitUint8(0x56); |
| 1359 emitXmmRegisterOperand(dst, src); | 1321 emitXmmRegisterOperand(dst, src); |
| 1360 } | 1322 } |
| 1361 | 1323 |
| 1362 template <class Machine> | 1324 template <typename TraitsType> |
| 1363 void AssemblerX86Base<Machine>::orps(Type Ty, typename Traits::XmmRegister dst, | 1325 void AssemblerX86Base<TraitsType>::orps(Type Ty, XmmRegister dst, |
| 1364 const typename Traits::Address &src) { | 1326 const Address &src) { |
| 1365 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1327 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1366 if (!isFloat32Asserting32Or64(Ty)) | 1328 if (!isFloat32Asserting32Or64(Ty)) |
| 1367 emitUint8(0x66); | 1329 emitUint8(0x66); |
| 1368 emitAddrSizeOverridePrefix(); | 1330 emitAddrSizeOverridePrefix(); |
| 1369 emitRex(RexTypeIrrelevant, src, dst); | 1331 emitRex(RexTypeIrrelevant, src, dst); |
| 1370 emitUint8(0x0F); | 1332 emitUint8(0x0F); |
| 1371 emitUint8(0x56); | 1333 emitUint8(0x56); |
| 1372 emitOperand(gprEncoding(dst), src); | 1334 emitOperand(gprEncoding(dst), src); |
| 1373 } | 1335 } |
| 1374 | 1336 |
| 1375 template <class Machine> | 1337 template <typename TraitsType> |
| 1376 void AssemblerX86Base<Machine>::blendvps(Type /* Ty */, | 1338 void AssemblerX86Base<TraitsType>::blendvps(Type /* Ty */, XmmRegister dst, |
| 1377 typename Traits::XmmRegister dst, | 1339 XmmRegister src) { |
| 1378 typename Traits::XmmRegister src) { | |
| 1379 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1340 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1380 emitUint8(0x66); | 1341 emitUint8(0x66); |
| 1381 emitRexRB(RexTypeIrrelevant, dst, src); | 1342 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1382 emitUint8(0x0F); | 1343 emitUint8(0x0F); |
| 1383 emitUint8(0x38); | 1344 emitUint8(0x38); |
| 1384 emitUint8(0x14); | 1345 emitUint8(0x14); |
| 1385 emitXmmRegisterOperand(dst, src); | 1346 emitXmmRegisterOperand(dst, src); |
| 1386 } | 1347 } |
| 1387 | 1348 |
| 1388 template <class Machine> | 1349 template <typename TraitsType> |
| 1389 void AssemblerX86Base<Machine>::blendvps(Type /* Ty */, | 1350 void AssemblerX86Base<TraitsType>::blendvps(Type /* Ty */, XmmRegister dst, |
| 1390 typename Traits::XmmRegister dst, | 1351 const Address &src) { |
| 1391 const typename Traits::Address &src) { | |
| 1392 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1352 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1393 emitUint8(0x66); | 1353 emitUint8(0x66); |
| 1394 emitAddrSizeOverridePrefix(); | 1354 emitAddrSizeOverridePrefix(); |
| 1395 emitRex(RexTypeIrrelevant, src, dst); | 1355 emitRex(RexTypeIrrelevant, src, dst); |
| 1396 emitUint8(0x0F); | 1356 emitUint8(0x0F); |
| 1397 emitUint8(0x38); | 1357 emitUint8(0x38); |
| 1398 emitUint8(0x14); | 1358 emitUint8(0x14); |
| 1399 emitOperand(gprEncoding(dst), src); | 1359 emitOperand(gprEncoding(dst), src); |
| 1400 } | 1360 } |
| 1401 | 1361 |
| 1402 template <class Machine> | 1362 template <typename TraitsType> |
| 1403 void AssemblerX86Base<Machine>::pblendvb(Type /* Ty */, | 1363 void AssemblerX86Base<TraitsType>::pblendvb(Type /* Ty */, XmmRegister dst, |
| 1404 typename Traits::XmmRegister dst, | 1364 XmmRegister src) { |
| 1405 typename Traits::XmmRegister src) { | |
| 1406 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1365 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1407 emitUint8(0x66); | 1366 emitUint8(0x66); |
| 1408 emitRexRB(RexTypeIrrelevant, dst, src); | 1367 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1409 emitUint8(0x0F); | 1368 emitUint8(0x0F); |
| 1410 emitUint8(0x38); | 1369 emitUint8(0x38); |
| 1411 emitUint8(0x10); | 1370 emitUint8(0x10); |
| 1412 emitXmmRegisterOperand(dst, src); | 1371 emitXmmRegisterOperand(dst, src); |
| 1413 } | 1372 } |
| 1414 | 1373 |
| 1415 template <class Machine> | 1374 template <typename TraitsType> |
| 1416 void AssemblerX86Base<Machine>::pblendvb(Type /* Ty */, | 1375 void AssemblerX86Base<TraitsType>::pblendvb(Type /* Ty */, XmmRegister dst, |
| 1417 typename Traits::XmmRegister dst, | 1376 const Address &src) { |
| 1418 const typename Traits::Address &src) { | |
| 1419 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1377 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1420 emitUint8(0x66); | 1378 emitUint8(0x66); |
| 1421 emitAddrSizeOverridePrefix(); | 1379 emitAddrSizeOverridePrefix(); |
| 1422 emitRex(RexTypeIrrelevant, src, dst); | 1380 emitRex(RexTypeIrrelevant, src, dst); |
| 1423 emitUint8(0x0F); | 1381 emitUint8(0x0F); |
| 1424 emitUint8(0x38); | 1382 emitUint8(0x38); |
| 1425 emitUint8(0x10); | 1383 emitUint8(0x10); |
| 1426 emitOperand(gprEncoding(dst), src); | 1384 emitOperand(gprEncoding(dst), src); |
| 1427 } | 1385 } |
| 1428 | 1386 |
| 1429 template <class Machine> | 1387 template <typename TraitsType> |
| 1430 void AssemblerX86Base<Machine>::cmpps( | 1388 void AssemblerX86Base<TraitsType>::cmpps(Type Ty, XmmRegister dst, |
| 1431 Type Ty, typename Traits::XmmRegister dst, typename Traits::XmmRegister src, | 1389 XmmRegister src, |
| 1432 typename Traits::Cond::CmppsCond CmpCondition) { | 1390 CmppsCond CmpCondition) { |
| 1433 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1391 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1434 if (Ty == IceType_f64) | 1392 if (Ty == IceType_f64) |
| 1435 emitUint8(0x66); | 1393 emitUint8(0x66); |
| 1436 emitRexRB(RexTypeIrrelevant, dst, src); | 1394 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1437 emitUint8(0x0F); | 1395 emitUint8(0x0F); |
| 1438 emitUint8(0xC2); | 1396 emitUint8(0xC2); |
| 1439 emitXmmRegisterOperand(dst, src); | 1397 emitXmmRegisterOperand(dst, src); |
| 1440 emitUint8(CmpCondition); | 1398 emitUint8(CmpCondition); |
| 1441 } | 1399 } |
| 1442 | 1400 |
| 1443 template <class Machine> | 1401 template <typename TraitsType> |
| 1444 void AssemblerX86Base<Machine>::cmpps( | 1402 void AssemblerX86Base<TraitsType>::cmpps(Type Ty, XmmRegister dst, |
| 1445 Type Ty, typename Traits::XmmRegister dst, | 1403 const Address &src, |
| 1446 const typename Traits::Address &src, | 1404 CmppsCond CmpCondition) { |
| 1447 typename Traits::Cond::CmppsCond CmpCondition) { | |
| 1448 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1405 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1449 if (Ty == IceType_f64) | 1406 if (Ty == IceType_f64) |
| 1450 emitUint8(0x66); | 1407 emitUint8(0x66); |
| 1451 emitAddrSizeOverridePrefix(); | 1408 emitAddrSizeOverridePrefix(); |
| 1452 emitRex(RexTypeIrrelevant, src, dst); | 1409 emitRex(RexTypeIrrelevant, src, dst); |
| 1453 emitUint8(0x0F); | 1410 emitUint8(0x0F); |
| 1454 emitUint8(0xC2); | 1411 emitUint8(0xC2); |
| 1455 emitOperand(gprEncoding(dst), src); | 1412 emitOperand(gprEncoding(dst), src); |
| 1456 emitUint8(CmpCondition); | 1413 emitUint8(CmpCondition); |
| 1457 } | 1414 } |
| 1458 | 1415 |
| 1459 template <class Machine> | 1416 template <typename TraitsType> |
| 1460 void AssemblerX86Base<Machine>::sqrtps(typename Traits::XmmRegister dst) { | 1417 void AssemblerX86Base<TraitsType>::sqrtps(XmmRegister dst) { |
| 1461 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1418 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1462 emitRexRB(RexTypeIrrelevant, dst, dst); | 1419 emitRexRB(RexTypeIrrelevant, dst, dst); |
| 1463 emitUint8(0x0F); | 1420 emitUint8(0x0F); |
| 1464 emitUint8(0x51); | 1421 emitUint8(0x51); |
| 1465 emitXmmRegisterOperand(dst, dst); | 1422 emitXmmRegisterOperand(dst, dst); |
| 1466 } | 1423 } |
| 1467 | 1424 |
| 1468 template <class Machine> | 1425 template <typename TraitsType> |
| 1469 void AssemblerX86Base<Machine>::rsqrtps(typename Traits::XmmRegister dst) { | 1426 void AssemblerX86Base<TraitsType>::rsqrtps(XmmRegister dst) { |
| 1470 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1427 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1471 emitRexRB(RexTypeIrrelevant, dst, dst); | 1428 emitRexRB(RexTypeIrrelevant, dst, dst); |
| 1472 emitUint8(0x0F); | 1429 emitUint8(0x0F); |
| 1473 emitUint8(0x52); | 1430 emitUint8(0x52); |
| 1474 emitXmmRegisterOperand(dst, dst); | 1431 emitXmmRegisterOperand(dst, dst); |
| 1475 } | 1432 } |
| 1476 | 1433 |
| 1477 template <class Machine> | 1434 template <typename TraitsType> |
| 1478 void AssemblerX86Base<Machine>::reciprocalps(typename Traits::XmmRegister dst) { | 1435 void AssemblerX86Base<TraitsType>::reciprocalps(XmmRegister dst) { |
| 1479 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1436 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1480 emitRexRB(RexTypeIrrelevant, dst, dst); | 1437 emitRexRB(RexTypeIrrelevant, dst, dst); |
| 1481 emitUint8(0x0F); | 1438 emitUint8(0x0F); |
| 1482 emitUint8(0x53); | 1439 emitUint8(0x53); |
| 1483 emitXmmRegisterOperand(dst, dst); | 1440 emitXmmRegisterOperand(dst, dst); |
| 1484 } | 1441 } |
| 1485 | 1442 |
| 1486 template <class Machine> | 1443 template <typename TraitsType> |
| 1487 void AssemblerX86Base<Machine>::movhlps(typename Traits::XmmRegister dst, | 1444 void AssemblerX86Base<TraitsType>::movhlps(XmmRegister dst, XmmRegister src) { |
| 1488 typename Traits::XmmRegister src) { | |
| 1489 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1445 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1490 emitRexRB(RexTypeIrrelevant, dst, src); | 1446 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1491 emitUint8(0x0F); | 1447 emitUint8(0x0F); |
| 1492 emitUint8(0x12); | 1448 emitUint8(0x12); |
| 1493 emitXmmRegisterOperand(dst, src); | 1449 emitXmmRegisterOperand(dst, src); |
| 1494 } | 1450 } |
| 1495 | 1451 |
| 1496 template <class Machine> | 1452 template <typename TraitsType> |
| 1497 void AssemblerX86Base<Machine>::movlhps(typename Traits::XmmRegister dst, | 1453 void AssemblerX86Base<TraitsType>::movlhps(XmmRegister dst, XmmRegister src) { |
| 1498 typename Traits::XmmRegister src) { | |
| 1499 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1454 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1500 emitRexRB(RexTypeIrrelevant, dst, src); | 1455 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1501 emitUint8(0x0F); | 1456 emitUint8(0x0F); |
| 1502 emitUint8(0x16); | 1457 emitUint8(0x16); |
| 1503 emitXmmRegisterOperand(dst, src); | 1458 emitXmmRegisterOperand(dst, src); |
| 1504 } | 1459 } |
| 1505 | 1460 |
| 1506 template <class Machine> | 1461 template <typename TraitsType> |
| 1507 void AssemblerX86Base<Machine>::unpcklps(typename Traits::XmmRegister dst, | 1462 void AssemblerX86Base<TraitsType>::unpcklps(XmmRegister dst, XmmRegister src) { |
| 1508 typename Traits::XmmRegister src) { | |
| 1509 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1463 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1510 emitRexRB(RexTypeIrrelevant, dst, src); | 1464 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1511 emitUint8(0x0F); | 1465 emitUint8(0x0F); |
| 1512 emitUint8(0x14); | 1466 emitUint8(0x14); |
| 1513 emitXmmRegisterOperand(dst, src); | 1467 emitXmmRegisterOperand(dst, src); |
| 1514 } | 1468 } |
| 1515 | 1469 |
| 1516 template <class Machine> | 1470 template <typename TraitsType> |
| 1517 void AssemblerX86Base<Machine>::unpckhps(typename Traits::XmmRegister dst, | 1471 void AssemblerX86Base<TraitsType>::unpckhps(XmmRegister dst, XmmRegister src) { |
| 1518 typename Traits::XmmRegister src) { | |
| 1519 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1472 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1520 emitRexRB(RexTypeIrrelevant, dst, src); | 1473 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1521 emitUint8(0x0F); | 1474 emitUint8(0x0F); |
| 1522 emitUint8(0x15); | 1475 emitUint8(0x15); |
| 1523 emitXmmRegisterOperand(dst, src); | 1476 emitXmmRegisterOperand(dst, src); |
| 1524 } | 1477 } |
| 1525 | 1478 |
| 1526 template <class Machine> | 1479 template <typename TraitsType> |
| 1527 void AssemblerX86Base<Machine>::unpcklpd(typename Traits::XmmRegister dst, | 1480 void AssemblerX86Base<TraitsType>::unpcklpd(XmmRegister dst, XmmRegister src) { |
| 1528 typename Traits::XmmRegister src) { | |
| 1529 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1481 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1530 emitUint8(0x66); | 1482 emitUint8(0x66); |
| 1531 emitRexRB(RexTypeIrrelevant, dst, src); | 1483 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1532 emitUint8(0x0F); | 1484 emitUint8(0x0F); |
| 1533 emitUint8(0x14); | 1485 emitUint8(0x14); |
| 1534 emitXmmRegisterOperand(dst, src); | 1486 emitXmmRegisterOperand(dst, src); |
| 1535 } | 1487 } |
| 1536 | 1488 |
| 1537 template <class Machine> | 1489 template <typename TraitsType> |
| 1538 void AssemblerX86Base<Machine>::unpckhpd(typename Traits::XmmRegister dst, | 1490 void AssemblerX86Base<TraitsType>::unpckhpd(XmmRegister dst, XmmRegister src) { |
| 1539 typename Traits::XmmRegister src) { | |
| 1540 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1491 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1541 emitUint8(0x66); | 1492 emitUint8(0x66); |
| 1542 emitRexRB(RexTypeIrrelevant, dst, src); | 1493 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1543 emitUint8(0x0F); | 1494 emitUint8(0x0F); |
| 1544 emitUint8(0x15); | 1495 emitUint8(0x15); |
| 1545 emitXmmRegisterOperand(dst, src); | 1496 emitXmmRegisterOperand(dst, src); |
| 1546 } | 1497 } |
| 1547 | 1498 |
| 1548 template <class Machine> | 1499 template <typename TraitsType> |
| 1549 void AssemblerX86Base<Machine>::set1ps(typename Traits::XmmRegister dst, | 1500 void AssemblerX86Base<TraitsType>::set1ps(XmmRegister dst, GPRRegister tmp1, |
| 1550 typename Traits::GPRRegister tmp1, | 1501 const Immediate &imm) { |
| 1551 const Immediate &imm) { | |
| 1552 // Load 32-bit immediate value into tmp1. | 1502 // Load 32-bit immediate value into tmp1. |
| 1553 mov(IceType_i32, tmp1, imm); | 1503 mov(IceType_i32, tmp1, imm); |
| 1554 // Move value from tmp1 into dst. | 1504 // Move value from tmp1 into dst. |
| 1555 movd(IceType_i32, dst, tmp1); | 1505 movd(IceType_i32, dst, tmp1); |
| 1556 // Broadcast low lane into other three lanes. | 1506 // Broadcast low lane into other three lanes. |
| 1557 shufps(RexTypeIrrelevant, dst, dst, Immediate(0x0)); | 1507 shufps(RexTypeIrrelevant, dst, dst, Immediate(0x0)); |
| 1558 } | 1508 } |
| 1559 | 1509 |
| 1560 template <class Machine> | 1510 template <typename TraitsType> |
| 1561 void AssemblerX86Base<Machine>::pshufd(Type /* Ty */, | 1511 void AssemblerX86Base<TraitsType>::pshufd(Type /* Ty */, XmmRegister dst, |
| 1562 typename Traits::XmmRegister dst, | 1512 XmmRegister src, |
| 1563 typename Traits::XmmRegister src, | 1513 const Immediate &imm) { |
| 1564 const Immediate &imm) { | |
| 1565 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1514 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1566 emitUint8(0x66); | 1515 emitUint8(0x66); |
| 1567 emitRexRB(RexTypeIrrelevant, dst, src); | 1516 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1568 emitUint8(0x0F); | 1517 emitUint8(0x0F); |
| 1569 emitUint8(0x70); | 1518 emitUint8(0x70); |
| 1570 emitXmmRegisterOperand(dst, src); | 1519 emitXmmRegisterOperand(dst, src); |
| 1571 assert(imm.is_uint8()); | 1520 assert(imm.is_uint8()); |
| 1572 emitUint8(imm.value()); | 1521 emitUint8(imm.value()); |
| 1573 } | 1522 } |
| 1574 | 1523 |
| 1575 template <class Machine> | 1524 template <typename TraitsType> |
| 1576 void AssemblerX86Base<Machine>::pshufd(Type /* Ty */, | 1525 void AssemblerX86Base<TraitsType>::pshufd(Type /* Ty */, XmmRegister dst, |
| 1577 typename Traits::XmmRegister dst, | 1526 const Address &src, |
| 1578 const typename Traits::Address &src, | 1527 const Immediate &imm) { |
| 1579 const Immediate &imm) { | |
| 1580 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1528 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1581 emitUint8(0x66); | 1529 emitUint8(0x66); |
| 1582 emitAddrSizeOverridePrefix(); | 1530 emitAddrSizeOverridePrefix(); |
| 1583 emitRex(RexTypeIrrelevant, src, dst); | 1531 emitRex(RexTypeIrrelevant, src, dst); |
| 1584 emitUint8(0x0F); | 1532 emitUint8(0x0F); |
| 1585 emitUint8(0x70); | 1533 emitUint8(0x70); |
| 1586 emitOperand(gprEncoding(dst), src); | 1534 emitOperand(gprEncoding(dst), src); |
| 1587 assert(imm.is_uint8()); | 1535 assert(imm.is_uint8()); |
| 1588 emitUint8(imm.value()); | 1536 emitUint8(imm.value()); |
| 1589 } | 1537 } |
| 1590 | 1538 |
| 1591 template <class Machine> | 1539 template <typename TraitsType> |
| 1592 void AssemblerX86Base<Machine>::shufps(Type /* Ty */, | 1540 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst, |
| 1593 typename Traits::XmmRegister dst, | 1541 XmmRegister src, |
| 1594 typename Traits::XmmRegister src, | 1542 const Immediate &imm) { |
| 1595 const Immediate &imm) { | |
| 1596 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1543 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1597 emitRexRB(RexTypeIrrelevant, dst, src); | 1544 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1598 emitUint8(0x0F); | 1545 emitUint8(0x0F); |
| 1599 emitUint8(0xC6); | 1546 emitUint8(0xC6); |
| 1600 emitXmmRegisterOperand(dst, src); | 1547 emitXmmRegisterOperand(dst, src); |
| 1601 assert(imm.is_uint8()); | 1548 assert(imm.is_uint8()); |
| 1602 emitUint8(imm.value()); | 1549 emitUint8(imm.value()); |
| 1603 } | 1550 } |
| 1604 | 1551 |
| 1605 template <class Machine> | 1552 template <typename TraitsType> |
| 1606 void AssemblerX86Base<Machine>::shufps(Type /* Ty */, | 1553 void AssemblerX86Base<TraitsType>::shufps(Type /* Ty */, XmmRegister dst, |
| 1607 typename Traits::XmmRegister dst, | 1554 const Address &src, |
| 1608 const typename Traits::Address &src, | 1555 const Immediate &imm) { |
| 1609 const Immediate &imm) { | |
| 1610 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1556 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1611 emitAddrSizeOverridePrefix(); | 1557 emitAddrSizeOverridePrefix(); |
| 1612 emitRex(RexTypeIrrelevant, src, dst); | 1558 emitRex(RexTypeIrrelevant, src, dst); |
| 1613 emitUint8(0x0F); | 1559 emitUint8(0x0F); |
| 1614 emitUint8(0xC6); | 1560 emitUint8(0xC6); |
| 1615 emitOperand(gprEncoding(dst), src); | 1561 emitOperand(gprEncoding(dst), src); |
| 1616 assert(imm.is_uint8()); | 1562 assert(imm.is_uint8()); |
| 1617 emitUint8(imm.value()); | 1563 emitUint8(imm.value()); |
| 1618 } | 1564 } |
| 1619 | 1565 |
| 1620 template <class Machine> | 1566 template <typename TraitsType> |
| 1621 void AssemblerX86Base<Machine>::sqrtpd(typename Traits::XmmRegister dst) { | 1567 void AssemblerX86Base<TraitsType>::sqrtpd(XmmRegister dst) { |
| 1622 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1568 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1623 emitUint8(0x66); | 1569 emitUint8(0x66); |
| 1624 emitRexRB(RexTypeIrrelevant, dst, dst); | 1570 emitRexRB(RexTypeIrrelevant, dst, dst); |
| 1625 emitUint8(0x0F); | 1571 emitUint8(0x0F); |
| 1626 emitUint8(0x51); | 1572 emitUint8(0x51); |
| 1627 emitXmmRegisterOperand(dst, dst); | 1573 emitXmmRegisterOperand(dst, dst); |
| 1628 } | 1574 } |
| 1629 | 1575 |
| 1630 template <class Machine> | 1576 template <typename TraitsType> |
| 1631 void AssemblerX86Base<Machine>::cvtdq2ps(Type /* Ignore */, | 1577 void AssemblerX86Base<TraitsType>::cvtdq2ps(Type /* Ignore */, XmmRegister dst, |
| 1632 typename Traits::XmmRegister dst, | 1578 XmmRegister src) { |
| 1633 typename Traits::XmmRegister src) { | |
| 1634 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1579 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1635 emitRexRB(RexTypeIrrelevant, dst, src); | 1580 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1636 emitUint8(0x0F); | 1581 emitUint8(0x0F); |
| 1637 emitUint8(0x5B); | 1582 emitUint8(0x5B); |
| 1638 emitXmmRegisterOperand(dst, src); | 1583 emitXmmRegisterOperand(dst, src); |
| 1639 } | 1584 } |
| 1640 | 1585 |
| 1641 template <class Machine> | 1586 template <typename TraitsType> |
| 1642 void AssemblerX86Base<Machine>::cvtdq2ps(Type /* Ignore */, | 1587 void AssemblerX86Base<TraitsType>::cvtdq2ps(Type /* Ignore */, XmmRegister dst, |
| 1643 typename Traits::XmmRegister dst, | 1588 const Address &src) { |
| 1644 const typename Traits::Address &src) { | |
| 1645 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1589 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1646 emitAddrSizeOverridePrefix(); | 1590 emitAddrSizeOverridePrefix(); |
| 1647 emitRex(RexTypeIrrelevant, src, dst); | 1591 emitRex(RexTypeIrrelevant, src, dst); |
| 1648 emitUint8(0x0F); | 1592 emitUint8(0x0F); |
| 1649 emitUint8(0x5B); | 1593 emitUint8(0x5B); |
| 1650 emitOperand(gprEncoding(dst), src); | 1594 emitOperand(gprEncoding(dst), src); |
| 1651 } | 1595 } |
| 1652 | 1596 |
| 1653 template <class Machine> | 1597 template <typename TraitsType> |
| 1654 void AssemblerX86Base<Machine>::cvttps2dq(Type /* Ignore */, | 1598 void AssemblerX86Base<TraitsType>::cvttps2dq(Type /* Ignore */, XmmRegister dst, |
| 1655 typename Traits::XmmRegister dst, | 1599 XmmRegister src) { |
| 1656 typename Traits::XmmRegister src) { | |
| 1657 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1600 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1658 emitUint8(0xF3); | 1601 emitUint8(0xF3); |
| 1659 emitRexRB(RexTypeIrrelevant, dst, src); | 1602 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1660 emitUint8(0x0F); | 1603 emitUint8(0x0F); |
| 1661 emitUint8(0x5B); | 1604 emitUint8(0x5B); |
| 1662 emitXmmRegisterOperand(dst, src); | 1605 emitXmmRegisterOperand(dst, src); |
| 1663 } | 1606 } |
| 1664 | 1607 |
| 1665 template <class Machine> | 1608 template <typename TraitsType> |
| 1666 void AssemblerX86Base<Machine>::cvttps2dq(Type /* Ignore */, | 1609 void AssemblerX86Base<TraitsType>::cvttps2dq(Type /* Ignore */, XmmRegister dst, |
| 1667 typename Traits::XmmRegister dst, | 1610 const Address &src) { |
| 1668 const typename Traits::Address &src) { | |
| 1669 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1611 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1670 emitUint8(0xF3); | 1612 emitUint8(0xF3); |
| 1671 emitAddrSizeOverridePrefix(); | 1613 emitAddrSizeOverridePrefix(); |
| 1672 emitRex(RexTypeIrrelevant, src, dst); | 1614 emitRex(RexTypeIrrelevant, src, dst); |
| 1673 emitUint8(0x0F); | 1615 emitUint8(0x0F); |
| 1674 emitUint8(0x5B); | 1616 emitUint8(0x5B); |
| 1675 emitOperand(gprEncoding(dst), src); | 1617 emitOperand(gprEncoding(dst), src); |
| 1676 } | 1618 } |
| 1677 | 1619 |
| 1678 template <class Machine> | 1620 template <typename TraitsType> |
| 1679 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, | 1621 void AssemblerX86Base<TraitsType>::cvtsi2ss(Type DestTy, XmmRegister dst, |
| 1680 typename Traits::XmmRegister dst, | 1622 Type SrcTy, GPRRegister src) { |
| 1681 Type SrcTy, | |
| 1682 typename Traits::GPRRegister src) { | |
| 1683 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1623 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1684 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); | 1624 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); |
| 1685 emitRexRB(SrcTy, dst, src); | 1625 emitRexRB(SrcTy, dst, src); |
| 1686 emitUint8(0x0F); | 1626 emitUint8(0x0F); |
| 1687 emitUint8(0x2A); | 1627 emitUint8(0x2A); |
| 1688 emitXmmRegisterOperand(dst, src); | 1628 emitXmmRegisterOperand(dst, src); |
| 1689 } | 1629 } |
| 1690 | 1630 |
| 1691 template <class Machine> | 1631 template <typename TraitsType> |
| 1692 void AssemblerX86Base<Machine>::cvtsi2ss(Type DestTy, | 1632 void AssemblerX86Base<TraitsType>::cvtsi2ss(Type DestTy, XmmRegister dst, |
| 1693 typename Traits::XmmRegister dst, | 1633 Type SrcTy, const Address &src) { |
| 1694 Type SrcTy, | |
| 1695 const typename Traits::Address &src) { | |
| 1696 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1634 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1697 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); | 1635 emitUint8(isFloat32Asserting32Or64(DestTy) ? 0xF3 : 0xF2); |
| 1698 emitAddrSizeOverridePrefix(); | 1636 emitAddrSizeOverridePrefix(); |
| 1699 emitRex(SrcTy, src, dst); | 1637 emitRex(SrcTy, src, dst); |
| 1700 emitUint8(0x0F); | 1638 emitUint8(0x0F); |
| 1701 emitUint8(0x2A); | 1639 emitUint8(0x2A); |
| 1702 emitOperand(gprEncoding(dst), src); | 1640 emitOperand(gprEncoding(dst), src); |
| 1703 } | 1641 } |
| 1704 | 1642 |
| 1705 template <class Machine> | 1643 template <typename TraitsType> |
| 1706 void AssemblerX86Base<Machine>::cvtfloat2float( | 1644 void AssemblerX86Base<TraitsType>::cvtfloat2float(Type SrcTy, XmmRegister dst, |
| 1707 Type SrcTy, typename Traits::XmmRegister dst, | 1645 XmmRegister src) { |
| 1708 typename Traits::XmmRegister src) { | |
| 1709 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1646 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1710 // ss2sd or sd2ss | 1647 // ss2sd or sd2ss |
| 1711 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1648 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1712 emitRexRB(RexTypeIrrelevant, dst, src); | 1649 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1713 emitUint8(0x0F); | 1650 emitUint8(0x0F); |
| 1714 emitUint8(0x5A); | 1651 emitUint8(0x5A); |
| 1715 emitXmmRegisterOperand(dst, src); | 1652 emitXmmRegisterOperand(dst, src); |
| 1716 } | 1653 } |
| 1717 | 1654 |
| 1718 template <class Machine> | 1655 template <typename TraitsType> |
| 1719 void AssemblerX86Base<Machine>::cvtfloat2float( | 1656 void AssemblerX86Base<TraitsType>::cvtfloat2float(Type SrcTy, XmmRegister dst, |
| 1720 Type SrcTy, typename Traits::XmmRegister dst, | 1657 const Address &src) { |
| 1721 const typename Traits::Address &src) { | |
| 1722 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1658 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1723 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1659 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1724 emitAddrSizeOverridePrefix(); | 1660 emitAddrSizeOverridePrefix(); |
| 1725 emitRex(RexTypeIrrelevant, src, dst); | 1661 emitRex(RexTypeIrrelevant, src, dst); |
| 1726 emitUint8(0x0F); | 1662 emitUint8(0x0F); |
| 1727 emitUint8(0x5A); | 1663 emitUint8(0x5A); |
| 1728 emitOperand(gprEncoding(dst), src); | 1664 emitOperand(gprEncoding(dst), src); |
| 1729 } | 1665 } |
| 1730 | 1666 |
| 1731 template <class Machine> | 1667 template <typename TraitsType> |
| 1732 void AssemblerX86Base<Machine>::cvttss2si(Type DestTy, | 1668 void AssemblerX86Base<TraitsType>::cvttss2si(Type DestTy, GPRRegister dst, |
| 1733 typename Traits::GPRRegister dst, | 1669 Type SrcTy, XmmRegister src) { |
| 1734 Type SrcTy, | |
| 1735 typename Traits::XmmRegister src) { | |
| 1736 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1670 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1737 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1671 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1738 emitRexRB(DestTy, dst, src); | 1672 emitRexRB(DestTy, dst, src); |
| 1739 emitUint8(0x0F); | 1673 emitUint8(0x0F); |
| 1740 emitUint8(0x2C); | 1674 emitUint8(0x2C); |
| 1741 emitXmmRegisterOperand(dst, src); | 1675 emitXmmRegisterOperand(dst, src); |
| 1742 } | 1676 } |
| 1743 | 1677 |
| 1744 template <class Machine> | 1678 template <typename TraitsType> |
| 1745 void AssemblerX86Base<Machine>::cvttss2si(Type DestTy, | 1679 void AssemblerX86Base<TraitsType>::cvttss2si(Type DestTy, GPRRegister dst, |
| 1746 typename Traits::GPRRegister dst, | 1680 Type SrcTy, const Address &src) { |
| 1747 Type SrcTy, | |
| 1748 const typename Traits::Address &src) { | |
| 1749 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1681 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1750 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); | 1682 emitUint8(isFloat32Asserting32Or64(SrcTy) ? 0xF3 : 0xF2); |
| 1751 emitAddrSizeOverridePrefix(); | 1683 emitAddrSizeOverridePrefix(); |
| 1752 emitRex(DestTy, src, dst); | 1684 emitRex(DestTy, src, dst); |
| 1753 emitUint8(0x0F); | 1685 emitUint8(0x0F); |
| 1754 emitUint8(0x2C); | 1686 emitUint8(0x2C); |
| 1755 emitOperand(gprEncoding(dst), src); | 1687 emitOperand(gprEncoding(dst), src); |
| 1756 } | 1688 } |
| 1757 | 1689 |
| 1758 template <class Machine> | 1690 template <typename TraitsType> |
| 1759 void AssemblerX86Base<Machine>::ucomiss(Type Ty, typename Traits::XmmRegister a, | 1691 void AssemblerX86Base<TraitsType>::ucomiss(Type Ty, XmmRegister a, |
| 1760 typename Traits::XmmRegister b) { | 1692 XmmRegister b) { |
| 1761 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1693 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1762 if (Ty == IceType_f64) | 1694 if (Ty == IceType_f64) |
| 1763 emitUint8(0x66); | 1695 emitUint8(0x66); |
| 1764 emitRexRB(RexTypeIrrelevant, a, b); | 1696 emitRexRB(RexTypeIrrelevant, a, b); |
| 1765 emitUint8(0x0F); | 1697 emitUint8(0x0F); |
| 1766 emitUint8(0x2E); | 1698 emitUint8(0x2E); |
| 1767 emitXmmRegisterOperand(a, b); | 1699 emitXmmRegisterOperand(a, b); |
| 1768 } | 1700 } |
| 1769 | 1701 |
| 1770 template <class Machine> | 1702 template <typename TraitsType> |
| 1771 void AssemblerX86Base<Machine>::ucomiss(Type Ty, typename Traits::XmmRegister a, | 1703 void AssemblerX86Base<TraitsType>::ucomiss(Type Ty, XmmRegister a, |
| 1772 const typename Traits::Address &b) { | 1704 const Address &b) { |
| 1773 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1705 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1774 if (Ty == IceType_f64) | 1706 if (Ty == IceType_f64) |
| 1775 emitUint8(0x66); | 1707 emitUint8(0x66); |
| 1776 emitAddrSizeOverridePrefix(); | 1708 emitAddrSizeOverridePrefix(); |
| 1777 emitRex(RexTypeIrrelevant, b, a); | 1709 emitRex(RexTypeIrrelevant, b, a); |
| 1778 emitUint8(0x0F); | 1710 emitUint8(0x0F); |
| 1779 emitUint8(0x2E); | 1711 emitUint8(0x2E); |
| 1780 emitOperand(gprEncoding(a), b); | 1712 emitOperand(gprEncoding(a), b); |
| 1781 } | 1713 } |
| 1782 | 1714 |
| 1783 template <class Machine> | 1715 template <typename TraitsType> |
| 1784 void AssemblerX86Base<Machine>::movmskpd(typename Traits::GPRRegister dst, | 1716 void AssemblerX86Base<TraitsType>::movmskpd(GPRRegister dst, XmmRegister src) { |
| 1785 typename Traits::XmmRegister src) { | |
| 1786 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1717 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1787 emitUint8(0x66); | 1718 emitUint8(0x66); |
| 1788 emitRexRB(RexTypeIrrelevant, dst, src); | 1719 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1789 emitUint8(0x0F); | 1720 emitUint8(0x0F); |
| 1790 emitUint8(0x50); | 1721 emitUint8(0x50); |
| 1791 emitXmmRegisterOperand(dst, src); | 1722 emitXmmRegisterOperand(dst, src); |
| 1792 } | 1723 } |
| 1793 | 1724 |
| 1794 template <class Machine> | 1725 template <typename TraitsType> |
| 1795 void AssemblerX86Base<Machine>::movmskps(typename Traits::GPRRegister dst, | 1726 void AssemblerX86Base<TraitsType>::movmskps(GPRRegister dst, XmmRegister src) { |
| 1796 typename Traits::XmmRegister src) { | |
| 1797 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1727 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1798 emitRexRB(RexTypeIrrelevant, dst, src); | 1728 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1799 emitUint8(0x0F); | 1729 emitUint8(0x0F); |
| 1800 emitUint8(0x50); | 1730 emitUint8(0x50); |
| 1801 emitXmmRegisterOperand(dst, src); | 1731 emitXmmRegisterOperand(dst, src); |
| 1802 } | 1732 } |
| 1803 | 1733 |
| 1804 template <class Machine> | 1734 template <typename TraitsType> |
| 1805 void AssemblerX86Base<Machine>::sqrtss(Type Ty, | 1735 void AssemblerX86Base<TraitsType>::sqrtss(Type Ty, XmmRegister dst, |
| 1806 typename Traits::XmmRegister dst, | 1736 const Address &src) { |
| 1807 const typename Traits::Address &src) { | |
| 1808 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1737 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1809 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 1738 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 1810 emitAddrSizeOverridePrefix(); | 1739 emitAddrSizeOverridePrefix(); |
| 1811 emitRex(RexTypeIrrelevant, src, dst); | 1740 emitRex(RexTypeIrrelevant, src, dst); |
| 1812 emitUint8(0x0F); | 1741 emitUint8(0x0F); |
| 1813 emitUint8(0x51); | 1742 emitUint8(0x51); |
| 1814 emitOperand(gprEncoding(dst), src); | 1743 emitOperand(gprEncoding(dst), src); |
| 1815 } | 1744 } |
| 1816 | 1745 |
| 1817 template <class Machine> | 1746 template <typename TraitsType> |
| 1818 void AssemblerX86Base<Machine>::sqrtss(Type Ty, | 1747 void AssemblerX86Base<TraitsType>::sqrtss(Type Ty, XmmRegister dst, |
| 1819 typename Traits::XmmRegister dst, | 1748 XmmRegister src) { |
| 1820 typename Traits::XmmRegister src) { | |
| 1821 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1749 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1822 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); | 1750 emitUint8(isFloat32Asserting32Or64(Ty) ? 0xF3 : 0xF2); |
| 1823 emitRexRB(RexTypeIrrelevant, dst, src); | 1751 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1824 emitUint8(0x0F); | 1752 emitUint8(0x0F); |
| 1825 emitUint8(0x51); | 1753 emitUint8(0x51); |
| 1826 emitXmmRegisterOperand(dst, src); | 1754 emitXmmRegisterOperand(dst, src); |
| 1827 } | 1755 } |
| 1828 | 1756 |
| 1829 template <class Machine> | 1757 template <typename TraitsType> |
| 1830 void AssemblerX86Base<Machine>::xorps(Type Ty, typename Traits::XmmRegister dst, | 1758 void AssemblerX86Base<TraitsType>::xorps(Type Ty, XmmRegister dst, |
| 1831 const typename Traits::Address &src) { | 1759 const Address &src) { |
| 1832 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1760 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1833 if (!isFloat32Asserting32Or64(Ty)) | 1761 if (!isFloat32Asserting32Or64(Ty)) |
| 1834 emitUint8(0x66); | 1762 emitUint8(0x66); |
| 1835 emitAddrSizeOverridePrefix(); | 1763 emitAddrSizeOverridePrefix(); |
| 1836 emitRex(RexTypeIrrelevant, src, dst); | 1764 emitRex(RexTypeIrrelevant, src, dst); |
| 1837 emitUint8(0x0F); | 1765 emitUint8(0x0F); |
| 1838 emitUint8(0x57); | 1766 emitUint8(0x57); |
| 1839 emitOperand(gprEncoding(dst), src); | 1767 emitOperand(gprEncoding(dst), src); |
| 1840 } | 1768 } |
| 1841 | 1769 |
| 1842 template <class Machine> | 1770 template <typename TraitsType> |
| 1843 void AssemblerX86Base<Machine>::xorps(Type Ty, typename Traits::XmmRegister dst, | 1771 void AssemblerX86Base<TraitsType>::xorps(Type Ty, XmmRegister dst, |
| 1844 typename Traits::XmmRegister src) { | 1772 XmmRegister src) { |
| 1845 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1773 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1846 if (!isFloat32Asserting32Or64(Ty)) | 1774 if (!isFloat32Asserting32Or64(Ty)) |
| 1847 emitUint8(0x66); | 1775 emitUint8(0x66); |
| 1848 emitRexRB(RexTypeIrrelevant, dst, src); | 1776 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1849 emitUint8(0x0F); | 1777 emitUint8(0x0F); |
| 1850 emitUint8(0x57); | 1778 emitUint8(0x57); |
| 1851 emitXmmRegisterOperand(dst, src); | 1779 emitXmmRegisterOperand(dst, src); |
| 1852 } | 1780 } |
| 1853 | 1781 |
| 1854 template <class Machine> | 1782 template <typename TraitsType> |
| 1855 void AssemblerX86Base<Machine>::insertps(Type Ty, | 1783 void AssemblerX86Base<TraitsType>::insertps(Type Ty, XmmRegister dst, |
| 1856 typename Traits::XmmRegister dst, | 1784 XmmRegister src, |
| 1857 typename Traits::XmmRegister src, | 1785 const Immediate &imm) { |
| 1858 const Immediate &imm) { | |
| 1859 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1786 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1860 assert(imm.is_uint8()); | 1787 assert(imm.is_uint8()); |
| 1861 assert(isVectorFloatingType(Ty)); | 1788 assert(isVectorFloatingType(Ty)); |
| 1862 (void)Ty; | 1789 (void)Ty; |
| 1863 emitUint8(0x66); | 1790 emitUint8(0x66); |
| 1864 emitRexRB(RexTypeIrrelevant, dst, src); | 1791 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1865 emitUint8(0x0F); | 1792 emitUint8(0x0F); |
| 1866 emitUint8(0x3A); | 1793 emitUint8(0x3A); |
| 1867 emitUint8(0x21); | 1794 emitUint8(0x21); |
| 1868 emitXmmRegisterOperand(dst, src); | 1795 emitXmmRegisterOperand(dst, src); |
| 1869 emitUint8(imm.value()); | 1796 emitUint8(imm.value()); |
| 1870 } | 1797 } |
| 1871 | 1798 |
| 1872 template <class Machine> | 1799 template <typename TraitsType> |
| 1873 void AssemblerX86Base<Machine>::insertps(Type Ty, | 1800 void AssemblerX86Base<TraitsType>::insertps(Type Ty, XmmRegister dst, |
| 1874 typename Traits::XmmRegister dst, | 1801 const Address &src, |
| 1875 const typename Traits::Address &src, | 1802 const Immediate &imm) { |
| 1876 const Immediate &imm) { | |
| 1877 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1803 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1878 assert(imm.is_uint8()); | 1804 assert(imm.is_uint8()); |
| 1879 assert(isVectorFloatingType(Ty)); | 1805 assert(isVectorFloatingType(Ty)); |
| 1880 (void)Ty; | 1806 (void)Ty; |
| 1881 emitUint8(0x66); | 1807 emitUint8(0x66); |
| 1882 emitAddrSizeOverridePrefix(); | 1808 emitAddrSizeOverridePrefix(); |
| 1883 emitRex(RexTypeIrrelevant, src, dst); | 1809 emitRex(RexTypeIrrelevant, src, dst); |
| 1884 emitUint8(0x0F); | 1810 emitUint8(0x0F); |
| 1885 emitUint8(0x3A); | 1811 emitUint8(0x3A); |
| 1886 emitUint8(0x21); | 1812 emitUint8(0x21); |
| 1887 emitOperand(gprEncoding(dst), src); | 1813 emitOperand(gprEncoding(dst), src); |
| 1888 emitUint8(imm.value()); | 1814 emitUint8(imm.value()); |
| 1889 } | 1815 } |
| 1890 | 1816 |
| 1891 template <class Machine> | 1817 template <typename TraitsType> |
| 1892 void AssemblerX86Base<Machine>::pinsr(Type Ty, typename Traits::XmmRegister dst, | 1818 void AssemblerX86Base<TraitsType>::pinsr(Type Ty, XmmRegister dst, |
| 1893 typename Traits::GPRRegister src, | 1819 GPRRegister src, |
| 1894 const Immediate &imm) { | 1820 const Immediate &imm) { |
| 1895 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1821 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1896 assert(imm.is_uint8()); | 1822 assert(imm.is_uint8()); |
| 1897 emitUint8(0x66); | 1823 emitUint8(0x66); |
| 1898 emitRexRB(Ty, dst, src); | 1824 emitRexRB(Ty, dst, src); |
| 1899 emitUint8(0x0F); | 1825 emitUint8(0x0F); |
| 1900 if (Ty == IceType_i16) { | 1826 if (Ty == IceType_i16) { |
| 1901 emitUint8(0xC4); | 1827 emitUint8(0xC4); |
| 1902 } else { | 1828 } else { |
| 1903 emitUint8(0x3A); | 1829 emitUint8(0x3A); |
| 1904 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); | 1830 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); |
| 1905 } | 1831 } |
| 1906 emitXmmRegisterOperand(dst, src); | 1832 emitXmmRegisterOperand(dst, src); |
| 1907 emitUint8(imm.value()); | 1833 emitUint8(imm.value()); |
| 1908 } | 1834 } |
| 1909 | 1835 |
| 1910 template <class Machine> | 1836 template <typename TraitsType> |
| 1911 void AssemblerX86Base<Machine>::pinsr(Type Ty, typename Traits::XmmRegister dst, | 1837 void AssemblerX86Base<TraitsType>::pinsr(Type Ty, XmmRegister dst, |
| 1912 const typename Traits::Address &src, | 1838 const Address &src, |
| 1913 const Immediate &imm) { | 1839 const Immediate &imm) { |
| 1914 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1840 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1915 assert(imm.is_uint8()); | 1841 assert(imm.is_uint8()); |
| 1916 emitUint8(0x66); | 1842 emitUint8(0x66); |
| 1917 emitAddrSizeOverridePrefix(); | 1843 emitAddrSizeOverridePrefix(); |
| 1918 emitRex(RexTypeIrrelevant, src, dst); | 1844 emitRex(RexTypeIrrelevant, src, dst); |
| 1919 emitUint8(0x0F); | 1845 emitUint8(0x0F); |
| 1920 if (Ty == IceType_i16) { | 1846 if (Ty == IceType_i16) { |
| 1921 emitUint8(0xC4); | 1847 emitUint8(0xC4); |
| 1922 } else { | 1848 } else { |
| 1923 emitUint8(0x3A); | 1849 emitUint8(0x3A); |
| 1924 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); | 1850 emitUint8(isByteSizedType(Ty) ? 0x20 : 0x22); |
| 1925 } | 1851 } |
| 1926 emitOperand(gprEncoding(dst), src); | 1852 emitOperand(gprEncoding(dst), src); |
| 1927 emitUint8(imm.value()); | 1853 emitUint8(imm.value()); |
| 1928 } | 1854 } |
| 1929 | 1855 |
| 1930 template <class Machine> | 1856 template <typename TraitsType> |
| 1931 void AssemblerX86Base<Machine>::pextr(Type Ty, typename Traits::GPRRegister dst, | 1857 void AssemblerX86Base<TraitsType>::pextr(Type Ty, GPRRegister dst, |
| 1932 typename Traits::XmmRegister src, | 1858 XmmRegister src, |
| 1933 const Immediate &imm) { | 1859 const Immediate &imm) { |
| 1934 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1860 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1935 assert(imm.is_uint8()); | 1861 assert(imm.is_uint8()); |
| 1936 if (Ty == IceType_i16) { | 1862 if (Ty == IceType_i16) { |
| 1937 emitUint8(0x66); | 1863 emitUint8(0x66); |
| 1938 emitRexRB(Ty, dst, src); | 1864 emitRexRB(Ty, dst, src); |
| 1939 emitUint8(0x0F); | 1865 emitUint8(0x0F); |
| 1940 emitUint8(0xC5); | 1866 emitUint8(0xC5); |
| 1941 emitXmmRegisterOperand(dst, src); | 1867 emitXmmRegisterOperand(dst, src); |
| 1942 emitUint8(imm.value()); | 1868 emitUint8(imm.value()); |
| 1943 } else { | 1869 } else { |
| 1944 emitUint8(0x66); | 1870 emitUint8(0x66); |
| 1945 emitRexRB(Ty, src, dst); | 1871 emitRexRB(Ty, src, dst); |
| 1946 emitUint8(0x0F); | 1872 emitUint8(0x0F); |
| 1947 emitUint8(0x3A); | 1873 emitUint8(0x3A); |
| 1948 emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16); | 1874 emitUint8(isByteSizedType(Ty) ? 0x14 : 0x16); |
| 1949 // SSE 4.1 versions are "MRI" because dst can be mem, while pextrw (SSE2) | 1875 // SSE 4.1 versions are "MRI" because dst can be mem, while pextrw (SSE2) |
| 1950 // is RMI because dst must be reg. | 1876 // is RMI because dst must be reg. |
| 1951 emitXmmRegisterOperand(src, dst); | 1877 emitXmmRegisterOperand(src, dst); |
| 1952 emitUint8(imm.value()); | 1878 emitUint8(imm.value()); |
| 1953 } | 1879 } |
| 1954 } | 1880 } |
| 1955 | 1881 |
| 1956 template <class Machine> | 1882 template <typename TraitsType> |
| 1957 void AssemblerX86Base<Machine>::pmovsxdq(typename Traits::XmmRegister dst, | 1883 void AssemblerX86Base<TraitsType>::pmovsxdq(XmmRegister dst, XmmRegister src) { |
| 1958 typename Traits::XmmRegister src) { | |
| 1959 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1884 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1960 emitUint8(0x66); | 1885 emitUint8(0x66); |
| 1961 emitRexRB(RexTypeIrrelevant, dst, src); | 1886 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1962 emitUint8(0x0F); | 1887 emitUint8(0x0F); |
| 1963 emitUint8(0x38); | 1888 emitUint8(0x38); |
| 1964 emitUint8(0x25); | 1889 emitUint8(0x25); |
| 1965 emitXmmRegisterOperand(dst, src); | 1890 emitXmmRegisterOperand(dst, src); |
| 1966 } | 1891 } |
| 1967 | 1892 |
| 1968 template <class Machine> | 1893 template <typename TraitsType> |
| 1969 void AssemblerX86Base<Machine>::pcmpeq(Type Ty, | 1894 void AssemblerX86Base<TraitsType>::pcmpeq(Type Ty, XmmRegister dst, |
| 1970 typename Traits::XmmRegister dst, | 1895 XmmRegister src) { |
| 1971 typename Traits::XmmRegister src) { | |
| 1972 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1896 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1973 emitUint8(0x66); | 1897 emitUint8(0x66); |
| 1974 emitRexRB(RexTypeIrrelevant, dst, src); | 1898 emitRexRB(RexTypeIrrelevant, dst, src); |
| 1975 emitUint8(0x0F); | 1899 emitUint8(0x0F); |
| 1976 if (isByteSizedArithType(Ty)) { | 1900 if (isByteSizedArithType(Ty)) { |
| 1977 emitUint8(0x74); | 1901 emitUint8(0x74); |
| 1978 } else if (Ty == IceType_i16) { | 1902 } else if (Ty == IceType_i16) { |
| 1979 emitUint8(0x75); | 1903 emitUint8(0x75); |
| 1980 } else { | 1904 } else { |
| 1981 emitUint8(0x76); | 1905 emitUint8(0x76); |
| 1982 } | 1906 } |
| 1983 emitXmmRegisterOperand(dst, src); | 1907 emitXmmRegisterOperand(dst, src); |
| 1984 } | 1908 } |
| 1985 | 1909 |
| 1986 template <class Machine> | 1910 template <typename TraitsType> |
| 1987 void AssemblerX86Base<Machine>::pcmpeq(Type Ty, | 1911 void AssemblerX86Base<TraitsType>::pcmpeq(Type Ty, XmmRegister dst, |
| 1988 typename Traits::XmmRegister dst, | 1912 const Address &src) { |
| 1989 const typename Traits::Address &src) { | |
| 1990 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1913 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1991 emitUint8(0x66); | 1914 emitUint8(0x66); |
| 1992 emitAddrSizeOverridePrefix(); | 1915 emitAddrSizeOverridePrefix(); |
| 1993 emitRex(RexTypeIrrelevant, src, dst); | 1916 emitRex(RexTypeIrrelevant, src, dst); |
| 1994 emitUint8(0x0F); | 1917 emitUint8(0x0F); |
| 1995 if (isByteSizedArithType(Ty)) { | 1918 if (isByteSizedArithType(Ty)) { |
| 1996 emitUint8(0x74); | 1919 emitUint8(0x74); |
| 1997 } else if (Ty == IceType_i16) { | 1920 } else if (Ty == IceType_i16) { |
| 1998 emitUint8(0x75); | 1921 emitUint8(0x75); |
| 1999 } else { | 1922 } else { |
| 2000 emitUint8(0x76); | 1923 emitUint8(0x76); |
| 2001 } | 1924 } |
| 2002 emitOperand(gprEncoding(dst), src); | 1925 emitOperand(gprEncoding(dst), src); |
| 2003 } | 1926 } |
| 2004 | 1927 |
| 2005 template <class Machine> | 1928 template <typename TraitsType> |
| 2006 void AssemblerX86Base<Machine>::pcmpgt(Type Ty, | 1929 void AssemblerX86Base<TraitsType>::pcmpgt(Type Ty, XmmRegister dst, |
| 2007 typename Traits::XmmRegister dst, | 1930 XmmRegister src) { |
| 2008 typename Traits::XmmRegister src) { | |
| 2009 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1931 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2010 emitUint8(0x66); | 1932 emitUint8(0x66); |
| 2011 emitRexRB(RexTypeIrrelevant, dst, src); | 1933 emitRexRB(RexTypeIrrelevant, dst, src); |
| 2012 emitUint8(0x0F); | 1934 emitUint8(0x0F); |
| 2013 if (isByteSizedArithType(Ty)) { | 1935 if (isByteSizedArithType(Ty)) { |
| 2014 emitUint8(0x64); | 1936 emitUint8(0x64); |
| 2015 } else if (Ty == IceType_i16) { | 1937 } else if (Ty == IceType_i16) { |
| 2016 emitUint8(0x65); | 1938 emitUint8(0x65); |
| 2017 } else { | 1939 } else { |
| 2018 emitUint8(0x66); | 1940 emitUint8(0x66); |
| 2019 } | 1941 } |
| 2020 emitXmmRegisterOperand(dst, src); | 1942 emitXmmRegisterOperand(dst, src); |
| 2021 } | 1943 } |
| 2022 | 1944 |
| 2023 template <class Machine> | 1945 template <typename TraitsType> |
| 2024 void AssemblerX86Base<Machine>::pcmpgt(Type Ty, | 1946 void AssemblerX86Base<TraitsType>::pcmpgt(Type Ty, XmmRegister dst, |
| 2025 typename Traits::XmmRegister dst, | 1947 const Address &src) { |
| 2026 const typename Traits::Address &src) { | |
| 2027 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1948 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2028 emitUint8(0x66); | 1949 emitUint8(0x66); |
| 2029 emitAddrSizeOverridePrefix(); | 1950 emitAddrSizeOverridePrefix(); |
| 2030 emitRex(RexTypeIrrelevant, src, dst); | 1951 emitRex(RexTypeIrrelevant, src, dst); |
| 2031 emitUint8(0x0F); | 1952 emitUint8(0x0F); |
| 2032 if (isByteSizedArithType(Ty)) { | 1953 if (isByteSizedArithType(Ty)) { |
| 2033 emitUint8(0x64); | 1954 emitUint8(0x64); |
| 2034 } else if (Ty == IceType_i16) { | 1955 } else if (Ty == IceType_i16) { |
| 2035 emitUint8(0x65); | 1956 emitUint8(0x65); |
| 2036 } else { | 1957 } else { |
| 2037 emitUint8(0x66); | 1958 emitUint8(0x66); |
| 2038 } | 1959 } |
| 2039 emitOperand(gprEncoding(dst), src); | 1960 emitOperand(gprEncoding(dst), src); |
| 2040 } | 1961 } |
| 2041 | 1962 |
| 2042 template <class Machine> | 1963 template <typename TraitsType> |
| 2043 void AssemblerX86Base<Machine>::roundsd(typename Traits::XmmRegister dst, | 1964 void AssemblerX86Base<TraitsType>::roundsd(XmmRegister dst, XmmRegister src, |
| 2044 typename Traits::XmmRegister src, | 1965 RoundingMode mode) { |
| 2045 RoundingMode mode) { | |
| 2046 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1966 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2047 emitUint8(0x66); | 1967 emitUint8(0x66); |
| 2048 emitRexRB(RexTypeIrrelevant, dst, src); | 1968 emitRexRB(RexTypeIrrelevant, dst, src); |
| 2049 emitUint8(0x0F); | 1969 emitUint8(0x0F); |
| 2050 emitUint8(0x3A); | 1970 emitUint8(0x3A); |
| 2051 emitUint8(0x0B); | 1971 emitUint8(0x0B); |
| 2052 emitXmmRegisterOperand(dst, src); | 1972 emitXmmRegisterOperand(dst, src); |
| 2053 // Mask precision exeption. | 1973 // Mask precision exeption. |
| 2054 emitUint8(static_cast<uint8_t>(mode) | 0x8); | 1974 emitUint8(static_cast<uint8_t>(mode) | 0x8); |
| 2055 } | 1975 } |
| 2056 | 1976 |
| 2057 template <class Machine> | 1977 template <typename TraitsType> |
| 2058 template <typename T, typename> | 1978 template <typename T, typename> |
| 2059 void AssemblerX86Base<Machine>::fnstcw(const typename T::Address &dst) { | 1979 void AssemblerX86Base<TraitsType>::fnstcw(const typename T::Address &dst) { |
| 2060 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1980 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2061 emitAddrSizeOverridePrefix(); | 1981 emitAddrSizeOverridePrefix(); |
| 2062 emitUint8(0xD9); | 1982 emitUint8(0xD9); |
| 2063 emitOperand(7, dst); | 1983 emitOperand(7, dst); |
| 2064 } | 1984 } |
| 2065 | 1985 |
| 2066 template <class Machine> | 1986 template <typename TraitsType> |
| 2067 template <typename T, typename> | 1987 template <typename T, typename> |
| 2068 void AssemblerX86Base<Machine>::fldcw(const typename T::Address &src) { | 1988 void AssemblerX86Base<TraitsType>::fldcw(const typename T::Address &src) { |
| 2069 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1989 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2070 emitAddrSizeOverridePrefix(); | 1990 emitAddrSizeOverridePrefix(); |
| 2071 emitUint8(0xD9); | 1991 emitUint8(0xD9); |
| 2072 emitOperand(5, src); | 1992 emitOperand(5, src); |
| 2073 } | 1993 } |
| 2074 | 1994 |
| 2075 template <class Machine> | 1995 template <typename TraitsType> |
| 2076 template <typename T, typename> | 1996 template <typename T, typename> |
| 2077 void AssemblerX86Base<Machine>::fistpl(const typename T::Address &dst) { | 1997 void AssemblerX86Base<TraitsType>::fistpl(const typename T::Address &dst) { |
| 2078 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1998 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2079 emitAddrSizeOverridePrefix(); | 1999 emitAddrSizeOverridePrefix(); |
| 2080 emitUint8(0xDF); | 2000 emitUint8(0xDF); |
| 2081 emitOperand(7, dst); | 2001 emitOperand(7, dst); |
| 2082 } | 2002 } |
| 2083 | 2003 |
| 2084 template <class Machine> | 2004 template <typename TraitsType> |
| 2085 template <typename T, typename> | 2005 template <typename T, typename> |
| 2086 void AssemblerX86Base<Machine>::fistps(const typename T::Address &dst) { | 2006 void AssemblerX86Base<TraitsType>::fistps(const typename T::Address &dst) { |
| 2087 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2007 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2088 emitAddrSizeOverridePrefix(); | 2008 emitAddrSizeOverridePrefix(); |
| 2089 emitUint8(0xDB); | 2009 emitUint8(0xDB); |
| 2090 emitOperand(3, dst); | 2010 emitOperand(3, dst); |
| 2091 } | 2011 } |
| 2092 | 2012 |
| 2093 template <class Machine> | 2013 template <typename TraitsType> |
| 2094 template <typename T, typename> | 2014 template <typename T, typename> |
| 2095 void AssemblerX86Base<Machine>::fildl(const typename T::Address &src) { | 2015 void AssemblerX86Base<TraitsType>::fildl(const typename T::Address &src) { |
| 2096 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2016 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2097 emitAddrSizeOverridePrefix(); | 2017 emitAddrSizeOverridePrefix(); |
| 2098 emitUint8(0xDF); | 2018 emitUint8(0xDF); |
| 2099 emitOperand(5, src); | 2019 emitOperand(5, src); |
| 2100 } | 2020 } |
| 2101 | 2021 |
| 2102 template <class Machine> | 2022 template <typename TraitsType> |
| 2103 template <typename T, typename> | 2023 template <typename T, typename> |
| 2104 void AssemblerX86Base<Machine>::filds(const typename T::Address &src) { | 2024 void AssemblerX86Base<TraitsType>::filds(const typename T::Address &src) { |
| 2105 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2025 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2106 emitAddrSizeOverridePrefix(); | 2026 emitAddrSizeOverridePrefix(); |
| 2107 emitUint8(0xDB); | 2027 emitUint8(0xDB); |
| 2108 emitOperand(0, src); | 2028 emitOperand(0, src); |
| 2109 } | 2029 } |
| 2110 | 2030 |
| 2111 template <class Machine> | 2031 template <typename TraitsType> |
| 2112 template <typename, typename> | 2032 template <typename, typename> |
| 2113 void AssemblerX86Base<Machine>::fincstp() { | 2033 void AssemblerX86Base<TraitsType>::fincstp() { |
| 2114 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2034 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2115 emitUint8(0xD9); | 2035 emitUint8(0xD9); |
| 2116 emitUint8(0xF7); | 2036 emitUint8(0xF7); |
| 2117 } | 2037 } |
| 2118 | 2038 |
| 2119 template <class Machine> | 2039 template <typename TraitsType> |
| 2120 template <uint32_t Tag> | 2040 template <uint32_t Tag> |
| 2121 void AssemblerX86Base<Machine>::arith_int(Type Ty, | 2041 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, GPRRegister reg, |
| 2122 typename Traits::GPRRegister reg, | 2042 const Immediate &imm) { |
| 2123 const Immediate &imm) { | |
| 2124 static_assert(Tag < 8, "Tag must be between 0..7"); | 2043 static_assert(Tag < 8, "Tag must be between 0..7"); |
| 2125 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2044 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2126 if (Ty == IceType_i16) | 2045 if (Ty == IceType_i16) |
| 2127 emitOperandSizeOverride(); | 2046 emitOperandSizeOverride(); |
| 2128 emitRexB(Ty, reg); | 2047 emitRexB(Ty, reg); |
| 2129 if (isByteSizedType(Ty)) { | 2048 if (isByteSizedType(Ty)) { |
| 2130 emitComplexI8(Tag, typename Traits::Operand(reg), imm); | 2049 emitComplexI8(Tag, Operand(reg), imm); |
| 2131 } else { | 2050 } else { |
| 2132 emitComplex(Ty, Tag, typename Traits::Operand(reg), imm); | 2051 emitComplex(Ty, Tag, Operand(reg), imm); |
| 2133 } | 2052 } |
| 2134 } | 2053 } |
| 2135 | 2054 |
| 2136 template <class Machine> | 2055 template <typename TraitsType> |
| 2137 template <uint32_t Tag> | 2056 template <uint32_t Tag> |
| 2138 void AssemblerX86Base<Machine>::arith_int(Type Ty, | 2057 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, GPRRegister reg0, |
| 2139 typename Traits::GPRRegister reg0, | 2058 GPRRegister reg1) { |
| 2140 typename Traits::GPRRegister reg1) { | |
| 2141 static_assert(Tag < 8, "Tag must be between 0..7"); | 2059 static_assert(Tag < 8, "Tag must be between 0..7"); |
| 2142 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2060 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2143 if (Ty == IceType_i16) | 2061 if (Ty == IceType_i16) |
| 2144 emitOperandSizeOverride(); | 2062 emitOperandSizeOverride(); |
| 2145 emitRexRB(Ty, reg0, reg1); | 2063 emitRexRB(Ty, reg0, reg1); |
| 2146 if (isByteSizedType(Ty)) | 2064 if (isByteSizedType(Ty)) |
| 2147 emitUint8(Tag * 8 + 2); | 2065 emitUint8(Tag * 8 + 2); |
| 2148 else | 2066 else |
| 2149 emitUint8(Tag * 8 + 3); | 2067 emitUint8(Tag * 8 + 3); |
| 2150 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1)); | 2068 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1)); |
| 2151 } | 2069 } |
| 2152 | 2070 |
| 2153 template <class Machine> | 2071 template <typename TraitsType> |
| 2154 template <uint32_t Tag> | 2072 template <uint32_t Tag> |
| 2155 void AssemblerX86Base<Machine>::arith_int( | 2073 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, GPRRegister reg, |
| 2156 Type Ty, typename Traits::GPRRegister reg, | 2074 const Address &address) { |
| 2157 const typename Traits::Address &address) { | |
| 2158 static_assert(Tag < 8, "Tag must be between 0..7"); | 2075 static_assert(Tag < 8, "Tag must be between 0..7"); |
| 2159 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2076 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2160 if (Ty == IceType_i16) | 2077 if (Ty == IceType_i16) |
| 2161 emitOperandSizeOverride(); | 2078 emitOperandSizeOverride(); |
| 2162 emitAddrSizeOverridePrefix(); | 2079 emitAddrSizeOverridePrefix(); |
| 2163 emitRex(Ty, address, reg); | 2080 emitRex(Ty, address, reg); |
| 2164 if (isByteSizedType(Ty)) | 2081 if (isByteSizedType(Ty)) |
| 2165 emitUint8(Tag * 8 + 2); | 2082 emitUint8(Tag * 8 + 2); |
| 2166 else | 2083 else |
| 2167 emitUint8(Tag * 8 + 3); | 2084 emitUint8(Tag * 8 + 3); |
| 2168 emitOperand(gprEncoding(reg), address); | 2085 emitOperand(gprEncoding(reg), address); |
| 2169 } | 2086 } |
| 2170 | 2087 |
| 2171 template <class Machine> | 2088 template <typename TraitsType> |
| 2172 template <uint32_t Tag> | 2089 template <uint32_t Tag> |
| 2173 void AssemblerX86Base<Machine>::arith_int( | 2090 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, const Address &address, |
| 2174 Type Ty, const typename Traits::Address &address, | 2091 GPRRegister reg) { |
| 2175 typename Traits::GPRRegister reg) { | |
| 2176 static_assert(Tag < 8, "Tag must be between 0..7"); | 2092 static_assert(Tag < 8, "Tag must be between 0..7"); |
| 2177 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2093 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2178 if (Ty == IceType_i16) | 2094 if (Ty == IceType_i16) |
| 2179 emitOperandSizeOverride(); | 2095 emitOperandSizeOverride(); |
| 2180 emitAddrSizeOverridePrefix(); | 2096 emitAddrSizeOverridePrefix(); |
| 2181 emitRex(Ty, address, reg); | 2097 emitRex(Ty, address, reg); |
| 2182 if (isByteSizedType(Ty)) | 2098 if (isByteSizedType(Ty)) |
| 2183 emitUint8(Tag * 8 + 0); | 2099 emitUint8(Tag * 8 + 0); |
| 2184 else | 2100 else |
| 2185 emitUint8(Tag * 8 + 1); | 2101 emitUint8(Tag * 8 + 1); |
| 2186 emitOperand(gprEncoding(reg), address); | 2102 emitOperand(gprEncoding(reg), address); |
| 2187 } | 2103 } |
| 2188 | 2104 |
| 2189 template <class Machine> | 2105 template <typename TraitsType> |
| 2190 template <uint32_t Tag> | 2106 template <uint32_t Tag> |
| 2191 void AssemblerX86Base<Machine>::arith_int( | 2107 void AssemblerX86Base<TraitsType>::arith_int(Type Ty, const Address &address, |
| 2192 Type Ty, const typename Traits::Address &address, const Immediate &imm) { | 2108 const Immediate &imm) { |
| 2193 static_assert(Tag < 8, "Tag must be between 0..7"); | 2109 static_assert(Tag < 8, "Tag must be between 0..7"); |
| 2194 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2110 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2195 if (Ty == IceType_i16) | 2111 if (Ty == IceType_i16) |
| 2196 emitOperandSizeOverride(); | 2112 emitOperandSizeOverride(); |
| 2197 emitAddrSizeOverridePrefix(); | 2113 emitAddrSizeOverridePrefix(); |
| 2198 emitRex(Ty, address, RexRegIrrelevant); | 2114 emitRex(Ty, address, RexRegIrrelevant); |
| 2199 if (isByteSizedType(Ty)) { | 2115 if (isByteSizedType(Ty)) { |
| 2200 emitComplexI8(Tag, address, imm); | 2116 emitComplexI8(Tag, address, imm); |
| 2201 } else { | 2117 } else { |
| 2202 emitComplex(Ty, Tag, address, imm); | 2118 emitComplex(Ty, Tag, address, imm); |
| 2203 } | 2119 } |
| 2204 } | 2120 } |
| 2205 | 2121 |
| 2206 template <class Machine> | 2122 template <typename TraitsType> |
| 2207 void AssemblerX86Base<Machine>::cmp(Type Ty, typename Traits::GPRRegister reg, | 2123 void AssemblerX86Base<TraitsType>::cmp(Type Ty, GPRRegister reg, |
| 2208 const Immediate &imm) { | 2124 const Immediate &imm) { |
| 2209 arith_int<7>(Ty, reg, imm); | 2125 arith_int<7>(Ty, reg, imm); |
| 2210 } | 2126 } |
| 2211 | 2127 |
| 2212 template <class Machine> | 2128 template <typename TraitsType> |
| 2213 void AssemblerX86Base<Machine>::cmp(Type Ty, typename Traits::GPRRegister reg0, | 2129 void AssemblerX86Base<TraitsType>::cmp(Type Ty, GPRRegister reg0, |
| 2214 typename Traits::GPRRegister reg1) { | 2130 GPRRegister reg1) { |
| 2215 arith_int<7>(Ty, reg0, reg1); | 2131 arith_int<7>(Ty, reg0, reg1); |
| 2216 } | 2132 } |
| 2217 | 2133 |
| 2218 template <class Machine> | 2134 template <typename TraitsType> |
| 2219 void AssemblerX86Base<Machine>::cmp(Type Ty, typename Traits::GPRRegister reg, | 2135 void AssemblerX86Base<TraitsType>::cmp(Type Ty, GPRRegister reg, |
| 2220 const typename Traits::Address &address) { | 2136 const Address &address) { |
| 2221 arith_int<7>(Ty, reg, address); | 2137 arith_int<7>(Ty, reg, address); |
| 2222 } | 2138 } |
| 2223 | 2139 |
| 2224 template <class Machine> | 2140 template <typename TraitsType> |
| 2225 void AssemblerX86Base<Machine>::cmp(Type Ty, | 2141 void AssemblerX86Base<TraitsType>::cmp(Type Ty, const Address &address, |
| 2226 const typename Traits::Address &address, | 2142 GPRRegister reg) { |
| 2227 typename Traits::GPRRegister reg) { | |
| 2228 arith_int<7>(Ty, address, reg); | 2143 arith_int<7>(Ty, address, reg); |
| 2229 } | 2144 } |
| 2230 | 2145 |
| 2231 template <class Machine> | 2146 template <typename TraitsType> |
| 2232 void AssemblerX86Base<Machine>::cmp(Type Ty, | 2147 void AssemblerX86Base<TraitsType>::cmp(Type Ty, const Address &address, |
| 2233 const typename Traits::Address &address, | 2148 const Immediate &imm) { |
| 2234 const Immediate &imm) { | |
| 2235 arith_int<7>(Ty, address, imm); | 2149 arith_int<7>(Ty, address, imm); |
| 2236 } | 2150 } |
| 2237 | 2151 |
| 2238 template <class Machine> | 2152 template <typename TraitsType> |
| 2239 void AssemblerX86Base<Machine>::test(Type Ty, typename Traits::GPRRegister reg1, | 2153 void AssemblerX86Base<TraitsType>::test(Type Ty, GPRRegister reg1, |
| 2240 typename Traits::GPRRegister reg2) { | 2154 GPRRegister reg2) { |
| 2241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2155 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2242 if (Ty == IceType_i16) | 2156 if (Ty == IceType_i16) |
| 2243 emitOperandSizeOverride(); | 2157 emitOperandSizeOverride(); |
| 2244 emitRexRB(Ty, reg1, reg2); | 2158 emitRexRB(Ty, reg1, reg2); |
| 2245 if (isByteSizedType(Ty)) | 2159 if (isByteSizedType(Ty)) |
| 2246 emitUint8(0x84); | 2160 emitUint8(0x84); |
| 2247 else | 2161 else |
| 2248 emitUint8(0x85); | 2162 emitUint8(0x85); |
| 2249 emitRegisterOperand(gprEncoding(reg1), gprEncoding(reg2)); | 2163 emitRegisterOperand(gprEncoding(reg1), gprEncoding(reg2)); |
| 2250 } | 2164 } |
| 2251 | 2165 |
| 2252 template <class Machine> | 2166 template <typename TraitsType> |
| 2253 void AssemblerX86Base<Machine>::test(Type Ty, | 2167 void AssemblerX86Base<TraitsType>::test(Type Ty, const Address &addr, |
| 2254 const typename Traits::Address &addr, | 2168 GPRRegister reg) { |
| 2255 typename Traits::GPRRegister reg) { | |
| 2256 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2169 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2257 if (Ty == IceType_i16) | 2170 if (Ty == IceType_i16) |
| 2258 emitOperandSizeOverride(); | 2171 emitOperandSizeOverride(); |
| 2259 emitAddrSizeOverridePrefix(); | 2172 emitAddrSizeOverridePrefix(); |
| 2260 emitRex(Ty, addr, reg); | 2173 emitRex(Ty, addr, reg); |
| 2261 if (isByteSizedType(Ty)) | 2174 if (isByteSizedType(Ty)) |
| 2262 emitUint8(0x84); | 2175 emitUint8(0x84); |
| 2263 else | 2176 else |
| 2264 emitUint8(0x85); | 2177 emitUint8(0x85); |
| 2265 emitOperand(gprEncoding(reg), addr); | 2178 emitOperand(gprEncoding(reg), addr); |
| 2266 } | 2179 } |
| 2267 | 2180 |
| 2268 template <class Machine> | 2181 template <typename TraitsType> |
| 2269 void AssemblerX86Base<Machine>::test(Type Ty, typename Traits::GPRRegister reg, | 2182 void AssemblerX86Base<TraitsType>::test(Type Ty, GPRRegister reg, |
| 2270 const Immediate &immediate) { | 2183 const Immediate &immediate) { |
| 2271 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2184 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2272 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) we only | 2185 // For registers that have a byte variant (EAX, EBX, ECX, and EDX) we only |
| 2273 // test the byte register to keep the encoding short. This is legal even if | 2186 // test the byte register to keep the encoding short. This is legal even if |
| 2274 // the register had high bits set since this only sets flags registers based | 2187 // the register had high bits set since this only sets flags registers based |
| 2275 // on the "AND" of the two operands, and the immediate had zeros at those | 2188 // on the "AND" of the two operands, and the immediate had zeros at those |
| 2276 // high bits. | 2189 // high bits. |
| 2277 if (immediate.is_uint8() && reg <= Traits::Last8BitGPR) { | 2190 if (immediate.is_uint8() && reg <= Traits::Last8BitGPR) { |
| 2278 // Use zero-extended 8-bit immediate. | 2191 // Use zero-extended 8-bit immediate. |
| 2279 emitRexB(Ty, reg); | 2192 emitRexB(Ty, reg); |
| 2280 if (reg == Traits::Encoded_Reg_Accumulator) { | 2193 if (reg == Traits::Encoded_Reg_Accumulator) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2293 } else { | 2206 } else { |
| 2294 if (Ty == IceType_i16) | 2207 if (Ty == IceType_i16) |
| 2295 emitOperandSizeOverride(); | 2208 emitOperandSizeOverride(); |
| 2296 emitRexB(Ty, reg); | 2209 emitRexB(Ty, reg); |
| 2297 emitUint8(0xF7); | 2210 emitUint8(0xF7); |
| 2298 emitRegisterOperand(0, gprEncoding(reg)); | 2211 emitRegisterOperand(0, gprEncoding(reg)); |
| 2299 emitImmediate(Ty, immediate); | 2212 emitImmediate(Ty, immediate); |
| 2300 } | 2213 } |
| 2301 } | 2214 } |
| 2302 | 2215 |
| 2303 template <class Machine> | 2216 template <typename TraitsType> |
| 2304 void AssemblerX86Base<Machine>::test(Type Ty, | 2217 void AssemblerX86Base<TraitsType>::test(Type Ty, const Address &addr, |
| 2305 const typename Traits::Address &addr, | 2218 const Immediate &immediate) { |
| 2306 const Immediate &immediate) { | |
| 2307 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2219 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2308 // If the immediate is short, we only test the byte addr to keep the encoding | 2220 // If the immediate is short, we only test the byte addr to keep the encoding |
| 2309 // short. | 2221 // short. |
| 2310 if (immediate.is_uint8()) { | 2222 if (immediate.is_uint8()) { |
| 2311 // Use zero-extended 8-bit immediate. | 2223 // Use zero-extended 8-bit immediate. |
| 2312 emitAddrSizeOverridePrefix(); | 2224 emitAddrSizeOverridePrefix(); |
| 2313 emitRex(Ty, addr, RexRegIrrelevant); | 2225 emitRex(Ty, addr, RexRegIrrelevant); |
| 2314 emitUint8(0xF6); | 2226 emitUint8(0xF6); |
| 2315 emitOperand(0, addr); | 2227 emitOperand(0, addr); |
| 2316 emitUint8(immediate.value() & 0xFF); | 2228 emitUint8(immediate.value() & 0xFF); |
| 2317 } else { | 2229 } else { |
| 2318 if (Ty == IceType_i16) | 2230 if (Ty == IceType_i16) |
| 2319 emitOperandSizeOverride(); | 2231 emitOperandSizeOverride(); |
| 2320 emitAddrSizeOverridePrefix(); | 2232 emitAddrSizeOverridePrefix(); |
| 2321 emitRex(Ty, addr, RexRegIrrelevant); | 2233 emitRex(Ty, addr, RexRegIrrelevant); |
| 2322 emitUint8(0xF7); | 2234 emitUint8(0xF7); |
| 2323 emitOperand(0, addr); | 2235 emitOperand(0, addr); |
| 2324 emitImmediate(Ty, immediate); | 2236 emitImmediate(Ty, immediate); |
| 2325 } | 2237 } |
| 2326 } | 2238 } |
| 2327 | 2239 |
| 2328 template <class Machine> | 2240 template <typename TraitsType> |
| 2329 void AssemblerX86Base<Machine>::And(Type Ty, typename Traits::GPRRegister dst, | 2241 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst, |
| 2330 typename Traits::GPRRegister src) { | 2242 GPRRegister src) { |
| 2331 arith_int<4>(Ty, dst, src); | 2243 arith_int<4>(Ty, dst, src); |
| 2332 } | 2244 } |
| 2333 | 2245 |
| 2334 template <class Machine> | 2246 template <typename TraitsType> |
| 2335 void AssemblerX86Base<Machine>::And(Type Ty, typename Traits::GPRRegister dst, | 2247 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst, |
| 2336 const typename Traits::Address &address) { | 2248 const Address &address) { |
| 2337 arith_int<4>(Ty, dst, address); | 2249 arith_int<4>(Ty, dst, address); |
| 2338 } | 2250 } |
| 2339 | 2251 |
| 2340 template <class Machine> | 2252 template <typename TraitsType> |
| 2341 void AssemblerX86Base<Machine>::And(Type Ty, typename Traits::GPRRegister dst, | 2253 void AssemblerX86Base<TraitsType>::And(Type Ty, GPRRegister dst, |
| 2342 const Immediate &imm) { | 2254 const Immediate &imm) { |
| 2343 arith_int<4>(Ty, dst, imm); | 2255 arith_int<4>(Ty, dst, imm); |
| 2344 } | 2256 } |
| 2345 | 2257 |
| 2346 template <class Machine> | 2258 template <typename TraitsType> |
| 2347 void AssemblerX86Base<Machine>::And(Type Ty, | 2259 void AssemblerX86Base<TraitsType>::And(Type Ty, const Address &address, |
| 2348 const typename Traits::Address &address, | 2260 GPRRegister reg) { |
| 2349 typename Traits::GPRRegister reg) { | |
| 2350 arith_int<4>(Ty, address, reg); | 2261 arith_int<4>(Ty, address, reg); |
| 2351 } | 2262 } |
| 2352 | 2263 |
| 2353 template <class Machine> | 2264 template <typename TraitsType> |
| 2354 void AssemblerX86Base<Machine>::And(Type Ty, | 2265 void AssemblerX86Base<TraitsType>::And(Type Ty, const Address &address, |
| 2355 const typename Traits::Address &address, | 2266 const Immediate &imm) { |
| 2356 const Immediate &imm) { | |
| 2357 arith_int<4>(Ty, address, imm); | 2267 arith_int<4>(Ty, address, imm); |
| 2358 } | 2268 } |
| 2359 | 2269 |
| 2360 template <class Machine> | 2270 template <typename TraitsType> |
| 2361 void AssemblerX86Base<Machine>::Or(Type Ty, typename Traits::GPRRegister dst, | 2271 void AssemblerX86Base<TraitsType>::Or(Type Ty, GPRRegister dst, |
| 2362 typename Traits::GPRRegister src) { | 2272 GPRRegister src) { |
| 2363 arith_int<1>(Ty, dst, src); | 2273 arith_int<1>(Ty, dst, src); |
| 2364 } | 2274 } |
| 2365 | 2275 |
| 2366 template <class Machine> | 2276 template <typename TraitsType> |
| 2367 void AssemblerX86Base<Machine>::Or(Type Ty, typename Traits::GPRRegister dst, | 2277 void AssemblerX86Base<TraitsType>::Or(Type Ty, GPRRegister dst, |
| 2368 const typename Traits::Address &address) { | 2278 const Address &address) { |
| 2369 arith_int<1>(Ty, dst, address); | 2279 arith_int<1>(Ty, dst, address); |
| 2370 } | 2280 } |
| 2371 | 2281 |
| 2372 template <class Machine> | 2282 template <typename TraitsType> |
| 2373 void AssemblerX86Base<Machine>::Or(Type Ty, typename Traits::GPRRegister dst, | 2283 void AssemblerX86Base<TraitsType>::Or(Type Ty, GPRRegister dst, |
| 2374 const Immediate &imm) { | 2284 const Immediate &imm) { |
| 2375 arith_int<1>(Ty, dst, imm); | 2285 arith_int<1>(Ty, dst, imm); |
| 2376 } | 2286 } |
| 2377 | 2287 |
| 2378 template <class Machine> | 2288 template <typename TraitsType> |
| 2379 void AssemblerX86Base<Machine>::Or(Type Ty, | 2289 void AssemblerX86Base<TraitsType>::Or(Type Ty, const Address &address, |
| 2380 const typename Traits::Address &address, | 2290 GPRRegister reg) { |
| 2381 typename Traits::GPRRegister reg) { | |
| 2382 arith_int<1>(Ty, address, reg); | 2291 arith_int<1>(Ty, address, reg); |
| 2383 } | 2292 } |
| 2384 | 2293 |
| 2385 template <class Machine> | 2294 template <typename TraitsType> |
| 2386 void AssemblerX86Base<Machine>::Or(Type Ty, | 2295 void AssemblerX86Base<TraitsType>::Or(Type Ty, const Address &address, |
| 2387 const typename Traits::Address &address, | 2296 const Immediate &imm) { |
| 2388 const Immediate &imm) { | |
| 2389 arith_int<1>(Ty, address, imm); | 2297 arith_int<1>(Ty, address, imm); |
| 2390 } | 2298 } |
| 2391 | 2299 |
| 2392 template <class Machine> | 2300 template <typename TraitsType> |
| 2393 void AssemblerX86Base<Machine>::Xor(Type Ty, typename Traits::GPRRegister dst, | 2301 void AssemblerX86Base<TraitsType>::Xor(Type Ty, GPRRegister dst, |
| 2394 typename Traits::GPRRegister src) { | 2302 GPRRegister src) { |
| 2395 arith_int<6>(Ty, dst, src); | 2303 arith_int<6>(Ty, dst, src); |
| 2396 } | 2304 } |
| 2397 | 2305 |
| 2398 template <class Machine> | 2306 template <typename TraitsType> |
| 2399 void AssemblerX86Base<Machine>::Xor(Type Ty, typename Traits::GPRRegister dst, | 2307 void AssemblerX86Base<TraitsType>::Xor(Type Ty, GPRRegister dst, |
| 2400 const typename Traits::Address &address) { | 2308 const Address &address) { |
| 2401 arith_int<6>(Ty, dst, address); | 2309 arith_int<6>(Ty, dst, address); |
| 2402 } | 2310 } |
| 2403 | 2311 |
| 2404 template <class Machine> | 2312 template <typename TraitsType> |
| 2405 void AssemblerX86Base<Machine>::Xor(Type Ty, typename Traits::GPRRegister dst, | 2313 void AssemblerX86Base<TraitsType>::Xor(Type Ty, GPRRegister dst, |
| 2406 const Immediate &imm) { | 2314 const Immediate &imm) { |
| 2407 arith_int<6>(Ty, dst, imm); | 2315 arith_int<6>(Ty, dst, imm); |
| 2408 } | 2316 } |
| 2409 | 2317 |
| 2410 template <class Machine> | 2318 template <typename TraitsType> |
| 2411 void AssemblerX86Base<Machine>::Xor(Type Ty, | 2319 void AssemblerX86Base<TraitsType>::Xor(Type Ty, const Address &address, |
| 2412 const typename Traits::Address &address, | 2320 GPRRegister reg) { |
| 2413 typename Traits::GPRRegister reg) { | |
| 2414 arith_int<6>(Ty, address, reg); | 2321 arith_int<6>(Ty, address, reg); |
| 2415 } | 2322 } |
| 2416 | 2323 |
| 2417 template <class Machine> | 2324 template <typename TraitsType> |
| 2418 void AssemblerX86Base<Machine>::Xor(Type Ty, | 2325 void AssemblerX86Base<TraitsType>::Xor(Type Ty, const Address &address, |
| 2419 const typename Traits::Address &address, | 2326 const Immediate &imm) { |
| 2420 const Immediate &imm) { | |
| 2421 arith_int<6>(Ty, address, imm); | 2327 arith_int<6>(Ty, address, imm); |
| 2422 } | 2328 } |
| 2423 | 2329 |
| 2424 template <class Machine> | 2330 template <typename TraitsType> |
| 2425 void AssemblerX86Base<Machine>::add(Type Ty, typename Traits::GPRRegister dst, | 2331 void AssemblerX86Base<TraitsType>::add(Type Ty, GPRRegister dst, |
| 2426 typename Traits::GPRRegister src) { | 2332 GPRRegister src) { |
| 2427 arith_int<0>(Ty, dst, src); | 2333 arith_int<0>(Ty, dst, src); |
| 2428 } | 2334 } |
| 2429 | 2335 |
| 2430 template <class Machine> | 2336 template <typename TraitsType> |
| 2431 void AssemblerX86Base<Machine>::add(Type Ty, typename Traits::GPRRegister reg, | 2337 void AssemblerX86Base<TraitsType>::add(Type Ty, GPRRegister reg, |
| 2432 const typename Traits::Address &address) { | 2338 const Address &address) { |
| 2433 arith_int<0>(Ty, reg, address); | 2339 arith_int<0>(Ty, reg, address); |
| 2434 } | 2340 } |
| 2435 | 2341 |
| 2436 template <class Machine> | 2342 template <typename TraitsType> |
| 2437 void AssemblerX86Base<Machine>::add(Type Ty, typename Traits::GPRRegister reg, | 2343 void AssemblerX86Base<TraitsType>::add(Type Ty, GPRRegister reg, |
| 2438 const Immediate &imm) { | 2344 const Immediate &imm) { |
| 2439 arith_int<0>(Ty, reg, imm); | 2345 arith_int<0>(Ty, reg, imm); |
| 2440 } | 2346 } |
| 2441 | 2347 |
| 2442 template <class Machine> | 2348 template <typename TraitsType> |
| 2443 void AssemblerX86Base<Machine>::add(Type Ty, | 2349 void AssemblerX86Base<TraitsType>::add(Type Ty, const Address &address, |
| 2444 const typename Traits::Address &address, | 2350 GPRRegister reg) { |
| 2445 typename Traits::GPRRegister reg) { | |
| 2446 arith_int<0>(Ty, address, reg); | 2351 arith_int<0>(Ty, address, reg); |
| 2447 } | 2352 } |
| 2448 | 2353 |
| 2449 template <class Machine> | 2354 template <typename TraitsType> |
| 2450 void AssemblerX86Base<Machine>::add(Type Ty, | 2355 void AssemblerX86Base<TraitsType>::add(Type Ty, const Address &address, |
| 2451 const typename Traits::Address &address, | 2356 const Immediate &imm) { |
| 2452 const Immediate &imm) { | |
| 2453 arith_int<0>(Ty, address, imm); | 2357 arith_int<0>(Ty, address, imm); |
| 2454 } | 2358 } |
| 2455 | 2359 |
| 2456 template <class Machine> | 2360 template <typename TraitsType> |
| 2457 void AssemblerX86Base<Machine>::adc(Type Ty, typename Traits::GPRRegister dst, | 2361 void AssemblerX86Base<TraitsType>::adc(Type Ty, GPRRegister dst, |
| 2458 typename Traits::GPRRegister src) { | 2362 GPRRegister src) { |
| 2459 arith_int<2>(Ty, dst, src); | 2363 arith_int<2>(Ty, dst, src); |
| 2460 } | 2364 } |
| 2461 | 2365 |
| 2462 template <class Machine> | 2366 template <typename TraitsType> |
| 2463 void AssemblerX86Base<Machine>::adc(Type Ty, typename Traits::GPRRegister dst, | 2367 void AssemblerX86Base<TraitsType>::adc(Type Ty, GPRRegister dst, |
| 2464 const typename Traits::Address &address) { | 2368 const Address &address) { |
| 2465 arith_int<2>(Ty, dst, address); | 2369 arith_int<2>(Ty, dst, address); |
| 2466 } | 2370 } |
| 2467 | 2371 |
| 2468 template <class Machine> | 2372 template <typename TraitsType> |
| 2469 void AssemblerX86Base<Machine>::adc(Type Ty, typename Traits::GPRRegister reg, | 2373 void AssemblerX86Base<TraitsType>::adc(Type Ty, GPRRegister reg, |
| 2470 const Immediate &imm) { | 2374 const Immediate &imm) { |
| 2471 arith_int<2>(Ty, reg, imm); | 2375 arith_int<2>(Ty, reg, imm); |
| 2472 } | 2376 } |
| 2473 | 2377 |
| 2474 template <class Machine> | 2378 template <typename TraitsType> |
| 2475 void AssemblerX86Base<Machine>::adc(Type Ty, | 2379 void AssemblerX86Base<TraitsType>::adc(Type Ty, const Address &address, |
| 2476 const typename Traits::Address &address, | 2380 GPRRegister reg) { |
| 2477 typename Traits::GPRRegister reg) { | |
| 2478 arith_int<2>(Ty, address, reg); | 2381 arith_int<2>(Ty, address, reg); |
| 2479 } | 2382 } |
| 2480 | 2383 |
| 2481 template <class Machine> | 2384 template <typename TraitsType> |
| 2482 void AssemblerX86Base<Machine>::adc(Type Ty, | 2385 void AssemblerX86Base<TraitsType>::adc(Type Ty, const Address &address, |
| 2483 const typename Traits::Address &address, | 2386 const Immediate &imm) { |
| 2484 const Immediate &imm) { | |
| 2485 arith_int<2>(Ty, address, imm); | 2387 arith_int<2>(Ty, address, imm); |
| 2486 } | 2388 } |
| 2487 | 2389 |
| 2488 template <class Machine> | 2390 template <typename TraitsType> |
| 2489 void AssemblerX86Base<Machine>::sub(Type Ty, typename Traits::GPRRegister dst, | 2391 void AssemblerX86Base<TraitsType>::sub(Type Ty, GPRRegister dst, |
| 2490 typename Traits::GPRRegister src) { | 2392 GPRRegister src) { |
| 2491 arith_int<5>(Ty, dst, src); | 2393 arith_int<5>(Ty, dst, src); |
| 2492 } | 2394 } |
| 2493 | 2395 |
| 2494 template <class Machine> | 2396 template <typename TraitsType> |
| 2495 void AssemblerX86Base<Machine>::sub(Type Ty, typename Traits::GPRRegister reg, | 2397 void AssemblerX86Base<TraitsType>::sub(Type Ty, GPRRegister reg, |
| 2496 const typename Traits::Address &address) { | 2398 const Address &address) { |
| 2497 arith_int<5>(Ty, reg, address); | 2399 arith_int<5>(Ty, reg, address); |
| 2498 } | 2400 } |
| 2499 | 2401 |
| 2500 template <class Machine> | 2402 template <typename TraitsType> |
| 2501 void AssemblerX86Base<Machine>::sub(Type Ty, typename Traits::GPRRegister reg, | 2403 void AssemblerX86Base<TraitsType>::sub(Type Ty, GPRRegister reg, |
| 2502 const Immediate &imm) { | 2404 const Immediate &imm) { |
| 2503 arith_int<5>(Ty, reg, imm); | 2405 arith_int<5>(Ty, reg, imm); |
| 2504 } | 2406 } |
| 2505 | 2407 |
| 2506 template <class Machine> | 2408 template <typename TraitsType> |
| 2507 void AssemblerX86Base<Machine>::sub(Type Ty, | 2409 void AssemblerX86Base<TraitsType>::sub(Type Ty, const Address &address, |
| 2508 const typename Traits::Address &address, | 2410 GPRRegister reg) { |
| 2509 typename Traits::GPRRegister reg) { | |
| 2510 arith_int<5>(Ty, address, reg); | 2411 arith_int<5>(Ty, address, reg); |
| 2511 } | 2412 } |
| 2512 | 2413 |
| 2513 template <class Machine> | 2414 template <typename TraitsType> |
| 2514 void AssemblerX86Base<Machine>::sub(Type Ty, | 2415 void AssemblerX86Base<TraitsType>::sub(Type Ty, const Address &address, |
| 2515 const typename Traits::Address &address, | 2416 const Immediate &imm) { |
| 2516 const Immediate &imm) { | |
| 2517 arith_int<5>(Ty, address, imm); | 2417 arith_int<5>(Ty, address, imm); |
| 2518 } | 2418 } |
| 2519 | 2419 |
| 2520 template <class Machine> | 2420 template <typename TraitsType> |
| 2521 void AssemblerX86Base<Machine>::sbb(Type Ty, typename Traits::GPRRegister dst, | 2421 void AssemblerX86Base<TraitsType>::sbb(Type Ty, GPRRegister dst, |
| 2522 typename Traits::GPRRegister src) { | 2422 GPRRegister src) { |
| 2523 arith_int<3>(Ty, dst, src); | 2423 arith_int<3>(Ty, dst, src); |
| 2524 } | 2424 } |
| 2525 | 2425 |
| 2526 template <class Machine> | 2426 template <typename TraitsType> |
| 2527 void AssemblerX86Base<Machine>::sbb(Type Ty, typename Traits::GPRRegister dst, | 2427 void AssemblerX86Base<TraitsType>::sbb(Type Ty, GPRRegister dst, |
| 2528 const typename Traits::Address &address) { | 2428 const Address &address) { |
| 2529 arith_int<3>(Ty, dst, address); | 2429 arith_int<3>(Ty, dst, address); |
| 2530 } | 2430 } |
| 2531 | 2431 |
| 2532 template <class Machine> | 2432 template <typename TraitsType> |
| 2533 void AssemblerX86Base<Machine>::sbb(Type Ty, typename Traits::GPRRegister reg, | 2433 void AssemblerX86Base<TraitsType>::sbb(Type Ty, GPRRegister reg, |
| 2534 const Immediate &imm) { | 2434 const Immediate &imm) { |
| 2535 arith_int<3>(Ty, reg, imm); | 2435 arith_int<3>(Ty, reg, imm); |
| 2536 } | 2436 } |
| 2537 | 2437 |
| 2538 template <class Machine> | 2438 template <typename TraitsType> |
| 2539 void AssemblerX86Base<Machine>::sbb(Type Ty, | 2439 void AssemblerX86Base<TraitsType>::sbb(Type Ty, const Address &address, |
| 2540 const typename Traits::Address &address, | 2440 GPRRegister reg) { |
| 2541 typename Traits::GPRRegister reg) { | |
| 2542 arith_int<3>(Ty, address, reg); | 2441 arith_int<3>(Ty, address, reg); |
| 2543 } | 2442 } |
| 2544 | 2443 |
| 2545 template <class Machine> | 2444 template <typename TraitsType> |
| 2546 void AssemblerX86Base<Machine>::sbb(Type Ty, | 2445 void AssemblerX86Base<TraitsType>::sbb(Type Ty, const Address &address, |
| 2547 const typename Traits::Address &address, | 2446 const Immediate &imm) { |
| 2548 const Immediate &imm) { | |
| 2549 arith_int<3>(Ty, address, imm); | 2447 arith_int<3>(Ty, address, imm); |
| 2550 } | 2448 } |
| 2551 | 2449 |
| 2552 template <class Machine> void AssemblerX86Base<Machine>::cbw() { | 2450 template <typename TraitsType> void AssemblerX86Base<TraitsType>::cbw() { |
| 2553 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2451 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2554 emitOperandSizeOverride(); | 2452 emitOperandSizeOverride(); |
| 2555 emitUint8(0x98); | 2453 emitUint8(0x98); |
| 2556 } | 2454 } |
| 2557 | 2455 |
| 2558 template <class Machine> void AssemblerX86Base<Machine>::cwd() { | 2456 template <typename TraitsType> void AssemblerX86Base<TraitsType>::cwd() { |
| 2559 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2457 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2560 emitOperandSizeOverride(); | 2458 emitOperandSizeOverride(); |
| 2561 emitUint8(0x99); | 2459 emitUint8(0x99); |
| 2562 } | 2460 } |
| 2563 | 2461 |
| 2564 template <class Machine> void AssemblerX86Base<Machine>::cdq() { | 2462 template <typename TraitsType> void AssemblerX86Base<TraitsType>::cdq() { |
| 2565 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2463 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2566 emitUint8(0x99); | 2464 emitUint8(0x99); |
| 2567 } | 2465 } |
| 2568 | 2466 |
| 2569 template <class Machine> | 2467 template <typename TraitsType> |
| 2570 template <typename T> | 2468 template <typename T> |
| 2571 typename std::enable_if<T::Is64Bit, void>::type | 2469 typename std::enable_if<T::Is64Bit, void>::type |
| 2572 AssemblerX86Base<Machine>::cqo() { | 2470 AssemblerX86Base<TraitsType>::cqo() { |
| 2573 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2471 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2574 emitRexB(RexTypeForceRexW, RexRegIrrelevant); | 2472 emitRexB(RexTypeForceRexW, RexRegIrrelevant); |
| 2575 emitUint8(0x99); | 2473 emitUint8(0x99); |
| 2576 } | 2474 } |
| 2577 | 2475 |
| 2578 template <class Machine> | 2476 template <typename TraitsType> |
| 2579 void AssemblerX86Base<Machine>::div(Type Ty, typename Traits::GPRRegister reg) { | 2477 void AssemblerX86Base<TraitsType>::div(Type Ty, GPRRegister reg) { |
| 2580 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2478 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2581 if (Ty == IceType_i16) | 2479 if (Ty == IceType_i16) |
| 2582 emitOperandSizeOverride(); | 2480 emitOperandSizeOverride(); |
| 2583 emitRexB(Ty, reg); | 2481 emitRexB(Ty, reg); |
| 2584 if (isByteSizedArithType(Ty)) | 2482 if (isByteSizedArithType(Ty)) |
| 2585 emitUint8(0xF6); | 2483 emitUint8(0xF6); |
| 2586 else | 2484 else |
| 2587 emitUint8(0xF7); | 2485 emitUint8(0xF7); |
| 2588 emitRegisterOperand(6, gprEncoding(reg)); | 2486 emitRegisterOperand(6, gprEncoding(reg)); |
| 2589 } | 2487 } |
| 2590 | 2488 |
| 2591 template <class Machine> | 2489 template <typename TraitsType> |
| 2592 void AssemblerX86Base<Machine>::div(Type Ty, | 2490 void AssemblerX86Base<TraitsType>::div(Type Ty, const Address &addr) { |
| 2593 const typename Traits::Address &addr) { | |
| 2594 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2491 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2595 if (Ty == IceType_i16) | 2492 if (Ty == IceType_i16) |
| 2596 emitOperandSizeOverride(); | 2493 emitOperandSizeOverride(); |
| 2597 emitAddrSizeOverridePrefix(); | 2494 emitAddrSizeOverridePrefix(); |
| 2598 emitRex(Ty, addr, RexRegIrrelevant); | 2495 emitRex(Ty, addr, RexRegIrrelevant); |
| 2599 if (isByteSizedArithType(Ty)) | 2496 if (isByteSizedArithType(Ty)) |
| 2600 emitUint8(0xF6); | 2497 emitUint8(0xF6); |
| 2601 else | 2498 else |
| 2602 emitUint8(0xF7); | 2499 emitUint8(0xF7); |
| 2603 emitOperand(6, addr); | 2500 emitOperand(6, addr); |
| 2604 } | 2501 } |
| 2605 | 2502 |
| 2606 template <class Machine> | 2503 template <typename TraitsType> |
| 2607 void AssemblerX86Base<Machine>::idiv(Type Ty, | 2504 void AssemblerX86Base<TraitsType>::idiv(Type Ty, GPRRegister reg) { |
| 2608 typename Traits::GPRRegister reg) { | |
| 2609 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2505 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2610 if (Ty == IceType_i16) | 2506 if (Ty == IceType_i16) |
| 2611 emitOperandSizeOverride(); | 2507 emitOperandSizeOverride(); |
| 2612 emitRexB(Ty, reg); | 2508 emitRexB(Ty, reg); |
| 2613 if (isByteSizedArithType(Ty)) | 2509 if (isByteSizedArithType(Ty)) |
| 2614 emitUint8(0xF6); | 2510 emitUint8(0xF6); |
| 2615 else | 2511 else |
| 2616 emitUint8(0xF7); | 2512 emitUint8(0xF7); |
| 2617 emitRegisterOperand(7, gprEncoding(reg)); | 2513 emitRegisterOperand(7, gprEncoding(reg)); |
| 2618 } | 2514 } |
| 2619 | 2515 |
| 2620 template <class Machine> | 2516 template <typename TraitsType> |
| 2621 void AssemblerX86Base<Machine>::idiv(Type Ty, | 2517 void AssemblerX86Base<TraitsType>::idiv(Type Ty, const Address &addr) { |
| 2622 const typename Traits::Address &addr) { | |
| 2623 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2518 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2624 if (Ty == IceType_i16) | 2519 if (Ty == IceType_i16) |
| 2625 emitOperandSizeOverride(); | 2520 emitOperandSizeOverride(); |
| 2626 emitAddrSizeOverridePrefix(); | 2521 emitAddrSizeOverridePrefix(); |
| 2627 emitRex(Ty, addr, RexRegIrrelevant); | 2522 emitRex(Ty, addr, RexRegIrrelevant); |
| 2628 if (isByteSizedArithType(Ty)) | 2523 if (isByteSizedArithType(Ty)) |
| 2629 emitUint8(0xF6); | 2524 emitUint8(0xF6); |
| 2630 else | 2525 else |
| 2631 emitUint8(0xF7); | 2526 emitUint8(0xF7); |
| 2632 emitOperand(7, addr); | 2527 emitOperand(7, addr); |
| 2633 } | 2528 } |
| 2634 | 2529 |
| 2635 template <class Machine> | 2530 template <typename TraitsType> |
| 2636 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, | 2531 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister dst, |
| 2637 typename Traits::GPRRegister src) { | 2532 GPRRegister src) { |
| 2638 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2533 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2639 assert(Ty == IceType_i16 || Ty == IceType_i32 || | 2534 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 2640 (Traits::Is64Bit && Ty == IceType_i64)); | 2535 (Traits::Is64Bit && Ty == IceType_i64)); |
| 2641 if (Ty == IceType_i16) | 2536 if (Ty == IceType_i16) |
| 2642 emitOperandSizeOverride(); | 2537 emitOperandSizeOverride(); |
| 2643 emitRexRB(Ty, dst, src); | 2538 emitRexRB(Ty, dst, src); |
| 2644 emitUint8(0x0F); | 2539 emitUint8(0x0F); |
| 2645 emitUint8(0xAF); | 2540 emitUint8(0xAF); |
| 2646 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 2541 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 2647 } | 2542 } |
| 2648 | 2543 |
| 2649 template <class Machine> | 2544 template <typename TraitsType> |
| 2650 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, | 2545 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg, |
| 2651 const typename Traits::Address &address) { | 2546 const Address &address) { |
| 2652 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2547 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2653 assert(Ty == IceType_i16 || Ty == IceType_i32 || | 2548 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 2654 (Traits::Is64Bit && Ty == IceType_i64)); | 2549 (Traits::Is64Bit && Ty == IceType_i64)); |
| 2655 if (Ty == IceType_i16) | 2550 if (Ty == IceType_i16) |
| 2656 emitOperandSizeOverride(); | 2551 emitOperandSizeOverride(); |
| 2657 emitAddrSizeOverridePrefix(); | 2552 emitAddrSizeOverridePrefix(); |
| 2658 emitRex(Ty, address, reg); | 2553 emitRex(Ty, address, reg); |
| 2659 emitUint8(0x0F); | 2554 emitUint8(0x0F); |
| 2660 emitUint8(0xAF); | 2555 emitUint8(0xAF); |
| 2661 emitOperand(gprEncoding(reg), address); | 2556 emitOperand(gprEncoding(reg), address); |
| 2662 } | 2557 } |
| 2663 | 2558 |
| 2664 template <class Machine> | 2559 template <typename TraitsType> |
| 2665 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister reg, | 2560 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg, |
| 2666 const Immediate &imm) { | 2561 const Immediate &imm) { |
| 2667 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2562 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2668 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2563 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2669 if (Ty == IceType_i16) | 2564 if (Ty == IceType_i16) |
| 2670 emitOperandSizeOverride(); | 2565 emitOperandSizeOverride(); |
| 2671 emitRexRB(Ty, reg, reg); | 2566 emitRexRB(Ty, reg, reg); |
| 2672 if (imm.is_int8()) { | 2567 if (imm.is_int8()) { |
| 2673 emitUint8(0x6B); | 2568 emitUint8(0x6B); |
| 2674 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg)); | 2569 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg)); |
| 2675 emitUint8(imm.value() & 0xFF); | 2570 emitUint8(imm.value() & 0xFF); |
| 2676 } else { | 2571 } else { |
| 2677 emitUint8(0x69); | 2572 emitUint8(0x69); |
| 2678 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg)); | 2573 emitRegisterOperand(gprEncoding(reg), gprEncoding(reg)); |
| 2679 emitImmediate(Ty, imm); | 2574 emitImmediate(Ty, imm); |
| 2680 } | 2575 } |
| 2681 } | 2576 } |
| 2682 | 2577 |
| 2683 template <class Machine> | 2578 template <typename TraitsType> |
| 2684 void AssemblerX86Base<Machine>::imul(Type Ty, | 2579 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister reg) { |
| 2685 typename Traits::GPRRegister reg) { | |
| 2686 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2580 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2687 if (Ty == IceType_i16) | 2581 if (Ty == IceType_i16) |
| 2688 emitOperandSizeOverride(); | 2582 emitOperandSizeOverride(); |
| 2689 emitRexB(Ty, reg); | 2583 emitRexB(Ty, reg); |
| 2690 if (isByteSizedArithType(Ty)) | 2584 if (isByteSizedArithType(Ty)) |
| 2691 emitUint8(0xF6); | 2585 emitUint8(0xF6); |
| 2692 else | 2586 else |
| 2693 emitUint8(0xF7); | 2587 emitUint8(0xF7); |
| 2694 emitRegisterOperand(5, gprEncoding(reg)); | 2588 emitRegisterOperand(5, gprEncoding(reg)); |
| 2695 } | 2589 } |
| 2696 | 2590 |
| 2697 template <class Machine> | 2591 template <typename TraitsType> |
| 2698 void AssemblerX86Base<Machine>::imul(Type Ty, | 2592 void AssemblerX86Base<TraitsType>::imul(Type Ty, const Address &address) { |
| 2699 const typename Traits::Address &address) { | |
| 2700 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2593 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2701 if (Ty == IceType_i16) | 2594 if (Ty == IceType_i16) |
| 2702 emitOperandSizeOverride(); | 2595 emitOperandSizeOverride(); |
| 2703 emitAddrSizeOverridePrefix(); | 2596 emitAddrSizeOverridePrefix(); |
| 2704 emitRex(Ty, address, RexRegIrrelevant); | 2597 emitRex(Ty, address, RexRegIrrelevant); |
| 2705 if (isByteSizedArithType(Ty)) | 2598 if (isByteSizedArithType(Ty)) |
| 2706 emitUint8(0xF6); | 2599 emitUint8(0xF6); |
| 2707 else | 2600 else |
| 2708 emitUint8(0xF7); | 2601 emitUint8(0xF7); |
| 2709 emitOperand(5, address); | 2602 emitOperand(5, address); |
| 2710 } | 2603 } |
| 2711 | 2604 |
| 2712 template <class Machine> | 2605 template <typename TraitsType> |
| 2713 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, | 2606 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister dst, |
| 2714 typename Traits::GPRRegister src, | 2607 GPRRegister src, const Immediate &imm) { |
| 2715 const Immediate &imm) { | |
| 2716 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2608 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2717 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2609 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2718 if (Ty == IceType_i16) | 2610 if (Ty == IceType_i16) |
| 2719 emitOperandSizeOverride(); | 2611 emitOperandSizeOverride(); |
| 2720 emitRexRB(Ty, dst, src); | 2612 emitRexRB(Ty, dst, src); |
| 2721 if (imm.is_int8()) { | 2613 if (imm.is_int8()) { |
| 2722 emitUint8(0x6B); | 2614 emitUint8(0x6B); |
| 2723 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 2615 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 2724 emitUint8(imm.value() & 0xFF); | 2616 emitUint8(imm.value() & 0xFF); |
| 2725 } else { | 2617 } else { |
| 2726 emitUint8(0x69); | 2618 emitUint8(0x69); |
| 2727 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 2619 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 2728 emitImmediate(Ty, imm); | 2620 emitImmediate(Ty, imm); |
| 2729 } | 2621 } |
| 2730 } | 2622 } |
| 2731 | 2623 |
| 2732 template <class Machine> | 2624 template <typename TraitsType> |
| 2733 void AssemblerX86Base<Machine>::imul(Type Ty, typename Traits::GPRRegister dst, | 2625 void AssemblerX86Base<TraitsType>::imul(Type Ty, GPRRegister dst, |
| 2734 const typename Traits::Address &address, | 2626 const Address &address, |
| 2735 const Immediate &imm) { | 2627 const Immediate &imm) { |
| 2736 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2628 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2737 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2629 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2738 if (Ty == IceType_i16) | 2630 if (Ty == IceType_i16) |
| 2739 emitOperandSizeOverride(); | 2631 emitOperandSizeOverride(); |
| 2740 emitAddrSizeOverridePrefix(); | 2632 emitAddrSizeOverridePrefix(); |
| 2741 emitRex(Ty, address, dst); | 2633 emitRex(Ty, address, dst); |
| 2742 if (imm.is_int8()) { | 2634 if (imm.is_int8()) { |
| 2743 emitUint8(0x6B); | 2635 emitUint8(0x6B); |
| 2744 emitOperand(gprEncoding(dst), address); | 2636 emitOperand(gprEncoding(dst), address); |
| 2745 emitUint8(imm.value() & 0xFF); | 2637 emitUint8(imm.value() & 0xFF); |
| 2746 } else { | 2638 } else { |
| 2747 emitUint8(0x69); | 2639 emitUint8(0x69); |
| 2748 emitOperand(gprEncoding(dst), address); | 2640 emitOperand(gprEncoding(dst), address); |
| 2749 emitImmediate(Ty, imm); | 2641 emitImmediate(Ty, imm); |
| 2750 } | 2642 } |
| 2751 } | 2643 } |
| 2752 | 2644 |
| 2753 template <class Machine> | 2645 template <typename TraitsType> |
| 2754 void AssemblerX86Base<Machine>::mul(Type Ty, typename Traits::GPRRegister reg) { | 2646 void AssemblerX86Base<TraitsType>::mul(Type Ty, GPRRegister reg) { |
| 2755 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2647 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2756 if (Ty == IceType_i16) | 2648 if (Ty == IceType_i16) |
| 2757 emitOperandSizeOverride(); | 2649 emitOperandSizeOverride(); |
| 2758 emitRexB(Ty, reg); | 2650 emitRexB(Ty, reg); |
| 2759 if (isByteSizedArithType(Ty)) | 2651 if (isByteSizedArithType(Ty)) |
| 2760 emitUint8(0xF6); | 2652 emitUint8(0xF6); |
| 2761 else | 2653 else |
| 2762 emitUint8(0xF7); | 2654 emitUint8(0xF7); |
| 2763 emitRegisterOperand(4, gprEncoding(reg)); | 2655 emitRegisterOperand(4, gprEncoding(reg)); |
| 2764 } | 2656 } |
| 2765 | 2657 |
| 2766 template <class Machine> | 2658 template <typename TraitsType> |
| 2767 void AssemblerX86Base<Machine>::mul(Type Ty, | 2659 void AssemblerX86Base<TraitsType>::mul(Type Ty, const Address &address) { |
| 2768 const typename Traits::Address &address) { | |
| 2769 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2660 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2770 if (Ty == IceType_i16) | 2661 if (Ty == IceType_i16) |
| 2771 emitOperandSizeOverride(); | 2662 emitOperandSizeOverride(); |
| 2772 emitAddrSizeOverridePrefix(); | 2663 emitAddrSizeOverridePrefix(); |
| 2773 emitRex(Ty, address, RexRegIrrelevant); | 2664 emitRex(Ty, address, RexRegIrrelevant); |
| 2774 if (isByteSizedArithType(Ty)) | 2665 if (isByteSizedArithType(Ty)) |
| 2775 emitUint8(0xF6); | 2666 emitUint8(0xF6); |
| 2776 else | 2667 else |
| 2777 emitUint8(0xF7); | 2668 emitUint8(0xF7); |
| 2778 emitOperand(4, address); | 2669 emitOperand(4, address); |
| 2779 } | 2670 } |
| 2780 | 2671 |
| 2781 template <class Machine> | 2672 template <typename TraitsType> |
| 2782 template <typename, typename> | 2673 template <typename, typename> |
| 2783 void AssemblerX86Base<Machine>::incl(typename Traits::GPRRegister reg) { | 2674 void AssemblerX86Base<TraitsType>::incl(GPRRegister reg) { |
| 2784 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2675 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2785 emitUint8(0x40 + reg); | 2676 emitUint8(0x40 + reg); |
| 2786 } | 2677 } |
| 2787 | 2678 |
| 2788 template <class Machine> | 2679 template <typename TraitsType> |
| 2789 void AssemblerX86Base<Machine>::incl(const typename Traits::Address &address) { | 2680 void AssemblerX86Base<TraitsType>::incl(const Address &address) { |
| 2790 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2681 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2791 emitAddrSizeOverridePrefix(); | 2682 emitAddrSizeOverridePrefix(); |
| 2792 emitRex(IceType_i32, address, RexRegIrrelevant); | 2683 emitRex(IceType_i32, address, RexRegIrrelevant); |
| 2793 emitUint8(0xFF); | 2684 emitUint8(0xFF); |
| 2794 emitOperand(0, address); | 2685 emitOperand(0, address); |
| 2795 } | 2686 } |
| 2796 | 2687 |
| 2797 template <class Machine> | 2688 template <typename TraitsType> |
| 2798 template <typename, typename> | 2689 template <typename, typename> |
| 2799 void AssemblerX86Base<Machine>::decl(typename Traits::GPRRegister reg) { | 2690 void AssemblerX86Base<TraitsType>::decl(GPRRegister reg) { |
| 2800 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2691 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2801 emitUint8(0x48 + reg); | 2692 emitUint8(0x48 + reg); |
| 2802 } | 2693 } |
| 2803 | 2694 |
| 2804 template <class Machine> | 2695 template <typename TraitsType> |
| 2805 void AssemblerX86Base<Machine>::decl(const typename Traits::Address &address) { | 2696 void AssemblerX86Base<TraitsType>::decl(const Address &address) { |
| 2806 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2697 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2807 emitAddrSizeOverridePrefix(); | 2698 emitAddrSizeOverridePrefix(); |
| 2808 emitRex(IceType_i32, address, RexRegIrrelevant); | 2699 emitRex(IceType_i32, address, RexRegIrrelevant); |
| 2809 emitUint8(0xFF); | 2700 emitUint8(0xFF); |
| 2810 emitOperand(1, address); | 2701 emitOperand(1, address); |
| 2811 } | 2702 } |
| 2812 | 2703 |
| 2813 template <class Machine> | 2704 template <typename TraitsType> |
| 2814 void AssemblerX86Base<Machine>::rol(Type Ty, typename Traits::GPRRegister reg, | 2705 void AssemblerX86Base<TraitsType>::rol(Type Ty, GPRRegister reg, |
| 2815 const Immediate &imm) { | 2706 const Immediate &imm) { |
| 2816 emitGenericShift(0, Ty, reg, imm); | 2707 emitGenericShift(0, Ty, reg, imm); |
| 2817 } | 2708 } |
| 2818 | 2709 |
| 2819 template <class Machine> | 2710 template <typename TraitsType> |
| 2820 void AssemblerX86Base<Machine>::rol(Type Ty, | 2711 void AssemblerX86Base<TraitsType>::rol(Type Ty, GPRRegister operand, |
| 2821 typename Traits::GPRRegister operand, | 2712 GPRRegister shifter) { |
| 2822 typename Traits::GPRRegister shifter) { | 2713 emitGenericShift(0, Ty, Operand(operand), shifter); |
| 2823 emitGenericShift(0, Ty, typename Traits::Operand(operand), shifter); | |
| 2824 } | 2714 } |
| 2825 | 2715 |
| 2826 template <class Machine> | 2716 template <typename TraitsType> |
| 2827 void AssemblerX86Base<Machine>::rol(Type Ty, | 2717 void AssemblerX86Base<TraitsType>::rol(Type Ty, const Address &operand, |
| 2828 const typename Traits::Address &operand, | 2718 GPRRegister shifter) { |
| 2829 typename Traits::GPRRegister shifter) { | |
| 2830 emitGenericShift(0, Ty, operand, shifter); | 2719 emitGenericShift(0, Ty, operand, shifter); |
| 2831 } | 2720 } |
| 2832 | 2721 |
| 2833 template <class Machine> | 2722 template <typename TraitsType> |
| 2834 void AssemblerX86Base<Machine>::shl(Type Ty, typename Traits::GPRRegister reg, | 2723 void AssemblerX86Base<TraitsType>::shl(Type Ty, GPRRegister reg, |
| 2835 const Immediate &imm) { | 2724 const Immediate &imm) { |
| 2836 emitGenericShift(4, Ty, reg, imm); | 2725 emitGenericShift(4, Ty, reg, imm); |
| 2837 } | 2726 } |
| 2838 | 2727 |
| 2839 template <class Machine> | 2728 template <typename TraitsType> |
| 2840 void AssemblerX86Base<Machine>::shl(Type Ty, | 2729 void AssemblerX86Base<TraitsType>::shl(Type Ty, GPRRegister operand, |
| 2841 typename Traits::GPRRegister operand, | 2730 GPRRegister shifter) { |
| 2842 typename Traits::GPRRegister shifter) { | 2731 emitGenericShift(4, Ty, Operand(operand), shifter); |
| 2843 emitGenericShift(4, Ty, typename Traits::Operand(operand), shifter); | |
| 2844 } | 2732 } |
| 2845 | 2733 |
| 2846 template <class Machine> | 2734 template <typename TraitsType> |
| 2847 void AssemblerX86Base<Machine>::shl(Type Ty, | 2735 void AssemblerX86Base<TraitsType>::shl(Type Ty, const Address &operand, |
| 2848 const typename Traits::Address &operand, | 2736 GPRRegister shifter) { |
| 2849 typename Traits::GPRRegister shifter) { | |
| 2850 emitGenericShift(4, Ty, operand, shifter); | 2737 emitGenericShift(4, Ty, operand, shifter); |
| 2851 } | 2738 } |
| 2852 | 2739 |
| 2853 template <class Machine> | 2740 template <typename TraitsType> |
| 2854 void AssemblerX86Base<Machine>::shr(Type Ty, typename Traits::GPRRegister reg, | 2741 void AssemblerX86Base<TraitsType>::shr(Type Ty, GPRRegister reg, |
| 2855 const Immediate &imm) { | 2742 const Immediate &imm) { |
| 2856 emitGenericShift(5, Ty, reg, imm); | 2743 emitGenericShift(5, Ty, reg, imm); |
| 2857 } | 2744 } |
| 2858 | 2745 |
| 2859 template <class Machine> | 2746 template <typename TraitsType> |
| 2860 void AssemblerX86Base<Machine>::shr(Type Ty, | 2747 void AssemblerX86Base<TraitsType>::shr(Type Ty, GPRRegister operand, |
| 2861 typename Traits::GPRRegister operand, | 2748 GPRRegister shifter) { |
| 2862 typename Traits::GPRRegister shifter) { | 2749 emitGenericShift(5, Ty, Operand(operand), shifter); |
| 2863 emitGenericShift(5, Ty, typename Traits::Operand(operand), shifter); | |
| 2864 } | 2750 } |
| 2865 | 2751 |
| 2866 template <class Machine> | 2752 template <typename TraitsType> |
| 2867 void AssemblerX86Base<Machine>::shr(Type Ty, | 2753 void AssemblerX86Base<TraitsType>::shr(Type Ty, const Address &operand, |
| 2868 const typename Traits::Address &operand, | 2754 GPRRegister shifter) { |
| 2869 typename Traits::GPRRegister shifter) { | |
| 2870 emitGenericShift(5, Ty, operand, shifter); | 2755 emitGenericShift(5, Ty, operand, shifter); |
| 2871 } | 2756 } |
| 2872 | 2757 |
| 2873 template <class Machine> | 2758 template <typename TraitsType> |
| 2874 void AssemblerX86Base<Machine>::sar(Type Ty, typename Traits::GPRRegister reg, | 2759 void AssemblerX86Base<TraitsType>::sar(Type Ty, GPRRegister reg, |
| 2875 const Immediate &imm) { | 2760 const Immediate &imm) { |
| 2876 emitGenericShift(7, Ty, reg, imm); | 2761 emitGenericShift(7, Ty, reg, imm); |
| 2877 } | 2762 } |
| 2878 | 2763 |
| 2879 template <class Machine> | 2764 template <typename TraitsType> |
| 2880 void AssemblerX86Base<Machine>::sar(Type Ty, | 2765 void AssemblerX86Base<TraitsType>::sar(Type Ty, GPRRegister operand, |
| 2881 typename Traits::GPRRegister operand, | 2766 GPRRegister shifter) { |
| 2882 typename Traits::GPRRegister shifter) { | 2767 emitGenericShift(7, Ty, Operand(operand), shifter); |
| 2883 emitGenericShift(7, Ty, typename Traits::Operand(operand), shifter); | |
| 2884 } | 2768 } |
| 2885 | 2769 |
| 2886 template <class Machine> | 2770 template <typename TraitsType> |
| 2887 void AssemblerX86Base<Machine>::sar(Type Ty, | 2771 void AssemblerX86Base<TraitsType>::sar(Type Ty, const Address &address, |
| 2888 const typename Traits::Address &address, | 2772 GPRRegister shifter) { |
| 2889 typename Traits::GPRRegister shifter) { | |
| 2890 emitGenericShift(7, Ty, address, shifter); | 2773 emitGenericShift(7, Ty, address, shifter); |
| 2891 } | 2774 } |
| 2892 | 2775 |
| 2893 template <class Machine> | 2776 template <typename TraitsType> |
| 2894 void AssemblerX86Base<Machine>::shld(Type Ty, typename Traits::GPRRegister dst, | 2777 void AssemblerX86Base<TraitsType>::shld(Type Ty, GPRRegister dst, |
| 2895 typename Traits::GPRRegister src) { | 2778 GPRRegister src) { |
| 2896 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2779 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2897 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2780 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2898 if (Ty == IceType_i16) | 2781 if (Ty == IceType_i16) |
| 2899 emitOperandSizeOverride(); | 2782 emitOperandSizeOverride(); |
| 2900 emitRexRB(Ty, src, dst); | 2783 emitRexRB(Ty, src, dst); |
| 2901 emitUint8(0x0F); | 2784 emitUint8(0x0F); |
| 2902 emitUint8(0xA5); | 2785 emitUint8(0xA5); |
| 2903 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 2786 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 2904 } | 2787 } |
| 2905 | 2788 |
| 2906 template <class Machine> | 2789 template <typename TraitsType> |
| 2907 void AssemblerX86Base<Machine>::shld(Type Ty, typename Traits::GPRRegister dst, | 2790 void AssemblerX86Base<TraitsType>::shld(Type Ty, GPRRegister dst, |
| 2908 typename Traits::GPRRegister src, | 2791 GPRRegister src, const Immediate &imm) { |
| 2909 const Immediate &imm) { | |
| 2910 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2792 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2911 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2793 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2912 assert(imm.is_int8()); | 2794 assert(imm.is_int8()); |
| 2913 if (Ty == IceType_i16) | 2795 if (Ty == IceType_i16) |
| 2914 emitOperandSizeOverride(); | 2796 emitOperandSizeOverride(); |
| 2915 emitRexRB(Ty, src, dst); | 2797 emitRexRB(Ty, src, dst); |
| 2916 emitUint8(0x0F); | 2798 emitUint8(0x0F); |
| 2917 emitUint8(0xA4); | 2799 emitUint8(0xA4); |
| 2918 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 2800 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 2919 emitUint8(imm.value() & 0xFF); | 2801 emitUint8(imm.value() & 0xFF); |
| 2920 } | 2802 } |
| 2921 | 2803 |
| 2922 template <class Machine> | 2804 template <typename TraitsType> |
| 2923 void AssemblerX86Base<Machine>::shld(Type Ty, | 2805 void AssemblerX86Base<TraitsType>::shld(Type Ty, const Address &operand, |
| 2924 const typename Traits::Address &operand, | 2806 GPRRegister src) { |
| 2925 typename Traits::GPRRegister src) { | |
| 2926 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2807 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2927 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2808 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2928 if (Ty == IceType_i16) | 2809 if (Ty == IceType_i16) |
| 2929 emitOperandSizeOverride(); | 2810 emitOperandSizeOverride(); |
| 2930 emitAddrSizeOverridePrefix(); | 2811 emitAddrSizeOverridePrefix(); |
| 2931 emitRex(Ty, operand, src); | 2812 emitRex(Ty, operand, src); |
| 2932 emitUint8(0x0F); | 2813 emitUint8(0x0F); |
| 2933 emitUint8(0xA5); | 2814 emitUint8(0xA5); |
| 2934 emitOperand(gprEncoding(src), operand); | 2815 emitOperand(gprEncoding(src), operand); |
| 2935 } | 2816 } |
| 2936 | 2817 |
| 2937 template <class Machine> | 2818 template <typename TraitsType> |
| 2938 void AssemblerX86Base<Machine>::shrd(Type Ty, typename Traits::GPRRegister dst, | 2819 void AssemblerX86Base<TraitsType>::shrd(Type Ty, GPRRegister dst, |
| 2939 typename Traits::GPRRegister src) { | 2820 GPRRegister src) { |
| 2940 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2821 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2941 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2822 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2942 if (Ty == IceType_i16) | 2823 if (Ty == IceType_i16) |
| 2943 emitOperandSizeOverride(); | 2824 emitOperandSizeOverride(); |
| 2944 emitRexRB(Ty, src, dst); | 2825 emitRexRB(Ty, src, dst); |
| 2945 emitUint8(0x0F); | 2826 emitUint8(0x0F); |
| 2946 emitUint8(0xAD); | 2827 emitUint8(0xAD); |
| 2947 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 2828 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 2948 } | 2829 } |
| 2949 | 2830 |
| 2950 template <class Machine> | 2831 template <typename TraitsType> |
| 2951 void AssemblerX86Base<Machine>::shrd(Type Ty, typename Traits::GPRRegister dst, | 2832 void AssemblerX86Base<TraitsType>::shrd(Type Ty, GPRRegister dst, |
| 2952 typename Traits::GPRRegister src, | 2833 GPRRegister src, const Immediate &imm) { |
| 2953 const Immediate &imm) { | |
| 2954 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2834 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2955 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2835 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2956 assert(imm.is_int8()); | 2836 assert(imm.is_int8()); |
| 2957 if (Ty == IceType_i16) | 2837 if (Ty == IceType_i16) |
| 2958 emitOperandSizeOverride(); | 2838 emitOperandSizeOverride(); |
| 2959 emitRexRB(Ty, src, dst); | 2839 emitRexRB(Ty, src, dst); |
| 2960 emitUint8(0x0F); | 2840 emitUint8(0x0F); |
| 2961 emitUint8(0xAC); | 2841 emitUint8(0xAC); |
| 2962 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); | 2842 emitRegisterOperand(gprEncoding(src), gprEncoding(dst)); |
| 2963 emitUint8(imm.value() & 0xFF); | 2843 emitUint8(imm.value() & 0xFF); |
| 2964 } | 2844 } |
| 2965 | 2845 |
| 2966 template <class Machine> | 2846 template <typename TraitsType> |
| 2967 void AssemblerX86Base<Machine>::shrd(Type Ty, | 2847 void AssemblerX86Base<TraitsType>::shrd(Type Ty, const Address &dst, |
| 2968 const typename Traits::Address &dst, | 2848 GPRRegister src) { |
| 2969 typename Traits::GPRRegister src) { | |
| 2970 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2849 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2971 assert(Ty == IceType_i16 || Ty == IceType_i32); | 2850 assert(Ty == IceType_i16 || Ty == IceType_i32); |
| 2972 if (Ty == IceType_i16) | 2851 if (Ty == IceType_i16) |
| 2973 emitOperandSizeOverride(); | 2852 emitOperandSizeOverride(); |
| 2974 emitAddrSizeOverridePrefix(); | 2853 emitAddrSizeOverridePrefix(); |
| 2975 emitRex(Ty, dst, src); | 2854 emitRex(Ty, dst, src); |
| 2976 emitUint8(0x0F); | 2855 emitUint8(0x0F); |
| 2977 emitUint8(0xAD); | 2856 emitUint8(0xAD); |
| 2978 emitOperand(gprEncoding(src), dst); | 2857 emitOperand(gprEncoding(src), dst); |
| 2979 } | 2858 } |
| 2980 | 2859 |
| 2981 template <class Machine> | 2860 template <typename TraitsType> |
| 2982 void AssemblerX86Base<Machine>::neg(Type Ty, typename Traits::GPRRegister reg) { | 2861 void AssemblerX86Base<TraitsType>::neg(Type Ty, GPRRegister reg) { |
| 2983 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2862 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2984 if (Ty == IceType_i16) | 2863 if (Ty == IceType_i16) |
| 2985 emitOperandSizeOverride(); | 2864 emitOperandSizeOverride(); |
| 2986 emitRexB(Ty, reg); | 2865 emitRexB(Ty, reg); |
| 2987 if (isByteSizedArithType(Ty)) | 2866 if (isByteSizedArithType(Ty)) |
| 2988 emitUint8(0xF6); | 2867 emitUint8(0xF6); |
| 2989 else | 2868 else |
| 2990 emitUint8(0xF7); | 2869 emitUint8(0xF7); |
| 2991 emitRegisterOperand(3, gprEncoding(reg)); | 2870 emitRegisterOperand(3, gprEncoding(reg)); |
| 2992 } | 2871 } |
| 2993 | 2872 |
| 2994 template <class Machine> | 2873 template <typename TraitsType> |
| 2995 void AssemblerX86Base<Machine>::neg(Type Ty, | 2874 void AssemblerX86Base<TraitsType>::neg(Type Ty, const Address &addr) { |
| 2996 const typename Traits::Address &addr) { | |
| 2997 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2875 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 2998 if (Ty == IceType_i16) | 2876 if (Ty == IceType_i16) |
| 2999 emitOperandSizeOverride(); | 2877 emitOperandSizeOverride(); |
| 3000 emitAddrSizeOverridePrefix(); | 2878 emitAddrSizeOverridePrefix(); |
| 3001 emitRex(Ty, addr, RexRegIrrelevant); | 2879 emitRex(Ty, addr, RexRegIrrelevant); |
| 3002 if (isByteSizedArithType(Ty)) | 2880 if (isByteSizedArithType(Ty)) |
| 3003 emitUint8(0xF6); | 2881 emitUint8(0xF6); |
| 3004 else | 2882 else |
| 3005 emitUint8(0xF7); | 2883 emitUint8(0xF7); |
| 3006 emitOperand(3, addr); | 2884 emitOperand(3, addr); |
| 3007 } | 2885 } |
| 3008 | 2886 |
| 3009 template <class Machine> | 2887 template <typename TraitsType> |
| 3010 void AssemblerX86Base<Machine>::notl(typename Traits::GPRRegister reg) { | 2888 void AssemblerX86Base<TraitsType>::notl(GPRRegister reg) { |
| 3011 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2889 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3012 emitRexB(IceType_i32, reg); | 2890 emitRexB(IceType_i32, reg); |
| 3013 emitUint8(0xF7); | 2891 emitUint8(0xF7); |
| 3014 emitUint8(0xD0 | gprEncoding(reg)); | 2892 emitUint8(0xD0 | gprEncoding(reg)); |
| 3015 } | 2893 } |
| 3016 | 2894 |
| 3017 template <class Machine> | 2895 template <typename TraitsType> |
| 3018 void AssemblerX86Base<Machine>::bswap(Type Ty, | 2896 void AssemblerX86Base<TraitsType>::bswap(Type Ty, GPRRegister reg) { |
| 3019 typename Traits::GPRRegister reg) { | |
| 3020 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2897 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3021 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); | 2898 assert(Ty == IceType_i32 || (Traits::Is64Bit && Ty == IceType_i64)); |
| 3022 emitRexB(Ty, reg); | 2899 emitRexB(Ty, reg); |
| 3023 emitUint8(0x0F); | 2900 emitUint8(0x0F); |
| 3024 emitUint8(0xC8 | gprEncoding(reg)); | 2901 emitUint8(0xC8 | gprEncoding(reg)); |
| 3025 } | 2902 } |
| 3026 | 2903 |
| 3027 template <class Machine> | 2904 template <typename TraitsType> |
| 3028 void AssemblerX86Base<Machine>::bsf(Type Ty, typename Traits::GPRRegister dst, | 2905 void AssemblerX86Base<TraitsType>::bsf(Type Ty, GPRRegister dst, |
| 3029 typename Traits::GPRRegister src) { | 2906 GPRRegister src) { |
| 3030 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2907 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3031 assert(Ty == IceType_i16 || Ty == IceType_i32 || | 2908 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 3032 (Traits::Is64Bit && Ty == IceType_i64)); | 2909 (Traits::Is64Bit && Ty == IceType_i64)); |
| 3033 if (Ty == IceType_i16) | 2910 if (Ty == IceType_i16) |
| 3034 emitOperandSizeOverride(); | 2911 emitOperandSizeOverride(); |
| 3035 emitRexRB(Ty, dst, src); | 2912 emitRexRB(Ty, dst, src); |
| 3036 emitUint8(0x0F); | 2913 emitUint8(0x0F); |
| 3037 emitUint8(0xBC); | 2914 emitUint8(0xBC); |
| 3038 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 2915 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 3039 } | 2916 } |
| 3040 | 2917 |
| 3041 template <class Machine> | 2918 template <typename TraitsType> |
| 3042 void AssemblerX86Base<Machine>::bsf(Type Ty, typename Traits::GPRRegister dst, | 2919 void AssemblerX86Base<TraitsType>::bsf(Type Ty, GPRRegister dst, |
| 3043 const typename Traits::Address &src) { | 2920 const Address &src) { |
| 3044 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2921 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3045 assert(Ty == IceType_i16 || Ty == IceType_i32 || | 2922 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 3046 (Traits::Is64Bit && Ty == IceType_i64)); | 2923 (Traits::Is64Bit && Ty == IceType_i64)); |
| 3047 if (Ty == IceType_i16) | 2924 if (Ty == IceType_i16) |
| 3048 emitOperandSizeOverride(); | 2925 emitOperandSizeOverride(); |
| 3049 emitAddrSizeOverridePrefix(); | 2926 emitAddrSizeOverridePrefix(); |
| 3050 emitRex(Ty, src, dst); | 2927 emitRex(Ty, src, dst); |
| 3051 emitUint8(0x0F); | 2928 emitUint8(0x0F); |
| 3052 emitUint8(0xBC); | 2929 emitUint8(0xBC); |
| 3053 emitOperand(gprEncoding(dst), src); | 2930 emitOperand(gprEncoding(dst), src); |
| 3054 } | 2931 } |
| 3055 | 2932 |
| 3056 template <class Machine> | 2933 template <typename TraitsType> |
| 3057 void AssemblerX86Base<Machine>::bsr(Type Ty, typename Traits::GPRRegister dst, | 2934 void AssemblerX86Base<TraitsType>::bsr(Type Ty, GPRRegister dst, |
| 3058 typename Traits::GPRRegister src) { | 2935 GPRRegister src) { |
| 3059 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2936 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3060 assert(Ty == IceType_i16 || Ty == IceType_i32 || | 2937 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 3061 (Traits::Is64Bit && Ty == IceType_i64)); | 2938 (Traits::Is64Bit && Ty == IceType_i64)); |
| 3062 if (Ty == IceType_i16) | 2939 if (Ty == IceType_i16) |
| 3063 emitOperandSizeOverride(); | 2940 emitOperandSizeOverride(); |
| 3064 emitRexRB(Ty, dst, src); | 2941 emitRexRB(Ty, dst, src); |
| 3065 emitUint8(0x0F); | 2942 emitUint8(0x0F); |
| 3066 emitUint8(0xBD); | 2943 emitUint8(0xBD); |
| 3067 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); | 2944 emitRegisterOperand(gprEncoding(dst), gprEncoding(src)); |
| 3068 } | 2945 } |
| 3069 | 2946 |
| 3070 template <class Machine> | 2947 template <typename TraitsType> |
| 3071 void AssemblerX86Base<Machine>::bsr(Type Ty, typename Traits::GPRRegister dst, | 2948 void AssemblerX86Base<TraitsType>::bsr(Type Ty, GPRRegister dst, |
| 3072 const typename Traits::Address &src) { | 2949 const Address &src) { |
| 3073 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2950 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3074 assert(Ty == IceType_i16 || Ty == IceType_i32 || | 2951 assert(Ty == IceType_i16 || Ty == IceType_i32 || |
| 3075 (Traits::Is64Bit && Ty == IceType_i64)); | 2952 (Traits::Is64Bit && Ty == IceType_i64)); |
| 3076 if (Ty == IceType_i16) | 2953 if (Ty == IceType_i16) |
| 3077 emitOperandSizeOverride(); | 2954 emitOperandSizeOverride(); |
| 3078 emitAddrSizeOverridePrefix(); | 2955 emitAddrSizeOverridePrefix(); |
| 3079 emitRex(Ty, src, dst); | 2956 emitRex(Ty, src, dst); |
| 3080 emitUint8(0x0F); | 2957 emitUint8(0x0F); |
| 3081 emitUint8(0xBD); | 2958 emitUint8(0xBD); |
| 3082 emitOperand(gprEncoding(dst), src); | 2959 emitOperand(gprEncoding(dst), src); |
| 3083 } | 2960 } |
| 3084 | 2961 |
| 3085 template <class Machine> | 2962 template <typename TraitsType> |
| 3086 void AssemblerX86Base<Machine>::bt(typename Traits::GPRRegister base, | 2963 void AssemblerX86Base<TraitsType>::bt(GPRRegister base, GPRRegister offset) { |
| 3087 typename Traits::GPRRegister offset) { | |
| 3088 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2964 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3089 emitRexRB(IceType_i32, offset, base); | 2965 emitRexRB(IceType_i32, offset, base); |
| 3090 emitUint8(0x0F); | 2966 emitUint8(0x0F); |
| 3091 emitUint8(0xA3); | 2967 emitUint8(0xA3); |
| 3092 emitRegisterOperand(gprEncoding(offset), gprEncoding(base)); | 2968 emitRegisterOperand(gprEncoding(offset), gprEncoding(base)); |
| 3093 } | 2969 } |
| 3094 | 2970 |
| 3095 template <class Machine> void AssemblerX86Base<Machine>::ret() { | 2971 template <typename TraitsType> void AssemblerX86Base<TraitsType>::ret() { |
| 3096 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2972 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3097 emitUint8(0xC3); | 2973 emitUint8(0xC3); |
| 3098 } | 2974 } |
| 3099 | 2975 |
| 3100 template <class Machine> | 2976 template <typename TraitsType> |
| 3101 void AssemblerX86Base<Machine>::ret(const Immediate &imm) { | 2977 void AssemblerX86Base<TraitsType>::ret(const Immediate &imm) { |
| 3102 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2978 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3103 emitUint8(0xC2); | 2979 emitUint8(0xC2); |
| 3104 assert(imm.is_uint16()); | 2980 assert(imm.is_uint16()); |
| 3105 emitUint8(imm.value() & 0xFF); | 2981 emitUint8(imm.value() & 0xFF); |
| 3106 emitUint8((imm.value() >> 8) & 0xFF); | 2982 emitUint8((imm.value() >> 8) & 0xFF); |
| 3107 } | 2983 } |
| 3108 | 2984 |
| 3109 template <class Machine> void AssemblerX86Base<Machine>::nop(int size) { | 2985 template <typename TraitsType> |
| 2986 void AssemblerX86Base<TraitsType>::nop(int size) { |
| 3110 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 2987 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3111 // There are nops up to size 15, but for now just provide up to size 8. | 2988 // There are nops up to size 15, but for now just provide up to size 8. |
| 3112 assert(0 < size && size <= MAX_NOP_SIZE); | 2989 assert(0 < size && size <= MAX_NOP_SIZE); |
| 3113 switch (size) { | 2990 switch (size) { |
| 3114 case 1: | 2991 case 1: |
| 3115 emitUint8(0x90); | 2992 emitUint8(0x90); |
| 3116 break; | 2993 break; |
| 3117 case 2: | 2994 case 2: |
| 3118 emitUint8(0x66); | 2995 emitUint8(0x66); |
| 3119 emitUint8(0x90); | 2996 emitUint8(0x90); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3161 emitUint8(0x00); | 3038 emitUint8(0x00); |
| 3162 emitUint8(0x00); | 3039 emitUint8(0x00); |
| 3163 emitUint8(0x00); | 3040 emitUint8(0x00); |
| 3164 emitUint8(0x00); | 3041 emitUint8(0x00); |
| 3165 break; | 3042 break; |
| 3166 default: | 3043 default: |
| 3167 llvm_unreachable("Unimplemented"); | 3044 llvm_unreachable("Unimplemented"); |
| 3168 } | 3045 } |
| 3169 } | 3046 } |
| 3170 | 3047 |
| 3171 template <class Machine> void AssemblerX86Base<Machine>::int3() { | 3048 template <typename TraitsType> void AssemblerX86Base<TraitsType>::int3() { |
| 3172 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3049 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3173 emitUint8(0xCC); | 3050 emitUint8(0xCC); |
| 3174 } | 3051 } |
| 3175 | 3052 |
| 3176 template <class Machine> void AssemblerX86Base<Machine>::hlt() { | 3053 template <typename TraitsType> void AssemblerX86Base<TraitsType>::hlt() { |
| 3177 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3054 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3178 emitUint8(0xF4); | 3055 emitUint8(0xF4); |
| 3179 } | 3056 } |
| 3180 | 3057 |
| 3181 template <class Machine> void AssemblerX86Base<Machine>::ud2() { | 3058 template <typename TraitsType> void AssemblerX86Base<TraitsType>::ud2() { |
| 3182 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3059 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3183 emitUint8(0x0F); | 3060 emitUint8(0x0F); |
| 3184 emitUint8(0x0B); | 3061 emitUint8(0x0B); |
| 3185 } | 3062 } |
| 3186 | 3063 |
| 3187 template <class Machine> | 3064 template <typename TraitsType> |
| 3188 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, | 3065 void AssemblerX86Base<TraitsType>::j(BrCond condition, Label *label, |
| 3189 Label *label, bool near) { | 3066 bool near) { |
| 3190 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3067 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3191 if (label->isBound()) { | 3068 if (label->isBound()) { |
| 3192 static const int kShortSize = 2; | 3069 static const int kShortSize = 2; |
| 3193 static const int kLongSize = 6; | 3070 static const int kLongSize = 6; |
| 3194 intptr_t offset = label->getPosition() - Buffer.size(); | 3071 intptr_t offset = label->getPosition() - Buffer.size(); |
| 3195 assert(offset <= 0); | 3072 assert(offset <= 0); |
| 3196 if (Utils::IsInt(8, offset - kShortSize)) { | 3073 if (Utils::IsInt(8, offset - kShortSize)) { |
| 3197 // TODO(stichnot): Here and in jmp(), we may need to be more | 3074 // TODO(stichnot): Here and in jmp(), we may need to be more |
| 3198 // conservative about the backward branch distance if the branch | 3075 // conservative about the backward branch distance if the branch |
| 3199 // instruction is within a bundle_lock sequence, because the | 3076 // instruction is within a bundle_lock sequence, because the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3211 } else if (near) { | 3088 } else if (near) { |
| 3212 emitUint8(0x70 + condition); | 3089 emitUint8(0x70 + condition); |
| 3213 emitNearLabelLink(label); | 3090 emitNearLabelLink(label); |
| 3214 } else { | 3091 } else { |
| 3215 emitUint8(0x0F); | 3092 emitUint8(0x0F); |
| 3216 emitUint8(0x80 + condition); | 3093 emitUint8(0x80 + condition); |
| 3217 emitLabelLink(label); | 3094 emitLabelLink(label); |
| 3218 } | 3095 } |
| 3219 } | 3096 } |
| 3220 | 3097 |
| 3221 template <class Machine> | 3098 template <typename TraitsType> |
| 3222 void AssemblerX86Base<Machine>::j(typename Traits::Cond::BrCond condition, | 3099 void AssemblerX86Base<TraitsType>::j(BrCond condition, |
| 3223 const ConstantRelocatable *label) { | 3100 const ConstantRelocatable *label) { |
| 3224 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3101 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3225 emitUint8(0x0F); | 3102 emitUint8(0x0F); |
| 3226 emitUint8(0x80 + condition); | 3103 emitUint8(0x80 + condition); |
| 3227 emitFixup(this->createFixup(Traits::PcRelFixup, label)); | 3104 emitFixup(this->createFixup(Traits::PcRelFixup, label)); |
| 3228 emitInt32(-4); | 3105 emitInt32(-4); |
| 3229 } | 3106 } |
| 3230 | 3107 |
| 3231 template <class Machine> | 3108 template <typename TraitsType> |
| 3232 void AssemblerX86Base<Machine>::jmp(typename Traits::GPRRegister reg) { | 3109 void AssemblerX86Base<TraitsType>::jmp(GPRRegister reg) { |
| 3233 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3110 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3234 emitRexB(RexTypeIrrelevant, reg); | 3111 emitRexB(RexTypeIrrelevant, reg); |
| 3235 emitUint8(0xFF); | 3112 emitUint8(0xFF); |
| 3236 emitRegisterOperand(4, gprEncoding(reg)); | 3113 emitRegisterOperand(4, gprEncoding(reg)); |
| 3237 } | 3114 } |
| 3238 | 3115 |
| 3239 template <class Machine> | 3116 template <typename TraitsType> |
| 3240 void AssemblerX86Base<Machine>::jmp(Label *label, bool near) { | 3117 void AssemblerX86Base<TraitsType>::jmp(Label *label, bool near) { |
| 3241 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3118 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3242 if (label->isBound()) { | 3119 if (label->isBound()) { |
| 3243 static const int kShortSize = 2; | 3120 static const int kShortSize = 2; |
| 3244 static const int kLongSize = 5; | 3121 static const int kLongSize = 5; |
| 3245 intptr_t offset = label->getPosition() - Buffer.size(); | 3122 intptr_t offset = label->getPosition() - Buffer.size(); |
| 3246 assert(offset <= 0); | 3123 assert(offset <= 0); |
| 3247 if (Utils::IsInt(8, offset - kShortSize)) { | 3124 if (Utils::IsInt(8, offset - kShortSize)) { |
| 3248 emitUint8(0xEB); | 3125 emitUint8(0xEB); |
| 3249 emitUint8((offset - kShortSize) & 0xFF); | 3126 emitUint8((offset - kShortSize) & 0xFF); |
| 3250 } else { | 3127 } else { |
| 3251 emitUint8(0xE9); | 3128 emitUint8(0xE9); |
| 3252 emitInt32(offset - kLongSize); | 3129 emitInt32(offset - kLongSize); |
| 3253 } | 3130 } |
| 3254 } else if (near) { | 3131 } else if (near) { |
| 3255 emitUint8(0xEB); | 3132 emitUint8(0xEB); |
| 3256 emitNearLabelLink(label); | 3133 emitNearLabelLink(label); |
| 3257 } else { | 3134 } else { |
| 3258 emitUint8(0xE9); | 3135 emitUint8(0xE9); |
| 3259 emitLabelLink(label); | 3136 emitLabelLink(label); |
| 3260 } | 3137 } |
| 3261 } | 3138 } |
| 3262 | 3139 |
| 3263 template <class Machine> | 3140 template <typename TraitsType> |
| 3264 void AssemblerX86Base<Machine>::jmp(const ConstantRelocatable *label) { | 3141 void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) { |
| 3265 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3142 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3266 emitUint8(0xE9); | 3143 emitUint8(0xE9); |
| 3267 emitFixup(this->createFixup(Traits::PcRelFixup, label)); | 3144 emitFixup(this->createFixup(Traits::PcRelFixup, label)); |
| 3268 emitInt32(-4); | 3145 emitInt32(-4); |
| 3269 } | 3146 } |
| 3270 | 3147 |
| 3271 template <class Machine> void AssemblerX86Base<Machine>::mfence() { | 3148 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() { |
| 3272 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3149 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3273 emitUint8(0x0F); | 3150 emitUint8(0x0F); |
| 3274 emitUint8(0xAE); | 3151 emitUint8(0xAE); |
| 3275 emitUint8(0xF0); | 3152 emitUint8(0xF0); |
| 3276 } | 3153 } |
| 3277 | 3154 |
| 3278 template <class Machine> void AssemblerX86Base<Machine>::lock() { | 3155 template <typename TraitsType> void AssemblerX86Base<TraitsType>::lock() { |
| 3279 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3156 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3280 emitUint8(0xF0); | 3157 emitUint8(0xF0); |
| 3281 } | 3158 } |
| 3282 | 3159 |
| 3283 template <class Machine> | 3160 template <typename TraitsType> |
| 3284 void AssemblerX86Base<Machine>::cmpxchg(Type Ty, | 3161 void AssemblerX86Base<TraitsType>::cmpxchg(Type Ty, const Address &address, |
| 3285 const typename Traits::Address &address, | 3162 GPRRegister reg, bool Locked) { |
| 3286 typename Traits::GPRRegister reg, | |
| 3287 bool Locked) { | |
| 3288 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3163 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3289 if (Ty == IceType_i16) | 3164 if (Ty == IceType_i16) |
| 3290 emitOperandSizeOverride(); | 3165 emitOperandSizeOverride(); |
| 3291 if (Locked) | 3166 if (Locked) |
| 3292 emitUint8(0xF0); | 3167 emitUint8(0xF0); |
| 3293 emitAddrSizeOverridePrefix(); | 3168 emitAddrSizeOverridePrefix(); |
| 3294 emitRex(Ty, address, reg); | 3169 emitRex(Ty, address, reg); |
| 3295 emitUint8(0x0F); | 3170 emitUint8(0x0F); |
| 3296 if (isByteSizedArithType(Ty)) | 3171 if (isByteSizedArithType(Ty)) |
| 3297 emitUint8(0xB0); | 3172 emitUint8(0xB0); |
| 3298 else | 3173 else |
| 3299 emitUint8(0xB1); | 3174 emitUint8(0xB1); |
| 3300 emitOperand(gprEncoding(reg), address); | 3175 emitOperand(gprEncoding(reg), address); |
| 3301 } | 3176 } |
| 3302 | 3177 |
| 3303 template <class Machine> | 3178 template <typename TraitsType> |
| 3304 void AssemblerX86Base<Machine>::cmpxchg8b( | 3179 void AssemblerX86Base<TraitsType>::cmpxchg8b(const Address &address, |
| 3305 const typename Traits::Address &address, bool Locked) { | 3180 bool Locked) { |
| 3306 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3181 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3307 if (Locked) | 3182 if (Locked) |
| 3308 emitUint8(0xF0); | 3183 emitUint8(0xF0); |
| 3309 emitAddrSizeOverridePrefix(); | 3184 emitAddrSizeOverridePrefix(); |
| 3310 emitRex(IceType_i32, address, RexRegIrrelevant); | 3185 emitRex(IceType_i32, address, RexRegIrrelevant); |
| 3311 emitUint8(0x0F); | 3186 emitUint8(0x0F); |
| 3312 emitUint8(0xC7); | 3187 emitUint8(0xC7); |
| 3313 emitOperand(1, address); | 3188 emitOperand(1, address); |
| 3314 } | 3189 } |
| 3315 | 3190 |
| 3316 template <class Machine> | 3191 template <typename TraitsType> |
| 3317 void AssemblerX86Base<Machine>::xadd(Type Ty, | 3192 void AssemblerX86Base<TraitsType>::xadd(Type Ty, const Address &addr, |
| 3318 const typename Traits::Address &addr, | 3193 GPRRegister reg, bool Locked) { |
| 3319 typename Traits::GPRRegister reg, | |
| 3320 bool Locked) { | |
| 3321 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3194 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3322 if (Ty == IceType_i16) | 3195 if (Ty == IceType_i16) |
| 3323 emitOperandSizeOverride(); | 3196 emitOperandSizeOverride(); |
| 3324 if (Locked) | 3197 if (Locked) |
| 3325 emitUint8(0xF0); | 3198 emitUint8(0xF0); |
| 3326 emitAddrSizeOverridePrefix(); | 3199 emitAddrSizeOverridePrefix(); |
| 3327 emitRex(Ty, addr, reg); | 3200 emitRex(Ty, addr, reg); |
| 3328 emitUint8(0x0F); | 3201 emitUint8(0x0F); |
| 3329 if (isByteSizedArithType(Ty)) | 3202 if (isByteSizedArithType(Ty)) |
| 3330 emitUint8(0xC0); | 3203 emitUint8(0xC0); |
| 3331 else | 3204 else |
| 3332 emitUint8(0xC1); | 3205 emitUint8(0xC1); |
| 3333 emitOperand(gprEncoding(reg), addr); | 3206 emitOperand(gprEncoding(reg), addr); |
| 3334 } | 3207 } |
| 3335 | 3208 |
| 3336 template <class Machine> | 3209 template <typename TraitsType> |
| 3337 void AssemblerX86Base<Machine>::xchg(Type Ty, typename Traits::GPRRegister reg0, | 3210 void AssemblerX86Base<TraitsType>::xchg(Type Ty, GPRRegister reg0, |
| 3338 typename Traits::GPRRegister reg1) { | 3211 GPRRegister reg1) { |
| 3339 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3212 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3340 if (Ty == IceType_i16) | 3213 if (Ty == IceType_i16) |
| 3341 emitOperandSizeOverride(); | 3214 emitOperandSizeOverride(); |
| 3342 // Use short form if either register is EAX. | 3215 // Use short form if either register is EAX. |
| 3343 if (reg0 == Traits::Encoded_Reg_Accumulator) { | 3216 if (reg0 == Traits::Encoded_Reg_Accumulator) { |
| 3344 emitRexB(Ty, reg1); | 3217 emitRexB(Ty, reg1); |
| 3345 emitUint8(0x90 + gprEncoding(reg1)); | 3218 emitUint8(0x90 + gprEncoding(reg1)); |
| 3346 } else if (reg1 == Traits::Encoded_Reg_Accumulator) { | 3219 } else if (reg1 == Traits::Encoded_Reg_Accumulator) { |
| 3347 emitRexB(Ty, reg0); | 3220 emitRexB(Ty, reg0); |
| 3348 emitUint8(0x90 + gprEncoding(reg0)); | 3221 emitUint8(0x90 + gprEncoding(reg0)); |
| 3349 } else { | 3222 } else { |
| 3350 emitRexRB(Ty, reg0, reg1); | 3223 emitRexRB(Ty, reg0, reg1); |
| 3351 if (isByteSizedArithType(Ty)) | 3224 if (isByteSizedArithType(Ty)) |
| 3352 emitUint8(0x86); | 3225 emitUint8(0x86); |
| 3353 else | 3226 else |
| 3354 emitUint8(0x87); | 3227 emitUint8(0x87); |
| 3355 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1)); | 3228 emitRegisterOperand(gprEncoding(reg0), gprEncoding(reg1)); |
| 3356 } | 3229 } |
| 3357 } | 3230 } |
| 3358 | 3231 |
| 3359 template <class Machine> | 3232 template <typename TraitsType> |
| 3360 void AssemblerX86Base<Machine>::xchg(Type Ty, | 3233 void AssemblerX86Base<TraitsType>::xchg(Type Ty, const Address &addr, |
| 3361 const typename Traits::Address &addr, | 3234 GPRRegister reg) { |
| 3362 typename Traits::GPRRegister reg) { | |
| 3363 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3235 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3364 if (Ty == IceType_i16) | 3236 if (Ty == IceType_i16) |
| 3365 emitOperandSizeOverride(); | 3237 emitOperandSizeOverride(); |
| 3366 emitAddrSizeOverridePrefix(); | 3238 emitAddrSizeOverridePrefix(); |
| 3367 emitRex(Ty, addr, reg); | 3239 emitRex(Ty, addr, reg); |
| 3368 if (isByteSizedArithType(Ty)) | 3240 if (isByteSizedArithType(Ty)) |
| 3369 emitUint8(0x86); | 3241 emitUint8(0x86); |
| 3370 else | 3242 else |
| 3371 emitUint8(0x87); | 3243 emitUint8(0x87); |
| 3372 emitOperand(gprEncoding(reg), addr); | 3244 emitOperand(gprEncoding(reg), addr); |
| 3373 } | 3245 } |
| 3374 | 3246 |
| 3375 template <class Machine> void AssemblerX86Base<Machine>::iaca_start() { | 3247 template <typename TraitsType> void AssemblerX86Base<TraitsType>::iaca_start() { |
| 3376 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3248 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3377 emitUint8(0x0F); | 3249 emitUint8(0x0F); |
| 3378 emitUint8(0x0B); | 3250 emitUint8(0x0B); |
| 3379 | 3251 |
| 3380 // mov $111, ebx | 3252 // mov $111, ebx |
| 3381 constexpr typename Traits::GPRRegister dst = | 3253 constexpr GPRRegister dst = Traits::GPRRegister::Encoded_Reg_ebx; |
| 3382 Traits::GPRRegister::Encoded_Reg_ebx; | |
| 3383 constexpr Type Ty = IceType_i32; | 3254 constexpr Type Ty = IceType_i32; |
| 3384 emitRexB(Ty, dst); | 3255 emitRexB(Ty, dst); |
| 3385 emitUint8(0xB8 + gprEncoding(dst)); | 3256 emitUint8(0xB8 + gprEncoding(dst)); |
| 3386 emitImmediate(Ty, Immediate(111)); | 3257 emitImmediate(Ty, Immediate(111)); |
| 3387 | 3258 |
| 3388 emitUint8(0x64); | 3259 emitUint8(0x64); |
| 3389 emitUint8(0x67); | 3260 emitUint8(0x67); |
| 3390 emitUint8(0x90); | 3261 emitUint8(0x90); |
| 3391 } | 3262 } |
| 3392 | 3263 |
| 3393 template <class Machine> void AssemblerX86Base<Machine>::iaca_end() { | 3264 template <typename TraitsType> void AssemblerX86Base<TraitsType>::iaca_end() { |
| 3394 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3265 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3395 | 3266 |
| 3396 // mov $222, ebx | 3267 // mov $222, ebx |
| 3397 constexpr typename Traits::GPRRegister dst = | 3268 constexpr GPRRegister dst = Traits::GPRRegister::Encoded_Reg_ebx; |
| 3398 Traits::GPRRegister::Encoded_Reg_ebx; | |
| 3399 constexpr Type Ty = IceType_i32; | 3269 constexpr Type Ty = IceType_i32; |
| 3400 emitRexB(Ty, dst); | 3270 emitRexB(Ty, dst); |
| 3401 emitUint8(0xB8 + gprEncoding(dst)); | 3271 emitUint8(0xB8 + gprEncoding(dst)); |
| 3402 emitImmediate(Ty, Immediate(222)); | 3272 emitImmediate(Ty, Immediate(222)); |
| 3403 | 3273 |
| 3404 emitUint8(0x64); | 3274 emitUint8(0x64); |
| 3405 emitUint8(0x67); | 3275 emitUint8(0x67); |
| 3406 emitUint8(0x90); | 3276 emitUint8(0x90); |
| 3407 | 3277 |
| 3408 emitUint8(0x0F); | 3278 emitUint8(0x0F); |
| 3409 emitUint8(0x0B); | 3279 emitUint8(0x0B); |
| 3410 } | 3280 } |
| 3411 | 3281 |
| 3412 template <class Machine> | 3282 template <typename TraitsType> |
| 3413 void AssemblerX86Base<Machine>::emitSegmentOverride(uint8_t prefix) { | 3283 void AssemblerX86Base<TraitsType>::emitSegmentOverride(uint8_t prefix) { |
| 3414 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3284 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3415 emitUint8(prefix); | 3285 emitUint8(prefix); |
| 3416 } | 3286 } |
| 3417 | 3287 |
| 3418 template <class Machine> | 3288 template <typename TraitsType> |
| 3419 void AssemblerX86Base<Machine>::align(intptr_t alignment, intptr_t offset) { | 3289 void AssemblerX86Base<TraitsType>::align(intptr_t alignment, intptr_t offset) { |
| 3420 assert(llvm::isPowerOf2_32(alignment)); | 3290 assert(llvm::isPowerOf2_32(alignment)); |
| 3421 intptr_t pos = offset + Buffer.getPosition(); | 3291 intptr_t pos = offset + Buffer.getPosition(); |
| 3422 intptr_t mod = pos & (alignment - 1); | 3292 intptr_t mod = pos & (alignment - 1); |
| 3423 if (mod == 0) { | 3293 if (mod == 0) { |
| 3424 return; | 3294 return; |
| 3425 } | 3295 } |
| 3426 intptr_t bytes_needed = alignment - mod; | 3296 intptr_t bytes_needed = alignment - mod; |
| 3427 while (bytes_needed > MAX_NOP_SIZE) { | 3297 while (bytes_needed > MAX_NOP_SIZE) { |
| 3428 nop(MAX_NOP_SIZE); | 3298 nop(MAX_NOP_SIZE); |
| 3429 bytes_needed -= MAX_NOP_SIZE; | 3299 bytes_needed -= MAX_NOP_SIZE; |
| 3430 } | 3300 } |
| 3431 if (bytes_needed) { | 3301 if (bytes_needed) { |
| 3432 nop(bytes_needed); | 3302 nop(bytes_needed); |
| 3433 } | 3303 } |
| 3434 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); | 3304 assert(((offset + Buffer.getPosition()) & (alignment - 1)) == 0); |
| 3435 } | 3305 } |
| 3436 | 3306 |
| 3437 template <class Machine> void AssemblerX86Base<Machine>::bind(Label *label) { | 3307 template <typename TraitsType> |
| 3308 void AssemblerX86Base<TraitsType>::bind(Label *label) { |
| 3438 intptr_t bound = Buffer.size(); | 3309 intptr_t bound = Buffer.size(); |
| 3439 assert(!label->isBound()); // Labels can only be bound once. | 3310 assert(!label->isBound()); // Labels can only be bound once. |
| 3440 while (label->isLinked()) { | 3311 while (label->isLinked()) { |
| 3441 intptr_t position = label->getLinkPosition(); | 3312 intptr_t position = label->getLinkPosition(); |
| 3442 intptr_t next = Buffer.load<int32_t>(position); | 3313 intptr_t next = Buffer.load<int32_t>(position); |
| 3443 Buffer.store<int32_t>(position, bound - (position + 4)); | 3314 Buffer.store<int32_t>(position, bound - (position + 4)); |
| 3444 label->Position = next; | 3315 label->Position = next; |
| 3445 } | 3316 } |
| 3446 while (label->hasNear()) { | 3317 while (label->hasNear()) { |
| 3447 intptr_t position = label->getNearPosition(); | 3318 intptr_t position = label->getNearPosition(); |
| 3448 intptr_t offset = bound - (position + 1); | 3319 intptr_t offset = bound - (position + 1); |
| 3449 assert(Utils::IsInt(8, offset)); | 3320 assert(Utils::IsInt(8, offset)); |
| 3450 Buffer.store<int8_t>(position, offset); | 3321 Buffer.store<int8_t>(position, offset); |
| 3451 } | 3322 } |
| 3452 label->bindTo(bound); | 3323 label->bindTo(bound); |
| 3453 } | 3324 } |
| 3454 | 3325 |
| 3455 template <class Machine> | 3326 template <typename TraitsType> |
| 3456 void AssemblerX86Base<Machine>::emitOperand( | 3327 void AssemblerX86Base<TraitsType>::emitOperand(int rm, const Operand &operand) { |
| 3457 int rm, const typename Traits::Operand &operand) { | |
| 3458 assert(rm >= 0 && rm < 8); | 3328 assert(rm >= 0 && rm < 8); |
| 3459 const intptr_t length = operand.length_; | 3329 const intptr_t length = operand.length_; |
| 3460 assert(length > 0); | 3330 assert(length > 0); |
| 3461 intptr_t displacement_start = 1; | 3331 intptr_t displacement_start = 1; |
| 3462 // Emit the ModRM byte updated with the given RM value. | 3332 // Emit the ModRM byte updated with the given RM value. |
| 3463 assert((operand.encoding_[0] & 0x38) == 0); | 3333 assert((operand.encoding_[0] & 0x38) == 0); |
| 3464 emitUint8(operand.encoding_[0] + (rm << 3)); | 3334 emitUint8(operand.encoding_[0] + (rm << 3)); |
| 3465 // Whenever the addressing mode is not register indirect, using esp == 0x4 | 3335 // Whenever the addressing mode is not register indirect, using esp == 0x4 |
| 3466 // as the register operation indicates an SIB byte follows. | 3336 // as the register operation indicates an SIB byte follows. |
| 3467 if (((operand.encoding_[0] & 0xc0) != 0xc0) && | 3337 if (((operand.encoding_[0] & 0xc0) != 0xc0) && |
| 3468 ((operand.encoding_[0] & 0x07) == 0x04)) { | 3338 ((operand.encoding_[0] & 0x07) == 0x04)) { |
| 3469 emitUint8(operand.encoding_[1]); | 3339 emitUint8(operand.encoding_[1]); |
| 3470 displacement_start = 2; | 3340 displacement_start = 2; |
| 3471 } | 3341 } |
| 3472 // Emit the displacement and the fixup that affects it, if any. | 3342 // Emit the displacement and the fixup that affects it, if any. |
| 3473 if (operand.fixup()) { | 3343 if (operand.fixup()) { |
| 3474 emitFixup(operand.fixup()); | 3344 emitFixup(operand.fixup()); |
| 3475 assert(length - displacement_start == 4); | 3345 assert(length - displacement_start == 4); |
| 3476 } | 3346 } |
| 3477 for (intptr_t i = displacement_start; i < length; i++) { | 3347 for (intptr_t i = displacement_start; i < length; i++) { |
| 3478 emitUint8(operand.encoding_[i]); | 3348 emitUint8(operand.encoding_[i]); |
| 3479 } | 3349 } |
| 3480 } | 3350 } |
| 3481 | 3351 |
| 3482 template <class Machine> | 3352 template <typename TraitsType> |
| 3483 void AssemblerX86Base<Machine>::emitImmediate(Type Ty, const Immediate &imm) { | 3353 void AssemblerX86Base<TraitsType>::emitImmediate(Type Ty, |
| 3354 const Immediate &imm) { |
| 3484 if (Ty == IceType_i16) { | 3355 if (Ty == IceType_i16) { |
| 3485 assert(!imm.fixup()); | 3356 assert(!imm.fixup()); |
| 3486 emitInt16(imm.value()); | 3357 emitInt16(imm.value()); |
| 3487 } else { | 3358 } else { |
| 3488 if (imm.fixup()) { | 3359 if (imm.fixup()) { |
| 3489 emitFixup(imm.fixup()); | 3360 emitFixup(imm.fixup()); |
| 3490 } | 3361 } |
| 3491 emitInt32(imm.value()); | 3362 emitInt32(imm.value()); |
| 3492 } | 3363 } |
| 3493 } | 3364 } |
| 3494 | 3365 |
| 3495 template <class Machine> | 3366 template <typename TraitsType> |
| 3496 void AssemblerX86Base<Machine>::emitComplexI8( | 3367 void AssemblerX86Base<TraitsType>::emitComplexI8(int rm, const Operand &operand, |
| 3497 int rm, const typename Traits::Operand &operand, | 3368 const Immediate &immediate) { |
| 3498 const Immediate &immediate) { | |
| 3499 assert(rm >= 0 && rm < 8); | 3369 assert(rm >= 0 && rm < 8); |
| 3500 assert(immediate.is_int8()); | 3370 assert(immediate.is_int8()); |
| 3501 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { | 3371 if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { |
| 3502 // Use short form if the destination is al. | 3372 // Use short form if the destination is al. |
| 3503 emitUint8(0x04 + (rm << 3)); | 3373 emitUint8(0x04 + (rm << 3)); |
| 3504 emitUint8(immediate.value() & 0xFF); | 3374 emitUint8(immediate.value() & 0xFF); |
| 3505 } else { | 3375 } else { |
| 3506 // Use sign-extended 8-bit immediate. | 3376 // Use sign-extended 8-bit immediate. |
| 3507 emitUint8(0x80); | 3377 emitUint8(0x80); |
| 3508 emitOperand(rm, operand); | 3378 emitOperand(rm, operand); |
| 3509 emitUint8(immediate.value() & 0xFF); | 3379 emitUint8(immediate.value() & 0xFF); |
| 3510 } | 3380 } |
| 3511 } | 3381 } |
| 3512 | 3382 |
| 3513 template <class Machine> | 3383 template <typename TraitsType> |
| 3514 void AssemblerX86Base<Machine>::emitComplex( | 3384 void AssemblerX86Base<TraitsType>::emitComplex(Type Ty, int rm, |
| 3515 Type Ty, int rm, const typename Traits::Operand &operand, | 3385 const Operand &operand, |
| 3516 const Immediate &immediate) { | 3386 const Immediate &immediate) { |
| 3517 assert(rm >= 0 && rm < 8); | 3387 assert(rm >= 0 && rm < 8); |
| 3518 if (immediate.is_int8()) { | 3388 if (immediate.is_int8()) { |
| 3519 // Use sign-extended 8-bit immediate. | 3389 // Use sign-extended 8-bit immediate. |
| 3520 emitUint8(0x83); | 3390 emitUint8(0x83); |
| 3521 emitOperand(rm, operand); | 3391 emitOperand(rm, operand); |
| 3522 emitUint8(immediate.value() & 0xFF); | 3392 emitUint8(immediate.value() & 0xFF); |
| 3523 } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { | 3393 } else if (operand.IsRegister(Traits::Encoded_Reg_Accumulator)) { |
| 3524 // Use short form if the destination is eax. | 3394 // Use short form if the destination is eax. |
| 3525 emitUint8(0x05 + (rm << 3)); | 3395 emitUint8(0x05 + (rm << 3)); |
| 3526 emitImmediate(Ty, immediate); | 3396 emitImmediate(Ty, immediate); |
| 3527 } else { | 3397 } else { |
| 3528 emitUint8(0x81); | 3398 emitUint8(0x81); |
| 3529 emitOperand(rm, operand); | 3399 emitOperand(rm, operand); |
| 3530 emitImmediate(Ty, immediate); | 3400 emitImmediate(Ty, immediate); |
| 3531 } | 3401 } |
| 3532 } | 3402 } |
| 3533 | 3403 |
| 3534 template <class Machine> | 3404 template <typename TraitsType> |
| 3535 void AssemblerX86Base<Machine>::emitLabel(Label *label, | 3405 void AssemblerX86Base<TraitsType>::emitLabel(Label *label, |
| 3536 intptr_t instruction_size) { | 3406 intptr_t instruction_size) { |
| 3537 if (label->isBound()) { | 3407 if (label->isBound()) { |
| 3538 intptr_t offset = label->getPosition() - Buffer.size(); | 3408 intptr_t offset = label->getPosition() - Buffer.size(); |
| 3539 assert(offset <= 0); | 3409 assert(offset <= 0); |
| 3540 emitInt32(offset - instruction_size); | 3410 emitInt32(offset - instruction_size); |
| 3541 } else { | 3411 } else { |
| 3542 emitLabelLink(label); | 3412 emitLabelLink(label); |
| 3543 } | 3413 } |
| 3544 } | 3414 } |
| 3545 | 3415 |
| 3546 template <class Machine> | 3416 template <typename TraitsType> |
| 3547 void AssemblerX86Base<Machine>::emitLabelLink(Label *Label) { | 3417 void AssemblerX86Base<TraitsType>::emitLabelLink(Label *Label) { |
| 3548 assert(!Label->isBound()); | 3418 assert(!Label->isBound()); |
| 3549 intptr_t Position = Buffer.size(); | 3419 intptr_t Position = Buffer.size(); |
| 3550 emitInt32(Label->Position); | 3420 emitInt32(Label->Position); |
| 3551 Label->linkTo(*this, Position); | 3421 Label->linkTo(*this, Position); |
| 3552 } | 3422 } |
| 3553 | 3423 |
| 3554 template <class Machine> | 3424 template <typename TraitsType> |
| 3555 void AssemblerX86Base<Machine>::emitNearLabelLink(Label *Label) { | 3425 void AssemblerX86Base<TraitsType>::emitNearLabelLink(Label *Label) { |
| 3556 assert(!Label->isBound()); | 3426 assert(!Label->isBound()); |
| 3557 intptr_t Position = Buffer.size(); | 3427 intptr_t Position = Buffer.size(); |
| 3558 emitUint8(0); | 3428 emitUint8(0); |
| 3559 Label->nearLinkTo(*this, Position); | 3429 Label->nearLinkTo(*this, Position); |
| 3560 } | 3430 } |
| 3561 | 3431 |
| 3562 template <class Machine> | 3432 template <typename TraitsType> |
| 3563 void AssemblerX86Base<Machine>::emitGenericShift( | 3433 void AssemblerX86Base<TraitsType>::emitGenericShift(int rm, Type Ty, |
| 3564 int rm, Type Ty, typename Traits::GPRRegister reg, const Immediate &imm) { | 3434 GPRRegister reg, |
| 3435 const Immediate &imm) { |
| 3565 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3436 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3566 // We don't assert that imm fits into 8 bits; instead, it gets masked below. | 3437 // We don't assert that imm fits into 8 bits; instead, it gets masked below. |
| 3567 // Note that we don't mask it further (e.g. to 5 bits) because we want the | 3438 // Note that we don't mask it further (e.g. to 5 bits) because we want the |
| 3568 // same processor behavior regardless of whether it's an immediate (masked to | 3439 // same processor behavior regardless of whether it's an immediate (masked to |
| 3569 // 8 bits) or in register cl (essentially ecx masked to 8 bits). | 3440 // 8 bits) or in register cl (essentially ecx masked to 8 bits). |
| 3570 if (Ty == IceType_i16) | 3441 if (Ty == IceType_i16) |
| 3571 emitOperandSizeOverride(); | 3442 emitOperandSizeOverride(); |
| 3572 emitRexB(Ty, reg); | 3443 emitRexB(Ty, reg); |
| 3573 if (imm.value() == 1) { | 3444 if (imm.value() == 1) { |
| 3574 emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); | 3445 emitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); |
| 3575 emitOperand(rm, typename Traits::Operand(reg)); | 3446 emitOperand(rm, Operand(reg)); |
| 3576 } else { | 3447 } else { |
| 3577 emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1); | 3448 emitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1); |
| 3578 emitOperand(rm, typename Traits::Operand(reg)); | 3449 emitOperand(rm, Operand(reg)); |
| 3579 emitUint8(imm.value() & 0xFF); | 3450 emitUint8(imm.value() & 0xFF); |
| 3580 } | 3451 } |
| 3581 } | 3452 } |
| 3582 | 3453 |
| 3583 template <class Machine> | 3454 template <typename TraitsType> |
| 3584 void AssemblerX86Base<Machine>::emitGenericShift( | 3455 void AssemblerX86Base<TraitsType>::emitGenericShift(int rm, Type Ty, |
| 3585 int rm, Type Ty, const typename Traits::Operand &operand, | 3456 const Operand &operand, |
| 3586 typename Traits::GPRRegister shifter) { | 3457 GPRRegister shifter) { |
| 3587 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 3458 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 3588 assert(shifter == Traits::Encoded_Reg_Counter); | 3459 assert(shifter == Traits::Encoded_Reg_Counter); |
| 3589 (void)shifter; | 3460 (void)shifter; |
| 3590 if (Ty == IceType_i16) | 3461 if (Ty == IceType_i16) |
| 3591 emitOperandSizeOverride(); | 3462 emitOperandSizeOverride(); |
| 3592 emitRexB(Ty, operand.rm()); | 3463 emitRexB(Ty, operand.rm()); |
| 3593 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); | 3464 emitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
| 3594 emitOperand(rm, operand); | 3465 emitOperand(rm, operand); |
| 3595 } | 3466 } |
| 3596 | 3467 |
| 3597 } // end of namespace X86Internal | 3468 } // end of namespace X86NAMESPACE |
| 3598 } // end of namespace Ice | 3469 } // end of namespace Ice |
| OLD | NEW |