Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=// | 1 //===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- C++ -*-=// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| 11 /// This file declares the X8632 Target Lowering Traits. | 11 /// This file declares the X8664 Target Lowering Traits. |
| 12 /// | 12 /// |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 15 #ifndef SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| 16 #define SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 16 #define SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| 17 | 17 |
| 18 #include "IceAssembler.h" | 18 #include "IceAssembler.h" |
| 19 #include "IceConditionCodesX8632.h" | 19 #include "IceConditionCodesX8664.h" |
| 20 #include "IceDefs.h" | 20 #include "IceDefs.h" |
| 21 #include "IceInst.h" | 21 #include "IceInst.h" |
| 22 #include "IceInstX8632.def" | 22 #include "IceInstX8664.def" |
| 23 #include "IceOperand.h" | 23 #include "IceOperand.h" |
| 24 #include "IceRegistersX8632.h" | 24 #include "IceRegistersX8664.h" |
| 25 #include "IceTargetLoweringX8632.def" | 25 #include "IceTargetLoweringX8664.def" |
| 26 #include "IceTargetLowering.h" | 26 #include "IceTargetLowering.h" |
| 27 | 27 |
| 28 namespace Ice { | 28 namespace Ice { |
| 29 | 29 |
| 30 class TargetX8632; | 30 class TargetX8664; |
| 31 | 31 |
| 32 namespace X8632 { | 32 namespace X8664 { |
| 33 class AssemblerX8632; | 33 class AssemblerX8664; |
| 34 } // end of namespace X8632 | 34 } // end of namespace X8664 |
| 35 | 35 |
| 36 namespace X86Internal { | 36 namespace X86Internal { |
| 37 | 37 |
| 38 template <class Machine> struct Insts; | 38 template <class Machine> struct Insts; |
| 39 template <class Machine> struct MachineTraits; | 39 template <class Machine> struct MachineTraits; |
| 40 template <class Machine> class TargetX86Base; | |
| 41 | 40 |
| 42 template <> struct MachineTraits<TargetX8632> { | 41 template <> struct MachineTraits<TargetX8664> { |
| 43 //---------------------------------------------------------------------------- | 42 //---------------------------------------------------------------------------- |
| 44 // ______ ______ __ __ | 43 // ______ ______ __ __ |
| 45 // /\ __ \/\ ___\/\ "-./ \ | 44 // /\ __ \/\ ___\/\ "-./ \ |
| 46 // \ \ __ \ \___ \ \ \-./\ \ | 45 // \ \ __ \ \___ \ \ \-./\ \ |
| 47 // \ \_\ \_\/\_____\ \_\ \ \_\ | 46 // \ \_\ \_\/\_____\ \_\ \ \_\ |
| 48 // \/_/\/_/\/_____/\/_/ \/_/ | 47 // \/_/\/_/\/_____/\/_/ \/_/ |
| 49 // | 48 // |
| 50 //---------------------------------------------------------------------------- | 49 //---------------------------------------------------------------------------- |
| 50 static constexpr bool Is64Bit = true; | |
| 51 static constexpr bool HasPopa = false; | |
| 52 static constexpr bool HasPusha = false; | |
| 53 static constexpr bool UsesX87 = false; | |
| 54 | |
| 51 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; | 55 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 }; |
| 52 | 56 |
| 53 using GPRRegister = ::Ice::RegX8632::GPRRegister; | 57 using GPRRegister = ::Ice::RegX8664::GPRRegister; |
| 54 using XmmRegister = ::Ice::RegX8632::XmmRegister; | 58 using XmmRegister = ::Ice::RegX8664::XmmRegister; |
| 55 using ByteRegister = ::Ice::RegX8632::ByteRegister; | 59 using ByteRegister = ::Ice::RegX8664::ByteRegister; |
| 56 using X87STRegister = ::Ice::RegX8632::X87STRegister; | |
| 57 | 60 |
| 58 using Cond = ::Ice::CondX86; | 61 using Cond = ::Ice::CondX8664; |
| 59 | 62 |
| 60 using RegisterSet = ::Ice::RegX8632; | 63 using RegisterSet = ::Ice::RegX8664; |
| 61 static const GPRRegister Encoded_Reg_Accumulator = RegX8632::Encoded_Reg_eax; | 64 static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax; |
| 62 static const GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx; | 65 static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx; |
| 63 static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32; | 66 static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32; // TODO(jpp): ??? |
|
jvoung (off chromium)
2015/07/23 17:59:36
FYI the llvm::ELF:: stuff comes from
toolchain_bu
John
2015/07/27 20:35:58
Thanks for the pointer.
| |
| 64 | 67 |
| 65 class Operand { | 68 class Operand { |
| 66 public: | 69 public: |
| 67 Operand(const Operand &other) | 70 Operand(const Operand &other) |
| 68 : fixup_(other.fixup_), length_(other.length_) { | 71 : fixup_(other.fixup_), length_(other.length_) { |
| 69 memmove(&encoding_[0], &other.encoding_[0], other.length_); | 72 memmove(&encoding_[0], &other.encoding_[0], other.length_); |
| 70 } | 73 } |
| 71 | 74 |
| 72 Operand &operator=(const Operand &other) { | 75 Operand &operator=(const Operand &other) { |
| 73 length_ = other.length_; | 76 length_ = other.length_; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 | 169 |
| 167 public: | 170 public: |
| 168 Address(const Address &other) : Operand(other) {} | 171 Address(const Address &other) : Operand(other) {} |
| 169 | 172 |
| 170 Address &operator=(const Address &other) { | 173 Address &operator=(const Address &other) { |
| 171 Operand::operator=(other); | 174 Operand::operator=(other); |
| 172 return *this; | 175 return *this; |
| 173 } | 176 } |
| 174 | 177 |
| 175 Address(GPRRegister base, int32_t disp) { | 178 Address(GPRRegister base, int32_t disp) { |
| 176 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) { | 179 if (disp == 0 && base != RegX8664::Encoded_Reg_ebp) { |
| 177 SetModRM(0, base); | 180 SetModRM(0, base); |
| 178 if (base == RegX8632::Encoded_Reg_esp) | 181 if (base == RegX8664::Encoded_Reg_esp) |
| 179 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); | 182 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base); |
| 180 } else if (Utils::IsInt(8, disp)) { | 183 } else if (Utils::IsInt(8, disp)) { |
| 181 SetModRM(1, base); | 184 SetModRM(1, base); |
| 182 if (base == RegX8632::Encoded_Reg_esp) | 185 if (base == RegX8664::Encoded_Reg_esp) |
| 183 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); | 186 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base); |
| 184 SetDisp8(disp); | 187 SetDisp8(disp); |
| 185 } else { | 188 } else { |
| 186 SetModRM(2, base); | 189 SetModRM(2, base); |
| 187 if (base == RegX8632::Encoded_Reg_esp) | 190 if (base == RegX8664::Encoded_Reg_esp) |
| 188 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base); | 191 SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base); |
| 189 SetDisp32(disp); | 192 SetDisp32(disp); |
| 190 } | 193 } |
| 191 } | 194 } |
| 192 | 195 |
| 193 Address(GPRRegister index, ScaleFactor scale, int32_t disp) { | 196 Address(GPRRegister index, ScaleFactor scale, int32_t disp) { |
| 194 assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode. | 197 assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode. |
| 195 SetModRM(0, RegX8632::Encoded_Reg_esp); | 198 SetModRM(0, RegX8664::Encoded_Reg_esp); |
| 196 SetSIB(scale, index, RegX8632::Encoded_Reg_ebp); | 199 SetSIB(scale, index, RegX8664::Encoded_Reg_ebp); |
| 197 SetDisp32(disp); | 200 SetDisp32(disp); |
| 198 } | 201 } |
| 199 | 202 |
| 200 Address(GPRRegister base, GPRRegister index, ScaleFactor scale, | 203 Address(GPRRegister base, GPRRegister index, ScaleFactor scale, |
| 201 int32_t disp) { | 204 int32_t disp) { |
| 202 assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode. | 205 assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode. |
| 203 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) { | 206 if (disp == 0 && base != RegX8664::Encoded_Reg_ebp) { |
| 204 SetModRM(0, RegX8632::Encoded_Reg_esp); | 207 SetModRM(0, RegX8664::Encoded_Reg_esp); |
| 205 SetSIB(scale, index, base); | 208 SetSIB(scale, index, base); |
| 206 } else if (Utils::IsInt(8, disp)) { | 209 } else if (Utils::IsInt(8, disp)) { |
| 207 SetModRM(1, RegX8632::Encoded_Reg_esp); | 210 SetModRM(1, RegX8664::Encoded_Reg_esp); |
| 208 SetSIB(scale, index, base); | 211 SetSIB(scale, index, base); |
| 209 SetDisp8(disp); | 212 SetDisp8(disp); |
| 210 } else { | 213 } else { |
| 211 SetModRM(2, RegX8632::Encoded_Reg_esp); | 214 SetModRM(2, RegX8664::Encoded_Reg_esp); |
| 212 SetSIB(scale, index, base); | 215 SetSIB(scale, index, base); |
| 213 SetDisp32(disp); | 216 SetDisp32(disp); |
| 214 } | 217 } |
| 215 } | 218 } |
| 216 | 219 |
| 217 /// AbsoluteTag is a special tag used by clients to create an absolute | 220 /// AbsoluteTag is a special tag used by clients to create an absolute |
| 218 /// Address. | 221 /// Address. |
| 219 enum AbsoluteTag { ABSOLUTE }; | 222 enum AbsoluteTag { ABSOLUTE }; |
| 220 | 223 |
| 221 Address(AbsoluteTag, const uintptr_t Addr) { | 224 Address(AbsoluteTag, const uintptr_t Addr) { |
| 222 SetModRM(0, RegX8632::Encoded_Reg_ebp); | 225 SetModRM(0, RegX8664::Encoded_Reg_ebp); |
| 223 SetDisp32(Addr); | 226 SetDisp32(Addr); |
| 224 } | 227 } |
| 225 | 228 |
| 226 // TODO(jpp): remove this. | 229 // TODO(jpp): remove this. |
| 227 static Address Absolute(const uintptr_t Addr) { | 230 static Address Absolute(const uintptr_t Addr) { |
| 228 return Address(ABSOLUTE, Addr); | 231 return Address(ABSOLUTE, Addr); |
| 229 } | 232 } |
| 230 | 233 |
| 231 Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) { | 234 Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) { |
| 232 SetModRM(0, RegX8632::Encoded_Reg_ebp); | 235 SetModRM(0, RegX8664::Encoded_Reg_ebp); |
| 233 // Use the Offset in the displacement for now. If we decide to process | 236 // Use the Offset in the displacement for now. If we decide to process |
| 234 // fixups later, we'll need to patch up the emitted displacement. | 237 // fixups later, we'll need to patch up the emitted displacement. |
| 235 SetDisp32(Offset); | 238 SetDisp32(Offset); |
| 236 SetFixup(Fixup); | 239 SetFixup(Fixup); |
| 237 } | 240 } |
| 238 | 241 |
| 239 // TODO(jpp): remove this. | 242 // TODO(jpp): remove this. |
| 240 static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) { | 243 static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) { |
| 241 return Address(ABSOLUTE, Offset, Fixup); | 244 return Address(ABSOLUTE, Offset, Fixup); |
| 242 } | 245 } |
| 243 | 246 |
| 244 static Address ofConstPool(Assembler *Asm, const Constant *Imm) { | 247 static Address ofConstPool(Assembler *Asm, const Constant *Imm) { |
| 248 // TODO(jpp): ??? | |
| 245 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm); | 249 AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm); |
| 246 const RelocOffsetT Offset = 0; | 250 const RelocOffsetT Offset = 0; |
| 247 return Address(ABSOLUTE, Offset, Fixup); | 251 return Address(ABSOLUTE, Offset, Fixup); |
| 248 } | 252 } |
| 249 }; | 253 }; |
| 250 | 254 |
| 255 #if 0 | |
| 256 // The Traits for lowering/insts for x86-64 are very similar to the ones for x 86-32, so these are kept here. | |
|
jvoung (off chromium)
2015/07/23 17:59:36
Just checking, but is the #if 0 necessary?
John
2015/07/27 20:35:58
It would help me out to keep implementing the back
| |
| 251 //---------------------------------------------------------------------------- | 257 //---------------------------------------------------------------------------- |
| 252 // __ ______ __ __ ______ ______ __ __ __ ______ | 258 // __ ______ __ __ ______ ______ __ __ __ ______ |
| 253 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ | 259 // /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\ |
| 254 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ | 260 // \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \ |
| 255 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ | 261 // \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\ |
| 256 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ | 262 // \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/ |
| 257 // | 263 // |
| 258 //---------------------------------------------------------------------------- | 264 //---------------------------------------------------------------------------- |
| 259 enum InstructionSet { | 265 enum InstructionSet { |
| 260 Begin, | 266 Begin, |
| 261 // SSE2 is the PNaCl baseline instruction set. | 267 // SSE2 is the PNaCl baseline instruction set. |
| 262 SSE2 = Begin, | 268 SSE2 = Begin, |
| 263 SSE4_1, | 269 SSE4_1, |
| 264 End | 270 End |
| 265 }; | 271 }; |
| 266 | 272 |
| 267 static const char *TargetName; | 273 static const char *TargetName; |
| 268 | 274 |
| 269 static IceString getRegName(SizeT RegNum, Type Ty) { | 275 static IceString getRegName(SizeT RegNum, Type Ty) { |
| 270 assert(RegNum < RegisterSet::Reg_NUM); | 276 assert(RegNum < RegisterSet::Reg_NUM); |
| 271 static const char *RegNames8[] = { | 277 static const char *RegNames8[] = { |
| 272 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 278 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 273 frameptr, isI8, isInt, isFP) \ | 279 frameptr, isI8, isInt, isFP) \ |
| 274 name8, | 280 name8, |
| 275 REGX8632_TABLE | 281 REGX8664_TABLE |
| 276 #undef X | 282 #undef X |
| 277 }; | 283 }; |
| 278 | 284 |
| 279 static const char *RegNames16[] = { | 285 static const char *RegNames16[] = { |
| 280 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 286 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 281 frameptr, isI8, isInt, isFP) \ | 287 frameptr, isI8, isInt, isFP) \ |
| 282 name16, | 288 name16, |
| 283 REGX8632_TABLE | 289 REGX8664_TABLE |
| 284 #undef X | 290 #undef X |
| 285 }; | 291 }; |
| 286 | 292 |
| 287 static const char *RegNames[] = { | 293 static const char *RegNames[] = { |
| 288 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 294 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 289 frameptr, isI8, isInt, isFP) \ | 295 frameptr, isI8, isInt, isFP) \ |
| 290 name, | 296 name, |
| 291 REGX8632_TABLE | 297 REGX8664_TABLE |
| 292 #undef X | 298 #undef X |
| 293 }; | 299 }; |
| 294 | 300 |
| 295 switch (Ty) { | 301 switch (Ty) { |
| 296 case IceType_i1: | 302 case IceType_i1: |
| 297 case IceType_i8: | 303 case IceType_i8: |
| 298 return RegNames8[RegNum]; | 304 return RegNames8[RegNum]; |
| 299 case IceType_i16: | 305 case IceType_i16: |
| 300 return RegNames16[RegNum]; | 306 return RegNames16[RegNum]; |
| 301 default: | 307 default: |
| 302 return RegNames[RegNum]; | 308 return RegNames[RegNum]; |
| 303 } | 309 } |
| 304 } | 310 } |
| 305 | 311 |
| 306 static void initRegisterSet(llvm::SmallBitVector *IntegerRegisters, | 312 static void initRegisterSet(llvm::SmallBitVector *IntegerRegisters, |
| 307 llvm::SmallBitVector *IntegerRegistersI8, | 313 llvm::SmallBitVector *IntegerRegistersI8, |
| 308 llvm::SmallBitVector *FloatRegisters, | 314 llvm::SmallBitVector *FloatRegisters, |
| 309 llvm::SmallBitVector *VectorRegisters, | 315 llvm::SmallBitVector *VectorRegisters, |
| 310 llvm::SmallBitVector *ScratchRegs) { | 316 llvm::SmallBitVector *ScratchRegs) { |
| 311 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 317 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 312 frameptr, isI8, isInt, isFP) \ | 318 frameptr, isI8, isInt, isFP) \ |
| 313 (*IntegerRegisters)[RegisterSet::val] = isInt; \ | 319 (*IntegerRegisters)[RegisterSet::val] = isInt; \ |
| 314 (*IntegerRegistersI8)[RegisterSet::val] = isI8; \ | 320 (*IntegerRegistersI8)[RegisterSet::val] = isI8; \ |
| 315 (*FloatRegisters)[RegisterSet::val] = isFP; \ | 321 (*FloatRegisters)[RegisterSet::val] = isFP; \ |
| 316 (*VectorRegisters)[RegisterSet::val] = isFP; \ | 322 (*VectorRegisters)[RegisterSet::val] = isFP; \ |
| 317 (*ScratchRegs)[RegisterSet::val] = scratch; | 323 (*ScratchRegs)[RegisterSet::val] = scratch; |
| 318 REGX8632_TABLE; | 324 REGX8664_TABLE; |
| 319 #undef X | 325 #undef X |
| 320 } | 326 } |
| 321 | 327 |
| 322 static llvm::SmallBitVector | 328 static llvm::SmallBitVector |
| 323 getRegisterSet(TargetLowering::RegSetMask Include, | 329 getRegisterSet(TargetLowering::RegSetMask Include, |
| 324 TargetLowering::RegSetMask Exclude) { | 330 TargetLowering::RegSetMask Exclude) { |
| 325 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); | 331 llvm::SmallBitVector Registers(RegisterSet::Reg_NUM); |
| 326 | 332 |
| 327 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 333 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 328 frameptr, isI8, isInt, isFP) \ | 334 frameptr, isI8, isInt, isFP) \ |
| 329 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 335 if (scratch && (Include & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
| 330 Registers[RegisterSet::val] = true; \ | 336 Registers[RegisterSet::val] = true; \ |
| 331 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 337 if (preserved && (Include & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
| 332 Registers[RegisterSet::val] = true; \ | 338 Registers[RegisterSet::val] = true; \ |
| 333 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 339 if (stackptr && (Include & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
| 334 Registers[RegisterSet::val] = true; \ | 340 Registers[RegisterSet::val] = true; \ |
| 335 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 341 if (frameptr && (Include & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
| 336 Registers[RegisterSet::val] = true; \ | 342 Registers[RegisterSet::val] = true; \ |
| 337 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ | 343 if (scratch && (Exclude & ::Ice::TargetLowering::RegSet_CallerSave)) \ |
| 338 Registers[RegisterSet::val] = false; \ | 344 Registers[RegisterSet::val] = false; \ |
| 339 if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ | 345 if (preserved && (Exclude & ::Ice::TargetLowering::RegSet_CalleeSave)) \ |
| 340 Registers[RegisterSet::val] = false; \ | 346 Registers[RegisterSet::val] = false; \ |
| 341 if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ | 347 if (stackptr && (Exclude & ::Ice::TargetLowering::RegSet_StackPointer)) \ |
| 342 Registers[RegisterSet::val] = false; \ | 348 Registers[RegisterSet::val] = false; \ |
| 343 if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ | 349 if (frameptr && (Exclude & ::Ice::TargetLowering::RegSet_FramePointer)) \ |
| 344 Registers[RegisterSet::val] = false; | 350 Registers[RegisterSet::val] = false; |
| 345 | 351 |
| 346 REGX8632_TABLE | 352 REGX8664_TABLE |
| 347 | 353 |
| 348 #undef X | 354 #undef X |
| 349 | 355 |
| 350 return Registers; | 356 return Registers; |
| 351 } | 357 } |
| 352 | 358 |
| 353 static void | 359 static void |
| 354 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, | 360 makeRandomRegisterPermutation(GlobalContext *Ctx, Cfg *Func, |
| 355 llvm::SmallVectorImpl<int32_t> &Permutation, | 361 llvm::SmallVectorImpl<int32_t> &Permutation, |
| 356 const llvm::SmallBitVector &ExcludeRegisters) { | 362 const llvm::SmallBitVector &ExcludeRegisters) { |
| 357 // TODO(stichnot): Declaring Permutation this way loses type/size | 363 // TODO(stichnot): Declaring Permutation this way loses type/size |
| 358 // information. Fix this in conjunction with the caller-side TODO. | 364 // information. Fix this in conjunction with the caller-side TODO. |
| 359 assert(Permutation.size() >= RegisterSet::Reg_NUM); | 365 assert(Permutation.size() >= RegisterSet::Reg_NUM); |
| 360 // Expected upper bound on the number of registers in a single equivalence | 366 // Expected upper bound on the number of registers in a single equivalence |
| 361 // class. For x86-32, this would comprise the 8 XMM registers. This is for | 367 // class. For x86-64, this would comprise the 8 XMM registers. This is for |
| 362 // performance, not correctness. | 368 // performance, not correctness. |
| 363 static const unsigned MaxEquivalenceClassSize = 8; | 369 static const unsigned MaxEquivalenceClassSize = 8; |
| 364 typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList; | 370 typedef llvm::SmallVector<int32_t, MaxEquivalenceClassSize> RegisterList; |
| 365 typedef std::map<uint32_t, RegisterList> EquivalenceClassMap; | 371 typedef std::map<uint32_t, RegisterList> EquivalenceClassMap; |
| 366 EquivalenceClassMap EquivalenceClasses; | 372 EquivalenceClassMap EquivalenceClasses; |
| 367 SizeT NumShuffled = 0, NumPreserved = 0; | 373 SizeT NumShuffled = 0, NumPreserved = 0; |
| 368 | 374 |
| 369 // Build up the equivalence classes of registers by looking at the register | 375 // Build up the equivalence classes of registers by looking at the register |
| 370 // properties as well as whether the registers should be explicitly excluded | 376 // properties as well as whether the registers should be explicitly excluded |
| 371 // from shuffling. | 377 // from shuffling. |
| 372 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ | 378 #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ |
| 373 frameptr, isI8, isInt, isFP) \ | 379 frameptr, isI8, isInt, isFP) \ |
| 374 if (ExcludeRegisters[RegisterSet::val]) { \ | 380 if (ExcludeRegisters[RegisterSet::val]) { \ |
| 375 /* val stays the same in the resulting permutation. */ \ | 381 /* val stays the same in the resulting permutation. */ \ |
| 376 Permutation[RegisterSet::val] = RegisterSet::val; \ | 382 Permutation[RegisterSet::val] = RegisterSet::val; \ |
| 377 ++NumPreserved; \ | 383 ++NumPreserved; \ |
| 378 } else { \ | 384 } else { \ |
| 379 const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \ | 385 const uint32_t Index = (scratch << 0) | (preserved << 1) | (isI8 << 2) | \ |
| 380 (isInt << 3) | (isFP << 4); \ | 386 (isInt << 3) | (isFP << 4); \ |
| 381 /* val is assigned to an equivalence class based on its properties. */ \ | 387 /* val is assigned to an equivalence class based on its properties. */ \ |
| 382 EquivalenceClasses[Index].push_back(RegisterSet::val); \ | 388 EquivalenceClasses[Index].push_back(RegisterSet::val); \ |
| 383 } | 389 } |
| 384 REGX8632_TABLE | 390 REGX8664_TABLE |
| 385 #undef X | 391 #undef X |
| 386 | 392 |
| 387 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); | 393 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); |
| 388 | 394 |
| 389 // Shuffle the resulting equivalence classes. | 395 // Shuffle the resulting equivalence classes. |
| 390 for (auto I : EquivalenceClasses) { | 396 for (auto I : EquivalenceClasses) { |
| 391 const RegisterList &List = I.second; | 397 const RegisterList &List = I.second; |
| 392 RegisterList Shuffled(List); | 398 RegisterList Shuffled(List); |
| 393 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG); | 399 RandomShuffle(Shuffled.begin(), Shuffled.end(), RNG); |
| 394 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { | 400 for (size_t SI = 0, SE = Shuffled.size(); SI < SE; ++SI) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 415 } | 421 } |
| 416 Str << "}\n"; | 422 Str << "}\n"; |
| 417 } | 423 } |
| 418 } | 424 } |
| 419 } | 425 } |
| 420 | 426 |
| 421 /// The maximum number of arguments to pass in XMM registers | 427 /// The maximum number of arguments to pass in XMM registers |
| 422 static const uint32_t X86_MAX_XMM_ARGS = 4; | 428 static const uint32_t X86_MAX_XMM_ARGS = 4; |
| 423 /// The number of bits in a byte | 429 /// The number of bits in a byte |
| 424 static const uint32_t X86_CHAR_BIT = 8; | 430 static const uint32_t X86_CHAR_BIT = 8; |
| 425 /// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it | 431 /// Stack alignment. This is defined in IceTargetLoweringX8664.cpp because it |
| 426 /// is used as an argument to std::max(), and the default std::less<T> has an | 432 /// is used as an argument to std::max(), and the default std::less<T> has an |
| 427 /// operator(T const&, T const&) which requires this member to have an | 433 /// operator(T const&, T const&) which requires this member to have an |
| 428 /// address. | 434 /// address. |
| 429 static const uint32_t X86_STACK_ALIGNMENT_BYTES; | 435 static const uint32_t X86_STACK_ALIGNMENT_BYTES; |
| 430 /// Size of the return address on the stack | 436 /// Size of the return address on the stack |
| 431 static const uint32_t X86_RET_IP_SIZE_BYTES = 4; | 437 static const uint32_t X86_RET_IP_SIZE_BYTES = 4; |
| 432 /// The number of different NOP instructions | 438 /// The number of different NOP instructions |
| 433 static const uint32_t X86_NUM_NOP_VARIANTS = 5; | 439 static const uint32_t X86_NUM_NOP_VARIANTS = 5; |
| 434 | 440 |
| 435 /// Value is in bytes. Return Value adjusted to the next highest multiple | 441 /// Value is in bytes. Return Value adjusted to the next highest multiple |
| 436 /// of the stack alignment. | 442 /// of the stack alignment. |
| 437 static uint32_t applyStackAlignment(uint32_t Value) { | 443 static uint32_t applyStackAlignment(uint32_t Value) { |
| 438 return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); | 444 return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); |
| 439 } | 445 } |
| 440 | 446 |
| 441 /// Return the type which the elements of the vector have in the X86 | 447 /// Return the type which the elements of the vector have in the X86 |
| 442 /// representation of the vector. | 448 /// representation of the vector. |
| 443 static Type getInVectorElementType(Type Ty) { | 449 static Type getInVectorElementType(Type Ty) { |
| 444 assert(isVectorType(Ty)); | 450 assert(isVectorType(Ty)); |
| 445 size_t Index = static_cast<size_t>(Ty); | 451 size_t Index = static_cast<size_t>(Ty); |
| 446 (void)Index; | 452 (void)Index; |
| 447 assert(Index < TableTypeX8632AttributesSize); | 453 assert(Index < TableTypeX8664AttributesSize); |
| 448 return TableTypeX8632Attributes[Ty].InVectorElementType; | 454 return TableTypeX8664Attributes[Ty].InVectorElementType; |
| 449 } | 455 } |
| 450 | 456 |
| 451 // Note: The following data structures are defined in | 457 // Note: The following data structures are defined in |
| 452 // IceTargetLoweringX8632.cpp. | 458 // IceTargetLoweringX8664.cpp. |
| 453 | 459 |
| 454 /// The following table summarizes the logic for lowering the fcmp | 460 /// The following table summarizes the logic for lowering the fcmp |
| 455 /// instruction. There is one table entry for each of the 16 conditions. | 461 /// instruction. There is one table entry for each of the 16 conditions. |
| 456 /// | 462 /// |
| 457 /// The first four columns describe the case when the operands are floating | 463 /// The first four columns describe the case when the operands are floating |
| 458 /// point scalar values. A comment in lowerFcmp() describes the lowering | 464 /// point scalar values. A comment in lowerFcmp() describes the lowering |
| 459 /// template. In the most general case, there is a compare followed by two | 465 /// template. In the most general case, there is a compare followed by two |
| 460 /// conditional branches, because some fcmp conditions don't map to a single | 466 /// conditional branches, because some fcmp conditions don't map to a single |
| 461 /// x86 conditional branch. However, in many cases it is possible to swap the | 467 /// x86 conditional branch. However, in many cases it is possible to swap the |
| 462 /// operands in the comparison and have a single conditional branch. Since | 468 /// operands in the comparison and have a single conditional branch. Since |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 } TableIcmp64[]; | 503 } TableIcmp64[]; |
| 498 static const size_t TableIcmp64Size; | 504 static const size_t TableIcmp64Size; |
| 499 /// @} | 505 /// @} |
| 500 | 506 |
| 501 static Cond::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { | 507 static Cond::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { |
| 502 size_t Index = static_cast<size_t>(Cond); | 508 size_t Index = static_cast<size_t>(Cond); |
| 503 assert(Index < TableIcmp32Size); | 509 assert(Index < TableIcmp32Size); |
| 504 return TableIcmp32[Index].Mapping; | 510 return TableIcmp32[Index].Mapping; |
| 505 } | 511 } |
| 506 | 512 |
| 507 static const struct TableTypeX8632AttributesType { | 513 static const struct TableTypeX8664AttributesType { |
| 508 Type InVectorElementType; | 514 Type InVectorElementType; |
| 509 } TableTypeX8632Attributes[]; | 515 } TableTypeX8664Attributes[]; |
| 510 static const size_t TableTypeX8632AttributesSize; | 516 static const size_t TableTypeX8664AttributesSize; |
| 511 | 517 |
| 512 //---------------------------------------------------------------------------- | 518 //---------------------------------------------------------------------------- |
| 513 // __ __ __ ______ ______ | 519 // __ __ __ ______ ______ |
| 514 // /\ \/\ "-.\ \/\ ___\/\__ _\ | 520 // /\ \/\ "-.\ \/\ ___\/\__ _\ |
| 515 // \ \ \ \ \-. \ \___ \/_/\ \/ | 521 // \ \ \ \ \-. \ \___ \/_/\ \/ |
| 516 // \ \_\ \_\\"\_\/\_____\ \ \_\ | 522 // \ \_\ \_\\"\_\/\_____\ \ \_\ |
| 517 // \/_/\/_/ \/_/\/_____/ \/_/ | 523 // \/_/\/_/ \/_/\/_____/ \/_/ |
| 518 // | 524 // |
| 519 //---------------------------------------------------------------------------- | 525 //---------------------------------------------------------------------------- |
| 520 using Insts = ::Ice::X86Internal::Insts<TargetX8632>; | 526 using Insts = ::Ice::X86Internal::Insts<TargetX8664>; |
| 521 | 527 |
| 522 using TargetLowering = ::Ice::X86Internal::TargetX86Base<TargetX8632>; | 528 using TargetLowering = TargetX8664; |
| 523 using Assembler = X8632::AssemblerX8632; | 529 using Assembler = X8664::AssemblerX8664; |
| 524 | 530 |
| 525 /// X86Operand extends the Operand hierarchy. Its subclasses are | 531 /// X86Operand extends the Operand hierarchy. Its subclasses are |
| 526 /// X86OperandMem and VariableSplit. | 532 /// X86OperandMem and VariableSplit. |
| 527 class X86Operand : public ::Ice::Operand { | 533 class X86Operand : public ::Ice::Operand { |
| 528 X86Operand() = delete; | 534 X86Operand() = delete; |
| 529 X86Operand(const X86Operand &) = delete; | 535 X86Operand(const X86Operand &) = delete; |
| 530 X86Operand &operator=(const X86Operand &) = delete; | 536 X86Operand &operator=(const X86Operand &) = delete; |
| 531 | 537 |
| 532 public: | 538 public: |
| 533 enum OperandKindX8632 { k__Start = ::Ice::Operand::kTarget, kMem, kSplit }; | 539 enum OperandKindX8664 { k__Start = ::Ice::Operand::kTarget, kMem, kSplit }; |
| 534 using ::Ice::Operand::dump; | 540 using ::Ice::Operand::dump; |
| 535 | 541 |
| 536 void dump(const Cfg *, Ostream &Str) const override; | 542 void dump(const Cfg *, Ostream &Str) const override; |
| 537 | 543 |
| 538 protected: | 544 protected: |
| 539 X86Operand(OperandKindX8632 Kind, Type Ty) | 545 X86Operand(OperandKindX8664 Kind, Type Ty) |
| 540 : Operand(static_cast<::Ice::Operand::OperandKind>(Kind), Ty) {} | 546 : Operand(static_cast<::Ice::Operand::OperandKind>(Kind), Ty) {} |
| 541 }; | 547 }; |
| 542 | 548 |
| 543 /// X86OperandMem represents the m32 addressing mode, with optional base and | 549 /// X86OperandMem represents the m32 addressing mode, with optional base and |
| 544 /// index registers, a constant offset, and a fixed shift value for the index | 550 /// index registers, a constant offset, and a fixed shift value for the index |
| 545 /// register. | 551 /// register. |
| 546 class X86OperandMem : public X86Operand { | 552 class X86OperandMem : public X86Operand { |
| 547 X86OperandMem() = delete; | 553 X86OperandMem() = delete; |
| 548 X86OperandMem(const X86OperandMem &) = delete; | 554 X86OperandMem(const X86OperandMem &) = delete; |
| 549 X86OperandMem &operator=(const X86OperandMem &) = delete; | 555 X86OperandMem &operator=(const X86OperandMem &) = delete; |
| 550 | 556 |
| 551 public: | 557 public: |
| 552 enum SegmentRegisters { | 558 enum SegmentRegisters { |
| 553 DefaultSegment = -1, | 559 DefaultSegment = -1, |
| 554 #define X(val, name, prefix) val, | 560 #define X(val, name, prefix) val, |
| 555 SEG_REGX8632_TABLE | 561 SEG_REGX8664_TABLE |
| 556 #undef X | 562 #undef X |
| 557 SegReg_NUM | 563 SegReg_NUM |
| 558 }; | 564 }; |
| 559 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, | 565 static X86OperandMem *create(Cfg *Func, Type Ty, Variable *Base, |
| 560 Constant *Offset, Variable *Index = nullptr, | 566 Constant *Offset, Variable *Index = nullptr, |
| 561 uint16_t Shift = 0, | 567 uint16_t Shift = 0, |
| 562 SegmentRegisters SegmentReg = DefaultSegment) { | 568 SegmentRegisters SegmentReg = DefaultSegment) { |
| 563 return new (Func->allocate<X86OperandMem>()) | 569 return new (Func->allocate<X86OperandMem>()) |
| 564 X86OperandMem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); | 570 X86OperandMem(Func, Ty, Base, Offset, Index, Shift, SegmentReg); |
| 565 } | 571 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 void setLinkedTo(Variable *Var) { LinkedTo = Var; } | 668 void setLinkedTo(Variable *Var) { LinkedTo = Var; } |
| 663 Variable *getLinkedTo() const { return LinkedTo; } | 669 Variable *getLinkedTo() const { return LinkedTo; } |
| 664 // Inherit dump() and emit() from Variable. | 670 // Inherit dump() and emit() from Variable. |
| 665 | 671 |
| 666 private: | 672 private: |
| 667 SpillVariable(Type Ty, SizeT Index) | 673 SpillVariable(Type Ty, SizeT Index) |
| 668 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} | 674 : Variable(SpillVariableKind, Ty, Index), LinkedTo(nullptr) {} |
| 669 Variable *LinkedTo; | 675 Variable *LinkedTo; |
| 670 }; | 676 }; |
| 671 | 677 |
| 672 // Note: The following data structures are defined in IceInstX8632.cpp. | 678 // Note: The following data structures are defined in IceInstX8664.cpp. |
| 673 | 679 |
| 674 static const struct InstBrAttributesType { | 680 static const struct InstBrAttributesType { |
| 675 Cond::BrCond Opposite; | 681 Cond::BrCond Opposite; |
| 676 const char *DisplayString; | 682 const char *DisplayString; |
| 677 const char *EmitString; | 683 const char *EmitString; |
| 678 } InstBrAttributes[]; | 684 } InstBrAttributes[]; |
| 679 | 685 |
| 680 static const struct InstCmppsAttributesType { | 686 static const struct InstCmppsAttributesType { |
| 681 const char *EmitString; | 687 const char *EmitString; |
| 682 } InstCmppsAttributes[]; | 688 } InstCmppsAttributes[]; |
| 683 | 689 |
| 684 static const struct TypeAttributesType { | 690 static const struct TypeAttributesType { |
| 685 const char *CvtString; // i (integer), s (single FP), d (double FP) | 691 const char *CvtString; // i (integer), s (single FP), d (double FP) |
| 686 const char *SdSsString; // ss, sd, or <blank> | 692 const char *SdSsString; // ss, sd, or <blank> |
| 687 const char *PackString; // b, w, d, or <blank> | 693 const char *PackString; // b, w, d, or <blank> |
| 688 const char *WidthString; // b, w, l, q, or <blank> | 694 const char *WidthString; // b, w, l, q, or <blank> |
| 689 const char *FldString; // s, l, or <blank> | 695 const char *FldString; // s, l, or <blank> |
| 690 } TypeAttributes[]; | 696 } TypeAttributes[]; |
| 691 | 697 |
| 692 static const char *InstSegmentRegNames[]; | 698 static const char *InstSegmentRegNames[]; |
| 693 | 699 |
| 694 static uint8_t InstSegmentPrefixes[]; | 700 static uint8_t InstSegmentPrefixes[]; |
| 701 #endif // 0 | |
| 695 }; | 702 }; |
| 696 | 703 |
| 697 } // end of namespace X86Internal | 704 } // end of namespace X86Internal |
| 698 | 705 |
| 699 namespace X8632 { | 706 namespace X8664 { |
| 700 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>; | 707 using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>; |
| 701 } // end of namespace X8632 | 708 } // end of namespace X8664 |
| 702 | 709 |
| 703 } // end of namespace Ice | 710 } // end of namespace Ice |
| 704 | 711 |
| 705 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H | 712 #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H |
| OLD | NEW |