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 | 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 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 // Stack alignment | 129 // Stack alignment |
130 const uint32_t X86_STACK_ALIGNMENT_BYTES = 16; | 130 const uint32_t X86_STACK_ALIGNMENT_BYTES = 16; |
131 // Size of the return address on the stack | 131 // Size of the return address on the stack |
132 const uint32_t X86_RET_IP_SIZE_BYTES = 4; | 132 const uint32_t X86_RET_IP_SIZE_BYTES = 4; |
133 // The base 2 logarithm of the width in bytes of the smallest stack slot | 133 // The base 2 logarithm of the width in bytes of the smallest stack slot |
134 const uint32_t X86_LOG2_OF_MIN_STACK_SLOT_SIZE = 2; | 134 const uint32_t X86_LOG2_OF_MIN_STACK_SLOT_SIZE = 2; |
135 // The base 2 logarithm of the width in bytes of the largest stack slot | 135 // The base 2 logarithm of the width in bytes of the largest stack slot |
136 const uint32_t X86_LOG2_OF_MAX_STACK_SLOT_SIZE = 4; | 136 const uint32_t X86_LOG2_OF_MAX_STACK_SLOT_SIZE = 4; |
137 // The number of different NOP instructions | 137 // The number of different NOP instructions |
138 const uint32_t X86_NUM_NOP_VARIANTS = 5; | 138 const uint32_t X86_NUM_NOP_VARIANTS = 5; |
| 139 // Randomize integer immediates at least 2 bytes in size. |
| 140 const uint64_t X86_INT_IMMEDIATE_RANDOMIZATION_THRESHOLD = 0xffff; |
139 | 141 |
140 // Value and Alignment are in bytes. Return Value adjusted to the next | 142 // Value and Alignment are in bytes. Return Value adjusted to the next |
141 // highest multiple of Alignment. | 143 // highest multiple of Alignment. |
142 uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) { | 144 uint32_t applyAlignment(uint32_t Value, uint32_t Alignment) { |
143 // power of 2 | 145 // power of 2 |
144 assert((Alignment & (Alignment - 1)) == 0); | 146 assert((Alignment & (Alignment - 1)) == 0); |
145 return (Value + Alignment - 1) & -Alignment; | 147 return (Value + Alignment - 1) & -Alignment; |
146 } | 148 } |
147 | 149 |
148 // Value is in bytes. Return Value adjusted to the next highest multiple | 150 // Value is in bytes. Return Value adjusted to the next highest multiple |
149 // of the stack alignment. | 151 // of the stack alignment. |
150 uint32_t applyStackAlignment(uint32_t Value) { | 152 uint32_t applyStackAlignment(uint32_t Value) { |
151 return applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); | 153 return applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES); |
152 } | 154 } |
153 | 155 |
| 156 // This gives a name to the immediate so it can be identified as a |
| 157 // constant pool entry. |
| 158 IceString nameImmediate(Constant *Immediate) { |
| 159 bool IsRelocatable = llvm::isa<ConstantRelocatable>(Immediate); |
| 160 IceString Name; |
| 161 llvm::raw_string_ostream NameBuf(Name); |
| 162 NameBuf << (IsRelocatable ? "L$__reloc" : "L$") << Immediate->getType() << "$" |
| 163 << Immediate->getPoolEntryID(); |
| 164 return NameBuf.str(); |
| 165 } |
| 166 |
154 // Instruction set options | 167 // Instruction set options |
155 namespace cl = ::llvm::cl; | 168 namespace cl = ::llvm::cl; |
156 cl::opt<TargetX8632::X86InstructionSet> CLInstructionSet( | 169 cl::opt<TargetX8632::X86InstructionSet> CLInstructionSet( |
157 "mattr", cl::desc("X86 target attributes"), | 170 "mattr", cl::desc("X86 target attributes"), |
158 cl::init(TargetX8632::SSE2), | 171 cl::init(TargetX8632::SSE2), |
159 cl::values( | 172 cl::values( |
160 clEnumValN(TargetX8632::SSE2, "sse2", | 173 clEnumValN(TargetX8632::SSE2, "sse2", |
161 "Enable SSE2 instructions (default)"), | 174 "Enable SSE2 instructions (default)"), |
162 clEnumValN(TargetX8632::SSE4_1, "sse4.1", | 175 clEnumValN(TargetX8632::SSE4_1, "sse4.1", |
163 "Enable SSE 4.1 instructions"), clEnumValEnd)); | 176 "Enable SSE 4.1 instructions"), clEnumValEnd)); |
164 | 177 |
| 178 enum RandomizeImmediates { |
| 179 Randomize_None, |
| 180 Randomize_ConstantBlinding, |
| 181 Randomize_ConstantPooling |
| 182 }; |
| 183 |
| 184 cl::opt<RandomizeImmediates> CLRandomizeImmediates( |
| 185 "randomize-immediates", |
| 186 cl::desc("Randomize the representation of immediates"), |
| 187 cl::init(Randomize_None), |
| 188 cl::values(clEnumValN(Randomize_None, "none", "Don't randomize (default)"), |
| 189 clEnumValN(Randomize_ConstantBlinding, "constant-blinding", |
| 190 "Use constant blinding"), |
| 191 clEnumValN(Randomize_ConstantPooling, "constant-pooling", |
| 192 "Use constant pooling"), |
| 193 clEnumValEnd)); |
| 194 |
| 195 bool immediateShouldBeRandomized(Operand *Immediate) { |
| 196 if (!CLRandomizeImmediates) |
| 197 return false; |
| 198 if (ConstantInteger *ConstInt = |
| 199 llvm::dyn_cast_or_null<ConstantInteger>(Immediate)) { |
| 200 // i64 should have been split at this point. |
| 201 assert(ConstInt->getType() != IceType_i64); |
| 202 return ConstInt->getType() == IceType_i32 && |
| 203 (ConstInt->getValue() + |
| 204 X86_INT_IMMEDIATE_RANDOMIZATION_THRESHOLD / 2) >= |
| 205 X86_INT_IMMEDIATE_RANDOMIZATION_THRESHOLD; |
| 206 } |
| 207 return false; |
| 208 } |
| 209 |
| 210 // Return a string representation of the type that is suitable for use |
| 211 // in an identifier. |
| 212 IceString typeIdentString(const Type Ty) { |
| 213 IceString Str; |
| 214 llvm::raw_string_ostream BaseOS(Str); |
| 215 if (isVectorType(Ty)) { |
| 216 BaseOS << "v" << typeNumElements(Ty) << typeElementType(Ty); |
| 217 } else { |
| 218 BaseOS << Ty; |
| 219 } |
| 220 return BaseOS.str(); |
| 221 } |
| 222 |
165 // In some cases, there are x-macros tables for both high-level and | 223 // In some cases, there are x-macros tables for both high-level and |
166 // low-level instructions/operands that use the same enum key value. | 224 // low-level instructions/operands that use the same enum key value. |
167 // The tables are kept separate to maintain a proper separation | 225 // The tables are kept separate to maintain a proper separation |
168 // between abstraction layers. There is a risk that the tables | 226 // between abstraction layers. There is a risk that the tables |
169 // could get out of sync if enum values are reordered or if entries | 227 // could get out of sync if enum values are reordered or if entries |
170 // are added or deleted. This dummy function uses static_assert to | 228 // are added or deleted. This dummy function uses static_assert to |
171 // ensure everything is kept in sync. | 229 // ensure everything is kept in sync. |
172 void __attribute__((unused)) xMacroIntegrityCheck() { | 230 void __attribute__((unused)) xMacroIntegrityCheck() { |
173 // Validate the enum values in FCMPX8632_TABLE. | 231 // Validate the enum values in FCMPX8632_TABLE. |
174 { | 232 { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 #undef X | 314 #undef X |
257 } | 315 } |
258 } | 316 } |
259 | 317 |
260 } // end of anonymous namespace | 318 } // end of anonymous namespace |
261 | 319 |
262 TargetX8632::TargetX8632(Cfg *Func) | 320 TargetX8632::TargetX8632(Cfg *Func) |
263 : TargetLowering(Func), InstructionSet(CLInstructionSet), | 321 : TargetLowering(Func), InstructionSet(CLInstructionSet), |
264 IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0), | 322 IsEbpBasedFrame(false), NeedsStackAlignment(false), FrameSizeLocals(0), |
265 SpillAreaSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false), | 323 SpillAreaSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false), |
266 PhysicalRegisters(VarList(Reg_NUM)) { | 324 PhysicalRegisters(VarList(Reg_NUM)), |
| 325 ConstantBlindingCookieInitialized(false), ConstantBlindingCookie(0) { |
267 // TODO: Don't initialize IntegerRegisters and friends every time. | 326 // TODO: Don't initialize IntegerRegisters and friends every time. |
268 // Instead, initialize in some sort of static initializer for the | 327 // Instead, initialize in some sort of static initializer for the |
269 // class. | 328 // class. |
270 llvm::SmallBitVector IntegerRegisters(Reg_NUM); | 329 llvm::SmallBitVector IntegerRegisters(Reg_NUM); |
271 llvm::SmallBitVector IntegerRegistersI8(Reg_NUM); | 330 llvm::SmallBitVector IntegerRegistersI8(Reg_NUM); |
272 llvm::SmallBitVector FloatRegisters(Reg_NUM); | 331 llvm::SmallBitVector FloatRegisters(Reg_NUM); |
273 llvm::SmallBitVector VectorRegisters(Reg_NUM); | 332 llvm::SmallBitVector VectorRegisters(Reg_NUM); |
274 llvm::SmallBitVector InvalidRegisters(Reg_NUM); | 333 llvm::SmallBitVector InvalidRegisters(Reg_NUM); |
275 ScratchRegs.resize(Reg_NUM); | 334 ScratchRegs.resize(Reg_NUM); |
276 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ | 335 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 1035 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
977 assert(CharsPrinted >= 0 && | 1036 assert(CharsPrinted >= 0 && |
978 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 1037 (size_t)CharsPrinted < llvm::array_lengthof(buf)); |
979 (void)CharsPrinted; // avoid warnings if asserts are disabled | 1038 (void)CharsPrinted; // avoid warnings if asserts are disabled |
980 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; | 1039 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; |
981 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " | 1040 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " |
982 << Value << "\n"; | 1041 << Value << "\n"; |
983 } | 1042 } |
984 } | 1043 } |
985 | 1044 |
| 1045 void TargetX8632::emitPooledImmediates() const { |
| 1046 Ostream &Str = Ctx->getStrEmit(); |
| 1047 SizeT Align = typeWidthInBytesOnStack(IceType_i32); |
| 1048 // TODO: Determine the right directives to place here. |
| 1049 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align |
| 1050 << "\n"; |
| 1051 Str << "\t.align\t" << Align << "\n"; |
| 1052 ConstantList PooledImmediates = Ctx->getImmediatePool(); |
| 1053 for (ConstantList::const_iterator I = PooledImmediates.begin(), |
| 1054 E = PooledImmediates.end(); |
| 1055 I != E; ++I) { |
| 1056 Constant *Value = *I; |
| 1057 IceString Name = nameImmediate(Value); |
| 1058 Str << Name << ":\n"; |
| 1059 if (ConstantInteger *Int = llvm::dyn_cast<ConstantInteger>(Value)) { |
| 1060 assert(Int->getType() == IceType_i32); |
| 1061 char buf[30]; |
| 1062 int CharsPrinted = snprintf(buf, llvm::array_lengthof(buf), "0x%x", |
| 1063 (uint32_t)Int->getValue()); |
| 1064 assert(CharsPrinted >= 0 && |
| 1065 (size_t)CharsPrinted < llvm::array_lengthof(buf)); |
| 1066 Str << "\t.long\t" << buf << "\n"; |
| 1067 } else if (ConstantRelocatable *Reloc = |
| 1068 llvm::dyn_cast<ConstantRelocatable>(Value)) { |
| 1069 Str << "\t.long\t"; |
| 1070 Reloc->emit(Ctx); |
| 1071 Str << "\n"; |
| 1072 } |
| 1073 } |
| 1074 } |
| 1075 |
986 void TargetX8632::emitConstants() const { | 1076 void TargetX8632::emitConstants() const { |
987 emitConstantPool<PoolTypeConverter<float> >(); | 1077 emitConstantPool<PoolTypeConverter<float> >(); |
988 emitConstantPool<PoolTypeConverter<double> >(); | 1078 emitConstantPool<PoolTypeConverter<double> >(); |
| 1079 emitPooledImmediates(); |
989 | 1080 |
990 // No need to emit constants from the int pool since (for x86) they | 1081 // No need to emit constants from the int pool since (for x86) they |
991 // are embedded as immediates in the instructions. | 1082 // are embedded as immediates in the instructions. |
992 } | 1083 } |
993 | 1084 |
994 void TargetX8632::split64(Variable *Var) { | 1085 void TargetX8632::split64(Variable *Var) { |
995 switch (Var->getType()) { | 1086 switch (Var->getType()) { |
996 default: | 1087 default: |
997 return; | 1088 return; |
998 case IceType_i64: | 1089 case IceType_i64: |
(...skipping 2802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3801 _br(InstX8632Br::Br_ne, Label); | 3892 _br(InstX8632Br::Br_ne, Label); |
3802 Context.insert(InstFakeUse::create(Func, DestLo)); | 3893 Context.insert(InstFakeUse::create(Func, DestLo)); |
3803 Context.insert(InstFakeUse::create(Func, DestHi)); | 3894 Context.insert(InstFakeUse::create(Func, DestHi)); |
3804 Operand *SrcFLo = loOperand(SrcF); | 3895 Operand *SrcFLo = loOperand(SrcF); |
3805 Operand *SrcFHi = hiOperand(SrcF); | 3896 Operand *SrcFHi = hiOperand(SrcF); |
3806 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); | 3897 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); |
3807 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); | 3898 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); |
3808 _mov(DestLo, SrcLoRI); | 3899 _mov(DestLo, SrcLoRI); |
3809 _mov(DestHi, SrcHiRI); | 3900 _mov(DestHi, SrcHiRI); |
3810 } else { | 3901 } else { |
| 3902 // Call legalize() before _cmp, since legalize() may modify flags. |
| 3903 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); |
3811 _cmp(ConditionRMI, Zero); | 3904 _cmp(ConditionRMI, Zero); |
3812 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); | |
3813 _mov(Dest, SrcT); | 3905 _mov(Dest, SrcT); |
3814 _br(InstX8632Br::Br_ne, Label); | 3906 _br(InstX8632Br::Br_ne, Label); |
3815 Context.insert(InstFakeUse::create(Func, Dest)); | 3907 Context.insert(InstFakeUse::create(Func, Dest)); |
3816 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); | 3908 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); |
3817 _mov(Dest, SrcF); | 3909 _mov(Dest, SrcF); |
3818 } | 3910 } |
3819 | 3911 |
3820 Context.insert(Label); | 3912 Context.insert(Label); |
3821 } | 3913 } |
3822 | 3914 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4020 Type Ty = Src->getType(); | 4112 Type Ty = Src->getType(); |
4021 Variable *Reg = makeReg(Ty, RegNum); | 4113 Variable *Reg = makeReg(Ty, RegNum); |
4022 if (isVectorType(Ty)) { | 4114 if (isVectorType(Ty)) { |
4023 _movp(Reg, Src); | 4115 _movp(Reg, Src); |
4024 } else { | 4116 } else { |
4025 _mov(Reg, Src); | 4117 _mov(Reg, Src); |
4026 } | 4118 } |
4027 return Reg; | 4119 return Reg; |
4028 } | 4120 } |
4029 | 4121 |
| 4122 // Insert code to randomize the representation of the immediate. Return |
| 4123 // a register that holds the (derandomized) value of the immediate. |
| 4124 // WARNING: Constant blinding overwrites the flags register. |
| 4125 Variable *TargetX8632::randomizeImmediate(Constant *Immediate) { |
| 4126 assert(llvm::isa<ConstantInteger>(Immediate) || |
| 4127 llvm::isa<ConstantRelocatable>(Immediate)); |
| 4128 |
| 4129 if (CLRandomizeImmediates == Randomize_None) |
| 4130 return legalizeToVar(Immediate); |
| 4131 |
| 4132 Variable *Dest = makeReg(Immediate->getType()); |
| 4133 |
| 4134 if (CLRandomizeImmediates == Randomize_ConstantPooling) { |
| 4135 const Type Ty = Immediate->getType(); |
| 4136 const int64_t Offset = 0; |
| 4137 const IceString Name = nameImmediate(Immediate); |
| 4138 const bool SuppressMangling = true; |
| 4139 Ctx->addConstantPooledImmediate(Name, Immediate); |
| 4140 Constant *Sym = Ctx->getConstantSym(Ty, Offset, Name, SuppressMangling); |
| 4141 // LEAHACK: Once a proper assembler is used, change this to be |
| 4142 // mov Dest, [Sym]. |
| 4143 _mov(Dest, OperandX8632Mem::create(Func, Ty, NULL, Sym)); |
| 4144 } else { |
| 4145 assert(CLRandomizeImmediates == Randomize_ConstantBlinding); |
| 4146 // Mask integer immediates with a random XOR key. |
| 4147 ConstantInteger *IntegerImmediate = llvm::cast<ConstantInteger>(Immediate); |
| 4148 assert(IntegerImmediate->getType() != IceType_i64); |
| 4149 uint64_t Value = IntegerImmediate->getValue(); |
| 4150 if (!ConstantBlindingCookieInitialized) { |
| 4151 RandomNumberGeneratorWrapper RNG(Ctx->getRNG()); |
| 4152 ConstantBlindingCookie = |
| 4153 RNG.next((uint64_t)std::numeric_limits<uint32_t>::max() + 1); |
| 4154 ConstantBlindingCookieInitialized = true; |
| 4155 } |
| 4156 uint32_t Mask1 = ConstantBlindingCookie; |
| 4157 uint32_t Mask2 = Mask1 ^ Value; |
| 4158 _mov(Dest, Ctx->getConstantInt(IceType_i32, Mask1)); |
| 4159 _xor(Dest, Ctx->getConstantInt(IceType_i32, Mask2)); |
| 4160 } |
| 4161 |
| 4162 return Dest; |
| 4163 } |
| 4164 |
4030 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, | 4165 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, |
4031 bool AllowOverlap, int32_t RegNum) { | 4166 bool AllowOverlap, int32_t RegNum) { |
4032 // Assert that a physical register is allowed. To date, all calls | 4167 // Assert that a physical register is allowed. To date, all calls |
4033 // to legalize() allow a physical register. If a physical register | 4168 // to legalize() allow a physical register. If a physical register |
4034 // needs to be explicitly disallowed, then new code will need to be | 4169 // needs to be explicitly disallowed, then new code will need to be |
4035 // written to force a spill. | 4170 // written to force a spill. |
4036 assert(Allowed & Legal_Reg); | 4171 assert(Allowed & Legal_Reg); |
4037 // If we're asking for a specific physical register, make sure we're | 4172 // If we're asking for a specific physical register, make sure we're |
4038 // not allowing any other operand kinds. (This could be future | 4173 // not allowing any other operand kinds. (This could be future |
4039 // work, e.g. allow the shl shift amount to be either an immediate | 4174 // work, e.g. allow the shl shift amount to be either an immediate |
4040 // or in ecx.) | 4175 // or in ecx.) |
4041 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); | 4176 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); |
4042 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { | 4177 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { |
4043 // Before doing anything with a Mem operand, we need to ensure | 4178 // Before doing anything with a Mem operand, we need to ensure |
4044 // that the Base and Index components are in physical registers. | 4179 // that the Base and Index components are in physical registers. |
4045 Variable *Base = Mem->getBase(); | 4180 Variable *Base = Mem->getBase(); |
4046 Variable *Index = Mem->getIndex(); | 4181 Variable *Index = Mem->getIndex(); |
| 4182 Constant *Offset = Mem->getOffset(); |
4047 Variable *RegBase = NULL; | 4183 Variable *RegBase = NULL; |
4048 Variable *RegIndex = NULL; | 4184 Variable *RegIndex = NULL; |
4049 if (Base) { | 4185 if (Base) { |
4050 RegBase = legalizeToVar(Base, true); | 4186 RegBase = legalizeToVar(Base, true); |
4051 } | 4187 } |
4052 if (Index) { | 4188 if (Index) { |
4053 RegIndex = legalizeToVar(Index, true); | 4189 RegIndex = legalizeToVar(Index, true); |
4054 } | 4190 } |
| 4191 |
| 4192 if (immediateShouldBeRandomized(Offset)) { |
| 4193 // lea new_base [base + randomize(offset)] |
| 4194 Variable *RegOffset = randomizeImmediate(Offset); |
| 4195 OperandX8632Mem *NewBaseAddr = OperandX8632Mem::create( |
| 4196 Func, Mem->getType(), RegBase, NULL, RegOffset, 0); |
| 4197 Variable *NewBase = makeReg(IceType_i32); |
| 4198 _lea(NewBase, NewBaseAddr); |
| 4199 RegBase = NewBase; |
| 4200 Offset = NULL; |
| 4201 } |
| 4202 |
4055 if (Base != RegBase || Index != RegIndex) { | 4203 if (Base != RegBase || Index != RegIndex) { |
4056 From = OperandX8632Mem::create( | 4204 From = OperandX8632Mem::create(Func, Mem->getType(), RegBase, Offset, |
4057 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, | 4205 RegIndex, Mem->getShift(), |
4058 Mem->getShift(), Mem->getSegmentRegister()); | 4206 Mem->getSegmentRegister()); |
4059 } | 4207 } |
4060 | 4208 |
4061 if (!(Allowed & Legal_Mem)) { | 4209 if (!(Allowed & Legal_Mem)) { |
4062 From = copyToReg(From, RegNum); | 4210 From = copyToReg(From, RegNum); |
4063 } | 4211 } |
4064 return From; | 4212 return From; |
4065 } | 4213 } |
4066 if (llvm::isa<Constant>(From)) { | 4214 if (llvm::isa<Constant>(From)) { |
4067 if (llvm::isa<ConstantUndef>(From)) { | 4215 if (llvm::isa<ConstantUndef>(From)) { |
4068 // Lower undefs to zero. Another option is to lower undefs to an | 4216 // Lower undefs to zero. Another option is to lower undefs to an |
4069 // uninitialized register; however, using an uninitialized register | 4217 // uninitialized register; however, using an uninitialized register |
4070 // results in less predictable code. | 4218 // results in less predictable code. |
4071 // | 4219 // |
4072 // If in the future the implementation is changed to lower undef | 4220 // If in the future the implementation is changed to lower undef |
4073 // values to uninitialized registers, a FakeDef will be needed: | 4221 // values to uninitialized registers, a FakeDef will be needed: |
4074 // Context.insert(InstFakeDef::create(Func, Reg)); | 4222 // Context.insert(InstFakeDef::create(Func, Reg)); |
4075 // This is in order to ensure that the live range of Reg is not | 4223 // This is in order to ensure that the live range of Reg is not |
4076 // overestimated. If the constant being lowered is a 64 bit value, | 4224 // overestimated. If the constant being lowered is a 64 bit value, |
4077 // then the result should be split and the lo and hi components will | 4225 // then the result should be split and the lo and hi components will |
4078 // need to go in uninitialized registers. | 4226 // need to go in uninitialized registers. |
4079 if (isVectorType(From->getType())) | 4227 if (isVectorType(From->getType())) |
4080 return makeVectorOfZeros(From->getType()); | 4228 return makeVectorOfZeros(From->getType()); |
4081 From = Ctx->getConstantZero(From->getType()); | 4229 From = Ctx->getConstantZero(From->getType()); |
4082 } | 4230 } |
4083 // There should be no constants of vector type (other than undef). | 4231 // There should be no constants of vector type (other than undef). |
4084 assert(!isVectorType(From->getType())); | 4232 assert(!isVectorType(From->getType())); |
| 4233 |
| 4234 if (immediateShouldBeRandomized(From)) { |
| 4235 return randomizeImmediate(llvm::cast<Constant>(From)); |
| 4236 } |
| 4237 |
4085 bool NeedsReg = false; | 4238 bool NeedsReg = false; |
4086 if (!(Allowed & Legal_Imm)) | 4239 if (!(Allowed & Legal_Imm)) |
4087 // Immediate specifically not allowed | 4240 // Immediate specifically not allowed |
4088 NeedsReg = true; | 4241 NeedsReg = true; |
4089 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper | 4242 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper |
4090 // emitter is used. | 4243 // emitter is used. |
4091 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) | 4244 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) |
4092 // Relocatable specifically not allowed | 4245 // Relocatable specifically not allowed |
4093 NeedsReg = true; | 4246 NeedsReg = true; |
4094 if (!(Allowed & Legal_Mem) && | 4247 if (!(Allowed & Legal_Mem) && |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4336 Str << "\t.align\t" << Align << "\n"; | 4489 Str << "\t.align\t" << Align << "\n"; |
4337 Str << MangledName << ":\n"; | 4490 Str << MangledName << ":\n"; |
4338 for (SizeT i = 0; i < Size; ++i) { | 4491 for (SizeT i = 0; i < Size; ++i) { |
4339 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4492 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
4340 } | 4493 } |
4341 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4494 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
4342 } | 4495 } |
4343 } | 4496 } |
4344 | 4497 |
4345 } // end of namespace Ice | 4498 } // end of namespace Ice |
OLD | NEW |