Chromium Code Reviews| 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 // |
|
jvoung (off chromium)
2015/06/30 21:19:48
Add boilerplate?
// This file is distributed unde
John
2015/06/30 21:42:00
Done.
| |
| 5 //===----------------------------------------------------------------------===// | 5 //===----------------------------------------------------------------------===// |
| 6 // | 6 // |
| 7 // This file implements the TargetLoweringX8632 class, which | 7 // This file implements the TargetLoweringX8632 class, which |
| 8 // consists almost entirely of the lowering sequence for each | 8 // consists almost entirely of the lowering sequence for each |
| 9 // high-level instruction. | 9 // high-level instruction. |
| 10 // | 10 // |
| 11 //===----------------------------------------------------------------------===// | 11 //===----------------------------------------------------------------------===// |
| 12 | 12 |
| 13 #include "IceTargetLoweringX8632.h" | 13 #include "IceTargetLoweringX8632.h" |
| 14 | 14 |
| 15 #include "IceTargetLoweringX8632Traits.h" | |
| 15 #include "IceTargetLoweringX86Base.h" | 16 #include "IceTargetLoweringX86Base.h" |
| 16 | 17 |
| 17 namespace Ice { | 18 namespace Ice { |
| 19 | |
| 18 namespace X86Internal { | 20 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 | 21 const MachineTraits<TargetX8632>::TableFcmpType |
| 106 MachineTraits<TargetX8632>::TableFcmp[] = { | 22 MachineTraits<TargetX8632>::TableFcmp[] = { |
| 107 #define X(val, dflt, swapS, C1, C2, swapV, pred) \ | 23 #define X(val, dflt, swapS, C1, C2, swapV, pred) \ |
| 108 { dflt, swapS, CondX86::C1, CondX86::C2, swapV, CondX86::pred } \ | 24 { \ |
| 25 dflt, swapS, X8632::Traits::Cond::C1, X8632::Traits::Cond::C2, swapV, \ | |
| 26 X8632::Traits::Cond::pred \ | |
| 27 } \ | |
| 109 , | 28 , |
| 110 FCMPX8632_TABLE | 29 FCMPX8632_TABLE |
| 111 #undef X | 30 #undef X |
| 112 }; | 31 }; |
| 113 | 32 |
| 114 const size_t MachineTraits<TargetX8632>::TableFcmpSize = | 33 const size_t MachineTraits<TargetX8632>::TableFcmpSize = |
| 115 llvm::array_lengthof(TableFcmp); | 34 llvm::array_lengthof(TableFcmp); |
| 116 | 35 |
| 117 const MachineTraits<TargetX8632>::TableIcmp32Type | 36 const MachineTraits<TargetX8632>::TableIcmp32Type |
| 118 MachineTraits<TargetX8632>::TableIcmp32[] = { | 37 MachineTraits<TargetX8632>::TableIcmp32[] = { |
| 119 #define X(val, C_32, C1_64, C2_64, C3_64) \ | 38 #define X(val, C_32, C1_64, C2_64, C3_64) \ |
| 120 { CondX86::C_32 } \ | 39 { X8632::Traits::Cond::C_32 } \ |
| 121 , | 40 , |
| 122 ICMPX8632_TABLE | 41 ICMPX8632_TABLE |
| 123 #undef X | 42 #undef X |
| 124 }; | 43 }; |
| 125 | 44 |
| 126 const size_t MachineTraits<TargetX8632>::TableIcmp32Size = | 45 const size_t MachineTraits<TargetX8632>::TableIcmp32Size = |
| 127 llvm::array_lengthof(TableIcmp32); | 46 llvm::array_lengthof(TableIcmp32); |
| 128 | 47 |
| 129 const MachineTraits<TargetX8632>::TableIcmp64Type | 48 const MachineTraits<TargetX8632>::TableIcmp64Type |
| 130 MachineTraits<TargetX8632>::TableIcmp64[] = { | 49 MachineTraits<TargetX8632>::TableIcmp64[] = { |
| 131 #define X(val, C_32, C1_64, C2_64, C3_64) \ | 50 #define X(val, C_32, C1_64, C2_64, C3_64) \ |
| 132 { CondX86::C1_64, CondX86::C2_64, CondX86::C3_64 } \ | 51 { \ |
| 52 X8632::Traits::Cond::C1_64, X8632::Traits::Cond::C2_64, \ | |
| 53 X8632::Traits::Cond::C3_64 \ | |
| 54 } \ | |
| 133 , | 55 , |
| 134 ICMPX8632_TABLE | 56 ICMPX8632_TABLE |
| 135 #undef X | 57 #undef X |
| 136 }; | 58 }; |
| 137 | 59 |
| 138 const size_t MachineTraits<TargetX8632>::TableIcmp64Size = | 60 const size_t MachineTraits<TargetX8632>::TableIcmp64Size = |
| 139 llvm::array_lengthof(TableIcmp64); | 61 llvm::array_lengthof(TableIcmp64); |
| 140 | 62 |
| 141 const MachineTraits<TargetX8632>::TableTypeX8632AttributesType | 63 const MachineTraits<TargetX8632>::TableTypeX8632AttributesType |
| 142 MachineTraits<TargetX8632>::TableTypeX8632Attributes[] = { | 64 MachineTraits<TargetX8632>::TableTypeX8632Attributes[] = { |
| 143 #define X(tag, elementty, cvt, sdss, pack, width, fld) \ | 65 #define X(tag, elementty, cvt, sdss, pack, width, fld) \ |
| 144 { elementty } \ | 66 { elementty } \ |
| 145 , | 67 , |
| 146 ICETYPEX8632_TABLE | 68 ICETYPEX8632_TABLE |
| 147 #undef X | 69 #undef X |
| 148 }; | 70 }; |
| 149 | 71 |
| 150 const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize = | 72 const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize = |
| 151 llvm::array_lengthof(TableTypeX8632Attributes); | 73 llvm::array_lengthof(TableTypeX8632Attributes); |
| 152 | 74 |
| 153 const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16; | 75 const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16; |
| 76 | |
| 154 } // end of namespace X86Internal | 77 } // end of namespace X86Internal |
| 155 | 78 |
| 156 TargetX8632 *TargetX8632::create(Cfg *Func) { | 79 TargetX8632 *TargetX8632::create(Cfg *Func) { |
| 157 return X86Internal::TargetX86Base<TargetX8632>::create(Func); | 80 return X86Internal::TargetX86Base<TargetX8632>::create(Func); |
| 158 } | 81 } |
| 159 | 82 |
| 160 TargetDataX8632::TargetDataX8632(GlobalContext *Ctx) | 83 TargetDataX8632::TargetDataX8632(GlobalContext *Ctx) |
| 161 : TargetDataLowering(Ctx) {} | 84 : TargetDataLowering(Ctx) {} |
| 162 | 85 |
| 163 namespace { | 86 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. | 346 // entries in case the high-level table has extra entries. |
| 424 #define X(tag, size, align, elts, elty, str) \ | 347 #define X(tag, size, align, elts, elty, str) \ |
| 425 static_assert(_table1_##tag == _table2_##tag, \ | 348 static_assert(_table1_##tag == _table2_##tag, \ |
| 426 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); | 349 "Inconsistency between ICETYPEX8632_TABLE and ICETYPE_TABLE"); |
| 427 ICETYPE_TABLE | 350 ICETYPE_TABLE |
| 428 #undef X | 351 #undef X |
| 429 } // end of namespace dummy3 | 352 } // end of namespace dummy3 |
| 430 } // end of anonymous namespace | 353 } // end of anonymous namespace |
| 431 | 354 |
| 432 } // end of namespace Ice | 355 } // end of namespace Ice |
| OLD | NEW |