Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===// | 1 //===- subzero/src/IceAssemblerX86Base.h - base x86 assembler -*- C++ -*---===// |
| 2 // | 2 // |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 // | 6 // |
| 7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not. | 188 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not. |
| 189 // In practice, we always normalize the Dest to a Register first. | 189 // In practice, we always normalize the Dest to a Register first. |
| 190 TypedEmitGPRGPR GPRGPR; | 190 TypedEmitGPRGPR GPRGPR; |
| 191 TypedEmitGPRImm GPRImm; | 191 TypedEmitGPRImm GPRImm; |
| 192 }; | 192 }; |
| 193 | 193 |
| 194 using TypedEmitGPRGPRImm = void (AssemblerX86Base::*)( | 194 using TypedEmitGPRGPRImm = void (AssemblerX86Base::*)( |
| 195 Type, typename Traits::GPRRegister, typename Traits::GPRRegister, | 195 Type, typename Traits::GPRRegister, typename Traits::GPRRegister, |
| 196 const Immediate &); | 196 const Immediate &); |
| 197 struct GPREmitterShiftD { | 197 struct GPREmitterShiftD { |
| 198 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice | 198 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice we |
| 199 // we always normalize Dest to a Register first. | 199 // always normalize Dest to a Register first. |
| 200 TypedEmitGPRGPR GPRGPR; | 200 TypedEmitGPRGPR GPRGPR; |
| 201 TypedEmitGPRGPRImm GPRGPRImm; | 201 TypedEmitGPRGPRImm GPRGPRImm; |
| 202 }; | 202 }; |
| 203 | 203 |
| 204 using TypedEmitAddrGPR = void (AssemblerX86Base::*)( | 204 using TypedEmitAddrGPR = void (AssemblerX86Base::*)( |
| 205 Type, const typename Traits::Address &, typename Traits::GPRRegister); | 205 Type, const typename Traits::Address &, typename Traits::GPRRegister); |
| 206 using TypedEmitAddrImm = void (AssemblerX86Base::*)( | 206 using TypedEmitAddrImm = void (AssemblerX86Base::*)( |
| 207 Type, const typename Traits::Address &, const Immediate &); | 207 Type, const typename Traits::Address &, const Immediate &); |
| 208 struct GPREmitterAddrOp { | 208 struct GPREmitterAddrOp { |
| 209 TypedEmitAddrGPR AddrGPR; | 209 TypedEmitAddrGPR AddrGPR; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp { | 245 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp { |
| 246 using TypedEmitRegs = void (AssemblerX86Base::*)(Type, DReg_t, Type, | 246 using TypedEmitRegs = void (AssemblerX86Base::*)(Type, DReg_t, Type, |
| 247 SReg_t); | 247 SReg_t); |
| 248 using TypedEmitAddr = void (AssemblerX86Base::*)( | 248 using TypedEmitAddr = void (AssemblerX86Base::*)( |
| 249 Type, DReg_t, Type, const typename Traits::Address &); | 249 Type, DReg_t, Type, const typename Traits::Address &); |
| 250 | 250 |
| 251 TypedEmitRegs RegReg; | 251 TypedEmitRegs RegReg; |
| 252 TypedEmitAddr RegAddr; | 252 TypedEmitAddr RegAddr; |
| 253 }; | 253 }; |
| 254 | 254 |
| 255 // Three operand (potentially) cross Xmm/GPR instructions. | 255 // Three operand (potentially) cross Xmm/GPR instructions. The last operand |
| 256 // The last operand must be an immediate. | 256 // must be an immediate. |
| 257 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter { | 257 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter { |
| 258 using TypedEmitRegRegImm = void (AssemblerX86Base::*)(Type, DReg_t, SReg_t, | 258 using TypedEmitRegRegImm = void (AssemblerX86Base::*)(Type, DReg_t, SReg_t, |
| 259 const Immediate &); | 259 const Immediate &); |
| 260 using TypedEmitRegAddrImm = void (AssemblerX86Base::*)( | 260 using TypedEmitRegAddrImm = void (AssemblerX86Base::*)( |
| 261 Type, DReg_t, const typename Traits::Address &, const Immediate &); | 261 Type, DReg_t, const typename Traits::Address &, const Immediate &); |
| 262 | 262 |
| 263 TypedEmitRegRegImm RegRegImm; | 263 TypedEmitRegRegImm RegRegImm; |
| 264 TypedEmitRegAddrImm RegAddrImm; | 264 TypedEmitRegAddrImm RegAddrImm; |
| 265 }; | 265 }; |
| 266 | 266 |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 899 typename Traits::GPRRegister shifter); | 899 typename Traits::GPRRegister shifter); |
| 900 | 900 |
| 901 using LabelVector = std::vector<Label *>; | 901 using LabelVector = std::vector<Label *>; |
| 902 // A vector of pool-allocated x86 labels for CFG nodes. | 902 // A vector of pool-allocated x86 labels for CFG nodes. |
| 903 LabelVector CfgNodeLabels; | 903 LabelVector CfgNodeLabels; |
| 904 // A vector of pool-allocated x86 labels for Local labels. | 904 // A vector of pool-allocated x86 labels for Local labels. |
| 905 LabelVector LocalLabels; | 905 LabelVector LocalLabels; |
| 906 | 906 |
| 907 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); | 907 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); |
| 908 | 908 |
| 909 // The arith_int() methods factor out the commonality between the encodings of | 909 // The arith_int() methods factor out the commonality between the encodings |
| 910 // add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag | 910 // of add(), Or(), adc(), sbb(), And(), sub(), Xor(), and cmp(). The Tag |
| 911 // parameter is statically asserted to be less than 8. | 911 // parameter is statically asserted to be less than 8. |
| 912 template <uint32_t Tag> | 912 template <uint32_t Tag> |
| 913 void arith_int(Type Ty, typename Traits::GPRRegister reg, | 913 void arith_int(Type Ty, typename Traits::GPRRegister reg, |
| 914 const Immediate &imm); | 914 const Immediate &imm); |
| 915 | 915 |
| 916 template <uint32_t Tag> | 916 template <uint32_t Tag> |
| 917 void arith_int(Type Ty, typename Traits::GPRRegister reg0, | 917 void arith_int(Type Ty, typename Traits::GPRRegister reg0, |
| 918 typename Traits::GPRRegister reg1); | 918 typename Traits::GPRRegister reg1); |
| 919 | 919 |
| 920 template <uint32_t Tag> | 920 template <uint32_t Tag> |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 950 static constexpr bool IsGPR = | 950 static constexpr bool IsGPR = |
| 951 std::is_same<typename std::decay<RegType>::type, | 951 std::is_same<typename std::decay<RegType>::type, |
| 952 typename Traits::ByteRegister>::value || | 952 typename Traits::ByteRegister>::value || |
| 953 std::is_same<typename std::decay<RegType>::type, | 953 std::is_same<typename std::decay<RegType>::type, |
| 954 typename Traits::GPRRegister>::value; | 954 typename Traits::GPRRegister>::value; |
| 955 | 955 |
| 956 return IsGPR && (Reg & 0x04) != 0 && (Reg & 0x08) == 0 && | 956 return IsGPR && (Reg & 0x04) != 0 && (Reg & 0x08) == 0 && |
| 957 isByteSizedType(Ty); | 957 isByteSizedType(Ty); |
| 958 } | 958 } |
| 959 | 959 |
| 960 // assembleAndEmitRex is used for determining which (if any) rex prefix should | 960 // assembleAndEmitRex is used for determining which (if any) rex prefix |
| 961 // be emitted for the current instruction. It allows different types for Reg | 961 // should be emitted for the current instruction. It allows different types |
| 962 // and Rm because they could be of different types (e.g., in mov[sz]x | 962 // for Reg and Rm because they could be of different types (e.g., in mov[sz]x |
| 963 // instrutions.) If Addr is not nullptr, then Rm is ignored, and Rex.B is | 963 // instrutions.) If Addr is not nullptr, then Rm is ignored, and Rex.B is |
|
Jim Stichnoth
2015/09/16 00:01:29
instructions
ascull
2015/09/16 18:30:09
Done.
| |
| 964 // determined by Addr instead. TyRm is still used to determine Addr's size. | 964 // determined by Addr instead. TyRm is still used to determine Addr's size. |
| 965 template <typename RegType, typename RmType, typename T = Traits> | 965 template <typename RegType, typename RmType, typename T = Traits> |
| 966 typename std::enable_if<T::Is64Bit, void>::type | 966 typename std::enable_if<T::Is64Bit, void>::type |
| 967 assembleAndEmitRex(const Type TyReg, const RegType Reg, const Type TyRm, | 967 assembleAndEmitRex(const Type TyReg, const RegType Reg, const Type TyRm, |
| 968 const RmType Rm, | 968 const RmType Rm, |
| 969 const typename T::Address *Addr = nullptr) { | 969 const typename T::Address *Addr = nullptr) { |
| 970 const uint8_t W = (TyReg == IceType_i64 || TyRm == IceType_i64) | 970 const uint8_t W = (TyReg == IceType_i64 || TyRm == IceType_i64) |
| 971 ? T::Operand::RexW | 971 ? T::Operand::RexW |
| 972 : T::Operand::RexNone; | 972 : T::Operand::RexNone; |
| 973 const uint8_t R = (Reg & 0x08) ? T::Operand::RexR : T::Operand::RexNone; | 973 const uint8_t R = (Reg & 0x08) ? T::Operand::RexR : T::Operand::RexNone; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 998 void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) { | 998 void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) { |
| 999 assembleAndEmitRex(Ty, Reg, Ty, Rm); | 999 assembleAndEmitRex(Ty, Reg, Ty, Rm); |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 template <typename RegType, typename RmType> | 1002 template <typename RegType, typename RmType> |
| 1003 void emitRexRB(const Type TyReg, const RegType Reg, const Type TyRm, | 1003 void emitRexRB(const Type TyReg, const RegType Reg, const Type TyRm, |
| 1004 const RmType Rm) { | 1004 const RmType Rm) { |
| 1005 assembleAndEmitRex(TyReg, Reg, TyRm, Rm); | 1005 assembleAndEmitRex(TyReg, Reg, TyRm, Rm); |
| 1006 } | 1006 } |
| 1007 | 1007 |
| 1008 // emitRexB is used for emitting a Rex prefix if one is needed on encoding the | 1008 // emitRexB is used for emitting a Rex prefix if one is needed on encoding |
| 1009 // Reg field in an x86 instruction. It is invoked by the template when Reg is | 1009 // the Reg field in an x86 instruction. It is invoked by the template when |
| 1010 // the single register operand in the instruction (e.g., push Reg.) | 1010 // Reg is the single register operand in the instruction (e.g., push Reg.) |
| 1011 template <typename RmType> void emitRexB(const Type Ty, const RmType Rm) { | 1011 template <typename RmType> void emitRexB(const Type Ty, const RmType Rm) { |
| 1012 emitRexRB(Ty, RexRegIrrelevant, Ty, Rm); | 1012 emitRexRB(Ty, RexRegIrrelevant, Ty, Rm); |
| 1013 } | 1013 } |
| 1014 | 1014 |
| 1015 // emitRex is used for emitting a Rex prefix for an address and a GPR. The | 1015 // emitRex is used for emitting a Rex prefix for an address and a GPR. The |
| 1016 // address may contain zero, one, or two registers. | 1016 // address may contain zero, one, or two registers. |
| 1017 template <typename RegType> | 1017 template <typename RegType> |
| 1018 void emitRex(const Type Ty, const typename Traits::Address &Addr, | 1018 void emitRex(const Type Ty, const typename Traits::Address &Addr, |
| 1019 const RegType Reg) { | 1019 const RegType Reg) { |
| 1020 assembleAndEmitRex(Ty, Reg, Ty, RexRegIrrelevant, &Addr); | 1020 assembleAndEmitRex(Ty, Reg, Ty, RexRegIrrelevant, &Addr); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1066 emitUint8(0x66); | 1066 emitUint8(0x66); |
| 1067 } | 1067 } |
| 1068 | 1068 |
| 1069 } // end of namespace X86Internal | 1069 } // end of namespace X86Internal |
| 1070 | 1070 |
| 1071 } // end of namespace Ice | 1071 } // end of namespace Ice |
| 1072 | 1072 |
| 1073 #include "IceAssemblerX86BaseImpl.h" | 1073 #include "IceAssemblerX86BaseImpl.h" |
| 1074 | 1074 |
| 1075 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H | 1075 #endif // SUBZERO_SRC_ICEASSEMBLERX86BASE_H |
| OLD | NEW |