| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
| 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 |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 5 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 6 // | 9 // |
| 7 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
| 8 // consists almost entirely of the lowering sequence for each | 11 // consists almost entirely of the lowering sequence for each |
| 9 // high-level instruction. | 12 // high-level instruction. |
| 10 // | 13 // |
| 11 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 12 | 15 |
| 13 #include "IceTargetLoweringX8632.h" | 16 #include "IceTargetLoweringX8632.h" |
| 14 | 17 |
| 18 #include "IceTargetLoweringX8632Traits.h" |
| 15 #include "IceTargetLoweringX86Base.h" | 19 #include "IceTargetLoweringX86Base.h" |
| 16 | 20 |
| 17 namespace Ice { | 21 namespace Ice { |
| 22 |
| 18 namespace X86Internal { | 23 namespace X86Internal { |
| 19 template <> struct MachineTraits<TargetX8632> { | |
| 20 using InstructionSet = TargetX8632::X86InstructionSet; | |
| 21 | |
| 22 // The following table summarizes the logic for lowering the fcmp | |
| 23 // instruction. There is one table entry for each of the 16 conditions. | |
| 24 // | |
| 25 // The first four columns describe the case when the operands are | |
| 26 // floating point scalar values. A comment in lowerFcmp() describes the | |
| 27 // lowering template. In the most general case, there is a compare | |
| 28 // followed by two conditional branches, because some fcmp conditions | |
| 29 // don't map to a single x86 conditional branch. However, in many cases | |
| 30 // it is possible to swap the operands in the comparison and have a | |
| 31 // single conditional branch. Since it's quite tedious to validate the | |
| 32 // table by hand, good execution tests are helpful. | |
| 33 // | |
| 34 // The last two columns describe the case when the operands are vectors | |
| 35 // of floating point values. For most fcmp conditions, there is a clear | |
| 36 // mapping to a single x86 cmpps instruction variant. Some fcmp | |
| 37 // conditions require special code to handle and these are marked in the | |
| 38 // table with a Cmpps_Invalid predicate. | |
| 39 static const struct TableFcmpType { | |
| 40 uint32_t Default; | |
| 41 bool SwapScalarOperands; | |
| 42 CondX86::BrCond C1, C2; | |
| 43 bool SwapVectorOperands; | |
| 44 CondX86::CmppsCond Predicate; | |
| 45 } TableFcmp[]; | |
| 46 static const size_t TableFcmpSize; | |
| 47 | |
| 48 // The following table summarizes the logic for lowering the icmp instruction | |
| 49 // for i32 and narrower types. Each icmp condition has a clear mapping to an | |
| 50 // x86 conditional branch instruction. | |
| 51 | |
| 52 static const struct TableIcmp32Type { | |
| 53 CondX86::BrCond Mapping; | |
| 54 } TableIcmp32[]; | |
| 55 static const size_t TableIcmp32Size; | |
| 56 | |
| 57 // The following table summarizes the logic for lowering the icmp instruction | |
| 58 // for the i64 type. For Eq and Ne, two separate 32-bit comparisons and | |
| 59 // conditional branches are needed. For the other conditions, three separate | |
| 60 // conditional branches are needed. | |
| 61 static const struct TableIcmp64Type { | |
| 62 CondX86::BrCond C1, C2, C3; | |
| 63 } TableIcmp64[]; | |
| 64 static const size_t TableIcmp64Size; | |
| 65 | |
| 66 static CondX86::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { | |
| 67 size_t Index = static_cast<size_t>(Cond); | |
| 68 assert(Index < TableIcmp32Size); | |
| 69 return TableIcmp32[Index].Mapping; | |
| 70 } | |
| 71 | |
| 72 static const struct TableTypeX8632AttributesType { | |
| 73 Type InVectorElementType; | |
| 74 } TableTypeX8632Attributes[]; | |
| 75 static const size_t TableTypeX8632AttributesSize; | |
| 76 | |
| 77 // Return the type which the elements of the vector have in the X86 | |
| 78 // representation of the vector. | |
| 79 static Type getInVectorElementType(Type Ty) { | |
| 80 assert(isVectorType(Ty)); | |
| 81 size_t Index = static_cast<size_t>(Ty); | |
| 82 (void)Index; | |
| 83 assert(Index < TableTypeX8632AttributesSize); | |
| 84 return TableTypeX8632Attributes[Ty].InVectorElementType; | |
| 85 } | |
| 86 | |
| 87 // The maximum number of arguments to pass in XMM registers | |
| 88 static const uint32_t X86_MAX_XMM_ARGS = 4; | |
| 89 // The number of bits in a byte | |
| 90 static const uint32_t X86_CHAR_BIT = 8; | |
| 91 // Stack alignment | |
| 92 static const uint32_t X86_STACK_ALIGNMENT_BYTES; | |
| 93 // Size of the return address on the stack | |
| 94 static const uint32_t X86_RET_IP_SIZE_BYTES = 4; | |
| 95 // The number of different NOP instructions | |
| 96 static const uint32_t X86_NUM_NOP_VARIANTS = 5; | |
| 97 | |
| 98 // Value is in bytes. Return Value adjusted to the next highest multiple | |
| 99 // of the stack alignment. | |
| 100 static uint32_t applyStackAlignment(uint32_t Value) { | |
| 101 return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); | |
| 102 } | |
| 103 }; | |
| 104 | |
| 105 const MachineTraits<TargetX8632>::TableFcmpType | 24 const MachineTraits<TargetX8632>::TableFcmpType |
| 106 MachineTraits<TargetX8632>::TableFcmp[] = { | 25 MachineTraits<TargetX8632>::TableFcmp[] = { |
| 107 #define X(val, dflt, swapS, C1, C2, swapV, pred) \ | 26 #define X(val, dflt, swapS, C1, C2, swapV, pred) \ |
| 108 { dflt, swapS, CondX86::C1, CondX86::C2, swapV, CondX86::pred } \ | 27 { \ |
| 28 dflt, swapS, X8632::Traits::Cond::C1, X8632::Traits::Cond::C2, swapV, \ |
| 29 X8632::Traits::Cond::pred \ |
| 30 } \ |
| 109 , | 31 , |
| 110 FCMPX8632_TABLE | 32 FCMPX8632_TABLE |
| 111 #undef X | 33 #undef X |
| 112 }; | 34 }; |
| 113 | 35 |
| 114 const size_t MachineTraits<TargetX8632>::TableFcmpSize = | 36 const size_t MachineTraits<TargetX8632>::TableFcmpSize = |
| 115 llvm::array_lengthof(TableFcmp); | 37 llvm::array_lengthof(TableFcmp); |
| 116 | 38 |
| 117 const MachineTraits<TargetX8632>::TableIcmp32Type | 39 const MachineTraits<TargetX8632>::TableIcmp32Type |
| 118 MachineTraits<TargetX8632>::TableIcmp32[] = { | 40 MachineTraits<TargetX8632>::TableIcmp32[] = { |
| 119 #define X(val, C_32, C1_64, C2_64, C3_64) \ | 41 #define X(val, C_32, C1_64, C2_64, C3_64) \ |
| 120 { CondX86::C_32 } \ | 42 { X8632::Traits::Cond::C_32 } \ |
| 121 , | 43 , |
| 122 ICMPX8632_TABLE | 44 ICMPX8632_TABLE |
| 123 #undef X | 45 #undef X |
| 124 }; | 46 }; |
| 125 | 47 |
| 126 const size_t MachineTraits<TargetX8632>::TableIcmp32Size = | 48 const size_t MachineTraits<TargetX8632>::TableIcmp32Size = |
| 127 llvm::array_lengthof(TableIcmp32); | 49 llvm::array_lengthof(TableIcmp32); |
| 128 | 50 |
| 129 const MachineTraits<TargetX8632>::TableIcmp64Type | 51 const MachineTraits<TargetX8632>::TableIcmp64Type |
| 130 MachineTraits<TargetX8632>::TableIcmp64[] = { | 52 MachineTraits<TargetX8632>::TableIcmp64[] = { |
| 131 #define X(val, C_32, C1_64, C2_64, C3_64) \ | 53 #define X(val, C_32, C1_64, C2_64, C3_64) \ |
| 132 { CondX86::C1_64, CondX86::C2_64, CondX86::C3_64 } \ | 54 { \ |
| 55 X8632::Traits::Cond::C1_64, X8632::Traits::Cond::C2_64, \ |
| 56 X8632::Traits::Cond::C3_64 \ |
| 57 } \ |
| 133 , | 58 , |
| 134 ICMPX8632_TABLE | 59 ICMPX8632_TABLE |
| 135 #undef X | 60 #undef X |
| 136 }; | 61 }; |
| 137 | 62 |
| 138 const size_t MachineTraits<TargetX8632>::TableIcmp64Size = | 63 const size_t MachineTraits<TargetX8632>::TableIcmp64Size = |
| 139 llvm::array_lengthof(TableIcmp64); | 64 llvm::array_lengthof(TableIcmp64); |
| 140 | 65 |
| 141 const MachineTraits<TargetX8632>::TableTypeX8632AttributesType | 66 const MachineTraits<TargetX8632>::TableTypeX8632AttributesType |
| 142 MachineTraits<TargetX8632>::TableTypeX8632Attributes[] = { | 67 MachineTraits<TargetX8632>::TableTypeX8632Attributes[] = { |
| 143 #define X(tag, elementty, cvt, sdss, pack, width, fld) \ | 68 #define X(tag, elementty, cvt, sdss, pack, width, fld) \ |
| 144 { elementty } \ | 69 { elementty } \ |
| 145 , | 70 , |
| 146 ICETYPEX8632_TABLE | 71 ICETYPEX8632_TABLE |
| 147 #undef X | 72 #undef X |
| 148 }; | 73 }; |
| 149 | 74 |
| 150 const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize = | 75 const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize = |
| 151 llvm::array_lengthof(TableTypeX8632Attributes); | 76 llvm::array_lengthof(TableTypeX8632Attributes); |
| 152 | 77 |
| 153 const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16; | 78 const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16; |
| 79 |
| 154 } // end of namespace X86Internal | 80 } // end of namespace X86Internal |
| 155 | 81 |
| 156 TargetX8632 *TargetX8632::create(Cfg *Func) { | 82 TargetX8632 *TargetX8632::create(Cfg *Func) { |
| 157 return X86Internal::TargetX86Base<TargetX8632>::create(Func); | 83 return X86Internal::TargetX86Base<TargetX8632>::create(Func); |
| 158 } | 84 } |
| 159 | 85 |
| 160 TargetDataX8632::TargetDataX8632(GlobalContext *Ctx) | 86 TargetDataX8632::TargetDataX8632(GlobalContext *Ctx) |
| 161 : TargetDataLowering(Ctx) {} | 87 : TargetDataLowering(Ctx) {} |
| 162 | 88 |
| 163 namespace { | 89 namespace { |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 // entries in case the high-level table has extra entries. | 349 // entries in case the high-level table has extra entries. |
| 424 #define X(tag, size, align, elts, elty, str) \ | 350 #define X(tag, size, align, elts, elty, str) \ |
| 425 static_assert(_table1_##tag == _table2_##tag, \ | 351 static_assert(_table1_##tag == _table2_##tag, \ |
| 426 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); | 352 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); |
| 427 ICETYPE_TABLE | 353 ICETYPE_TABLE |
| 428 #undef X | 354 #undef X |
| 429 } // end of namespace dummy3 | 355 } // end of namespace dummy3 |
| 430 } // end of anonymous namespace | 356 } // end of anonymous namespace |
| 431 | 357 |
| 432 } // end of namespace Ice | 358 } // end of namespace Ice |
| OLD | NEW |