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 // |
| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 121 } | 121 } |
| 122 | 122 |
| 123 // The maximum number of arguments to pass in XMM registers | 123 // The maximum number of arguments to pass in XMM registers |
| 124 const uint32_t X86_MAX_XMM_ARGS = 4; | 124 const uint32_t X86_MAX_XMM_ARGS = 4; |
| 125 // The number of bits in a byte | 125 // The number of bits in a byte |
| 126 const uint32_t X86_CHAR_BIT = 8; | 126 const uint32_t X86_CHAR_BIT = 8; |
| 127 // Stack alignment | 127 // Stack alignment |
| 128 const uint32_t X86_STACK_ALIGNMENT_BYTES = 16; | 128 const uint32_t X86_STACK_ALIGNMENT_BYTES = 16; |
| 129 // Size of the return address on the stack | 129 // Size of the return address on the stack |
| 130 const uint32_t X86_RET_IP_SIZE_BYTES = 4; | 130 const uint32_t X86_RET_IP_SIZE_BYTES = 4; |
| 131 // Randomize integer immediates at least 2 bytes in size. | |
| 132 const uint64_t X86_INT_IMMEDIATE_RANDOMIZATION_THRESHOLD = 65536; | |
|
JF
2014/08/12 05:37:47
I find 0xFFFF more readable.
wala
2014/08/16 00:07:13
Done.
| |
| 131 | 133 |
| 132 // Value is a size in bytes. Return Value adjusted to the next highest | 134 // Value is a size in bytes. Return Value adjusted to the next highest |
| 133 // multiple of the stack alignment. | 135 // multiple of the stack alignment. |
| 134 uint32_t applyStackAlignment(uint32_t Value) { | 136 uint32_t applyStackAlignment(uint32_t Value) { |
| 135 // power of 2 | 137 // power of 2 |
| 136 assert((X86_STACK_ALIGNMENT_BYTES & (X86_STACK_ALIGNMENT_BYTES - 1)) == 0); | 138 assert((X86_STACK_ALIGNMENT_BYTES & (X86_STACK_ALIGNMENT_BYTES - 1)) == 0); |
| 137 return (Value + X86_STACK_ALIGNMENT_BYTES - 1) & -X86_STACK_ALIGNMENT_BYTES; | 139 return (Value + X86_STACK_ALIGNMENT_BYTES - 1) & -X86_STACK_ALIGNMENT_BYTES; |
| 138 } | 140 } |
| 139 | 141 |
| 142 bool immediateShouldBeRandomized(Operand *Immediate) { | |
| 143 if (!Immediate) { | |
| 144 return false; | |
| 145 } else if (llvm::isa<ConstantRelocatable>(Immediate)) { | |
|
Jim Stichnoth
2014/08/13 23:30:25
Remove "else" after "return".
wala
2014/08/16 00:07:12
Done.
| |
| 146 return true; | |
| 147 } else if (ConstantInteger *ConstInt = | |
| 148 llvm::dyn_cast<ConstantInteger>(Immediate)) { | |
| 149 return ConstInt->getType() != IceType_i64 && | |
|
JF
2014/08/12 05:37:47
Why not i64?
Jim Stichnoth
2014/08/13 23:30:25
i64 constants are split into i32 operations at thi
wala
2014/08/16 00:07:13
Done.
wala
2014/08/16 00:16:15
Hmm, it looks like some i64 "immediates" are reach
| |
| 150 ConstInt->getValue() >= X86_INT_IMMEDIATE_RANDOMIZATION_THRESHOLD; | |
|
Jim Stichnoth
2014/08/13 23:30:25
As we discussed offline, you probably want to add
| |
| 151 } else { | |
| 152 return false; | |
|
JF
2014/08/12 05:37:47
What about FP and vectors?
Jim Stichnoth
2014/08/13 23:30:26
FP and vector constants are always pooled, due to
| |
| 153 } | |
| 154 } | |
| 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 | |
| 140 // Instruction set options | 167 // Instruction set options |
| 141 namespace cl = ::llvm::cl; | 168 namespace cl = ::llvm::cl; |
| 142 cl::opt<TargetX8632::X86InstructionSet> CLInstructionSet( | 169 cl::opt<TargetX8632::X86InstructionSet> CLInstructionSet( |
| 143 "mattr", cl::desc("X86 target attributes"), | 170 "mattr", cl::desc("X86 target attributes"), |
| 144 cl::init(TargetX8632::SSE2), | 171 cl::init(TargetX8632::SSE2), |
| 145 cl::values( | 172 cl::values( |
| 146 clEnumValN(TargetX8632::SSE2, "sse2", | 173 clEnumValN(TargetX8632::SSE2, "sse2", |
| 147 "Enable SSE2 instructions (default)"), | 174 "Enable SSE2 instructions (default)"), |
| 148 clEnumValN(TargetX8632::SSE4_1, "sse4.1", | 175 clEnumValN(TargetX8632::SSE4_1, "sse4.1", |
| 149 "Enable SSE 4.1 instructions"), clEnumValEnd)); | 176 "Enable SSE 4.1 instructions"), clEnumValEnd)); |
| 150 | 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)); | |
|
JF
2014/08/12 05:37:47
Those should probably be composable.
Jim Stichnoth
2014/08/13 23:30:26
I didn't think it would add any more security to b
| |
| 194 | |
| 151 // Return a string representation of the type that is suitable for use | 195 // Return a string representation of the type that is suitable for use |
| 152 // in an identifier. | 196 // in an identifier. |
| 153 IceString typeIdentString(const Type Ty) { | 197 IceString typeIdentString(const Type Ty) { |
| 154 IceString Str; | 198 IceString Str; |
| 155 llvm::raw_string_ostream BaseOS(Str); | 199 llvm::raw_string_ostream BaseOS(Str); |
| 156 if (isVectorType(Ty)) { | 200 if (isVectorType(Ty)) { |
| 157 BaseOS << "v" << typeNumElements(Ty) << typeElementType(Ty); | 201 BaseOS << "v" << typeNumElements(Ty) << typeElementType(Ty); |
| 158 } else { | 202 } else { |
| 159 BaseOS << Ty; | 203 BaseOS << Ty; |
| 160 } | 204 } |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 896 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
| 853 assert(CharsPrinted >= 0 && | 897 assert(CharsPrinted >= 0 && |
| 854 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 898 (size_t)CharsPrinted < llvm::array_lengthof(buf)); |
| 855 (void)CharsPrinted; // avoid warnings if asserts are disabled | 899 (void)CharsPrinted; // avoid warnings if asserts are disabled |
| 856 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; | 900 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; |
| 857 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " | 901 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " |
| 858 << Value << "\n"; | 902 << Value << "\n"; |
| 859 } | 903 } |
| 860 } | 904 } |
| 861 | 905 |
| 906 void TargetX8632::emitPooledImmediates() const { | |
|
JF
2014/08/12 05:37:47
Are redundant pooled immediates pooled at the same
wala
2014/08/16 00:07:12
Right now, the implementation uses the Subzero con
| |
| 907 Ostream &Str = Ctx->getStrEmit(); | |
| 908 SizeT Align = typeWidthInBytesOnStack(IceType_i32); | |
| 909 // TODO: Determine the right directives to place here. | |
| 910 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | |
| 911 << "\n"; | |
| 912 Str << "\t.align\t" << Align << "\n"; | |
| 913 ConstantList PooledImmediates = Ctx->getImmediatePool(); | |
| 914 for (ConstantList::const_iterator I = PooledImmediates.begin(), | |
| 915 E = PooledImmediates.end(); I != E; ++I) { | |
| 916 Constant *Value = *I; | |
| 917 IceString Name = nameImmediate(Value); | |
| 918 Str << Name << ":\n"; | |
| 919 if (ConstantInteger *Int = llvm::dyn_cast<ConstantInteger>(Value)) { | |
| 920 assert(Int->getType() == IceType_i32); | |
| 921 char buf[30]; | |
| 922 int CharsPrinted = | |
| 923 snprintf(buf, llvm::array_lengthof(buf), "0x%x", | |
| 924 (uint32_t) Int->getValue()); | |
| 925 assert(CharsPrinted >= 0 && | |
| 926 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | |
| 927 Str << "\t.long\t" << buf << "\n"; | |
| 928 } else if (ConstantRelocatable *Reloc = | |
| 929 llvm::dyn_cast<ConstantRelocatable>(Value)) { | |
| 930 Str << "\t.long\t"; | |
| 931 Reloc->emit(Ctx); | |
| 932 Str << "\n"; | |
| 933 } | |
| 934 } | |
| 935 } | |
| 936 | |
| 862 void TargetX8632::emitConstants() const { | 937 void TargetX8632::emitConstants() const { |
| 863 emitConstantPool<PoolTypeConverter<float> >(); | 938 emitConstantPool<PoolTypeConverter<float> >(); |
| 864 emitConstantPool<PoolTypeConverter<double> >(); | 939 emitConstantPool<PoolTypeConverter<double> >(); |
| 940 emitPooledImmediates(); | |
| 865 | 941 |
| 866 // No need to emit constants from the int pool since (for x86) they | 942 // No need to emit constants from the int pool since (for x86) they |
| 867 // are embedded as immediates in the instructions. | 943 // are embedded as immediates in the instructions. |
| 868 } | 944 } |
| 869 | 945 |
| 870 void TargetX8632::split64(Variable *Var) { | 946 void TargetX8632::split64(Variable *Var) { |
| 871 switch (Var->getType()) { | 947 switch (Var->getType()) { |
| 872 default: | 948 default: |
| 873 return; | 949 return; |
| 874 case IceType_i64: | 950 case IceType_i64: |
| (...skipping 2839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3714 _br(InstX8632Br::Br_ne, Label); | 3790 _br(InstX8632Br::Br_ne, Label); |
| 3715 Context.insert(InstFakeUse::create(Func, DestLo)); | 3791 Context.insert(InstFakeUse::create(Func, DestLo)); |
| 3716 Context.insert(InstFakeUse::create(Func, DestHi)); | 3792 Context.insert(InstFakeUse::create(Func, DestHi)); |
| 3717 Operand *SrcFLo = loOperand(SrcF); | 3793 Operand *SrcFLo = loOperand(SrcF); |
| 3718 Operand *SrcFHi = hiOperand(SrcF); | 3794 Operand *SrcFHi = hiOperand(SrcF); |
| 3719 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); | 3795 SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm, true); |
| 3720 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); | 3796 SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm, true); |
| 3721 _mov(DestLo, SrcLoRI); | 3797 _mov(DestLo, SrcLoRI); |
| 3722 _mov(DestHi, SrcHiRI); | 3798 _mov(DestHi, SrcHiRI); |
| 3723 } else { | 3799 } else { |
| 3800 // Call legalize() before _cmp, since legalize() may modify flags. | |
| 3801 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); | |
| 3724 _cmp(ConditionRMI, Zero); | 3802 _cmp(ConditionRMI, Zero); |
| 3725 SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true); | |
| 3726 _mov(Dest, SrcT); | 3803 _mov(Dest, SrcT); |
| 3727 _br(InstX8632Br::Br_ne, Label); | 3804 _br(InstX8632Br::Br_ne, Label); |
| 3728 Context.insert(InstFakeUse::create(Func, Dest)); | 3805 Context.insert(InstFakeUse::create(Func, Dest)); |
| 3729 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); | 3806 SrcF = legalize(SrcF, Legal_Reg | Legal_Imm, true); |
| 3730 _mov(Dest, SrcF); | 3807 _mov(Dest, SrcF); |
| 3731 } | 3808 } |
| 3732 | 3809 |
| 3733 Context.insert(Label); | 3810 Context.insert(Label); |
| 3734 } | 3811 } |
| 3735 | 3812 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3933 Type Ty = Src->getType(); | 4010 Type Ty = Src->getType(); |
| 3934 Variable *Reg = makeReg(Ty, RegNum); | 4011 Variable *Reg = makeReg(Ty, RegNum); |
| 3935 if (isVectorType(Ty)) { | 4012 if (isVectorType(Ty)) { |
| 3936 _movp(Reg, Src); | 4013 _movp(Reg, Src); |
| 3937 } else { | 4014 } else { |
| 3938 _mov(Reg, Src); | 4015 _mov(Reg, Src); |
| 3939 } | 4016 } |
| 3940 return Reg; | 4017 return Reg; |
| 3941 } | 4018 } |
| 3942 | 4019 |
| 4020 // Insert code to randomize the representation of the immediate. Return | |
| 4021 // a register that holds the (derandomized) value of the immediate. | |
| 4022 // WARNING: Constant blinding overwrites the flags register. | |
|
JF
2014/08/12 05:37:47
Is that one random cookie per immediate, or one pe
wala
2014/08/16 00:07:13
One per immediate.
| |
| 4023 Variable *TargetX8632::randomizeImmediate(Constant *Immediate) { | |
| 4024 assert(llvm::isa<ConstantInteger>(Immediate) || | |
| 4025 llvm::isa<ConstantRelocatable>(Immediate)); | |
| 4026 | |
| 4027 if (CLRandomizeImmediates == Randomize_None) | |
| 4028 return legalizeToVar(Immediate); | |
| 4029 | |
| 4030 Variable *Dest = makeReg(Immediate->getType()); | |
| 4031 | |
| 4032 if (CLRandomizeImmediates == Randomize_ConstantPooling || | |
| 4033 llvm::isa<ConstantRelocatable>(Immediate)) { | |
| 4034 const Type Ty = Immediate->getType(); | |
| 4035 const int64_t Offset = 0; | |
| 4036 const IceString Name = nameImmediate(Immediate); | |
| 4037 const bool SuppressMangling = true; | |
| 4038 Ctx->addConstantPooledImmediate(Name, Immediate); | |
| 4039 Constant *Sym = Ctx->getConstantSym(Ty, Offset, Name, SuppressMangling); | |
| 4040 // LEAHACK: Once a proper assembler is used, change this to be | |
| 4041 // mov Dest, [Sym]. | |
| 4042 _mov(Dest, OperandX8632Mem::create(Func, Ty, NULL, Sym)); | |
| 4043 } else { | |
| 4044 assert(CLRandomizeImmediates == Randomize_ConstantBlinding); | |
| 4045 // Mask integer immediates with a random XOR key. | |
| 4046 ConstantInteger *IntegerImmediate = llvm::cast<ConstantInteger>(Immediate); | |
| 4047 assert(IntegerImmediate->getType() != IceType_i64); | |
| 4048 uint64_t Value = IntegerImmediate->getValue(); | |
| 4049 RandomNumberGenerator &RNG = Ctx->getRNG(); | |
|
Jim Stichnoth
2014/08/13 23:30:25
I think it should be one random cookie per functio
wala
2014/08/16 00:07:12
Done, no CSE yet.
| |
| 4050 uint32_t Mask1 = RNG.next((uint64_t)UINT32_MAX + 1); | |
|
JF
2014/08/12 05:37:47
Use std::numeric_limits.
wala
2014/08/16 00:07:12
Done.
| |
| 4051 uint32_t Mask2 = Mask1 ^ Value; | |
| 4052 _mov(Dest, Ctx->getConstantInt(IceType_i32, Mask1)); | |
| 4053 _xor(Dest, Ctx->getConstantInt(IceType_i32, Mask2)); | |
| 4054 } | |
| 4055 | |
| 4056 return Dest; | |
| 4057 } | |
| 4058 | |
| 3943 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, | 4059 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, |
| 3944 bool AllowOverlap, int32_t RegNum) { | 4060 bool AllowOverlap, int32_t RegNum) { |
| 3945 // Assert that a physical register is allowed. To date, all calls | 4061 // Assert that a physical register is allowed. To date, all calls |
| 3946 // to legalize() allow a physical register. If a physical register | 4062 // to legalize() allow a physical register. If a physical register |
| 3947 // needs to be explicitly disallowed, then new code will need to be | 4063 // needs to be explicitly disallowed, then new code will need to be |
| 3948 // written to force a spill. | 4064 // written to force a spill. |
| 3949 assert(Allowed & Legal_Reg); | 4065 assert(Allowed & Legal_Reg); |
| 3950 // If we're asking for a specific physical register, make sure we're | 4066 // If we're asking for a specific physical register, make sure we're |
| 3951 // not allowing any other operand kinds. (This could be future | 4067 // not allowing any other operand kinds. (This could be future |
| 3952 // work, e.g. allow the shl shift amount to be either an immediate | 4068 // work, e.g. allow the shl shift amount to be either an immediate |
| 3953 // or in ecx.) | 4069 // or in ecx.) |
| 3954 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); | 4070 assert(RegNum == Variable::NoRegister || Allowed == Legal_Reg); |
| 3955 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { | 4071 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(From)) { |
| 3956 // Before doing anything with a Mem operand, we need to ensure | 4072 // Before doing anything with a Mem operand, we need to ensure |
| 3957 // that the Base and Index components are in physical registers. | 4073 // that the Base and Index components are in physical registers. |
| 3958 Variable *Base = Mem->getBase(); | 4074 Variable *Base = Mem->getBase(); |
| 3959 Variable *Index = Mem->getIndex(); | 4075 Variable *Index = Mem->getIndex(); |
| 4076 Constant *Offset = Mem->getOffset(); | |
| 3960 Variable *RegBase = NULL; | 4077 Variable *RegBase = NULL; |
| 3961 Variable *RegIndex = NULL; | 4078 Variable *RegIndex = NULL; |
| 3962 if (Base) { | 4079 if (Base) { |
| 3963 RegBase = legalizeToVar(Base, true); | 4080 RegBase = legalizeToVar(Base, true); |
| 3964 } | 4081 } |
| 3965 if (Index) { | 4082 if (Index) { |
| 3966 RegIndex = legalizeToVar(Index, true); | 4083 RegIndex = legalizeToVar(Index, true); |
| 3967 } | 4084 } |
| 4085 | |
| 4086 if (CLRandomizeImmediates && immediateShouldBeRandomized(Offset)) { | |
|
Jim Stichnoth
2014/08/13 23:30:25
Can you just add the CLRandomizeImmediates test in
wala
2014/08/16 00:07:12
Done.
| |
| 4087 // lea new_base [base + randomize(offset)] | |
| 4088 Variable *RegOffset = randomizeImmediate(Offset); | |
| 4089 OperandX8632Mem *NewBaseAddr = OperandX8632Mem::create( | |
| 4090 Func, Mem->getType(), RegBase, NULL, RegOffset, 0); | |
| 4091 Variable *NewBase = makeReg(IceType_i32); | |
| 4092 _lea(NewBase, NewBaseAddr); | |
| 4093 RegBase = NewBase; | |
| 4094 Offset = NULL; | |
| 4095 } | |
| 4096 | |
| 3968 if (Base != RegBase || Index != RegIndex) { | 4097 if (Base != RegBase || Index != RegIndex) { |
| 3969 From = OperandX8632Mem::create( | 4098 From = OperandX8632Mem::create(Func, Mem->getType(), RegBase, Offset, |
| 3970 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, | 4099 RegIndex, Mem->getShift(), |
| 3971 Mem->getShift(), Mem->getSegmentRegister()); | 4100 Mem->getSegmentRegister()); |
| 3972 } | 4101 } |
| 3973 | 4102 |
| 3974 if (!(Allowed & Legal_Mem)) { | 4103 if (!(Allowed & Legal_Mem)) { |
| 3975 From = copyToReg(From, RegNum); | 4104 From = copyToReg(From, RegNum); |
| 3976 } | 4105 } |
| 3977 return From; | 4106 return From; |
| 3978 } | 4107 } |
| 3979 if (llvm::isa<Constant>(From)) { | 4108 if (llvm::isa<Constant>(From)) { |
| 3980 if (llvm::isa<ConstantUndef>(From)) { | 4109 if (llvm::isa<ConstantUndef>(From)) { |
| 3981 // Lower undefs to zero. Another option is to lower undefs to an | 4110 // Lower undefs to zero. Another option is to lower undefs to an |
| 3982 // uninitialized register; however, using an uninitialized register | 4111 // uninitialized register; however, using an uninitialized register |
| 3983 // results in less predictable code. | 4112 // results in less predictable code. |
| 3984 // | 4113 // |
| 3985 // If in the future the implementation is changed to lower undef | 4114 // If in the future the implementation is changed to lower undef |
| 3986 // values to uninitialized registers, a FakeDef will be needed: | 4115 // values to uninitialized registers, a FakeDef will be needed: |
| 3987 // Context.insert(InstFakeDef::create(Func, Reg)); | 4116 // Context.insert(InstFakeDef::create(Func, Reg)); |
| 3988 // This is in order to ensure that the live range of Reg is not | 4117 // This is in order to ensure that the live range of Reg is not |
| 3989 // overestimated. If the constant being lowered is a 64 bit value, | 4118 // overestimated. If the constant being lowered is a 64 bit value, |
| 3990 // then the result should be split and the lo and hi components will | 4119 // then the result should be split and the lo and hi components will |
| 3991 // need to go in uninitialized registers. | 4120 // need to go in uninitialized registers. |
| 3992 if (isVectorType(From->getType())) | 4121 if (isVectorType(From->getType())) |
| 3993 return makeVectorOfZeros(From->getType()); | 4122 return makeVectorOfZeros(From->getType()); |
| 3994 From = Ctx->getConstantZero(From->getType()); | 4123 From = Ctx->getConstantZero(From->getType()); |
| 3995 } | 4124 } |
| 3996 // There should be no constants of vector type (other than undef). | 4125 // There should be no constants of vector type (other than undef). |
| 3997 assert(!isVectorType(From->getType())); | 4126 assert(!isVectorType(From->getType())); |
| 4127 | |
| 4128 if (CLRandomizeImmediates && immediateShouldBeRandomized(From)) { | |
| 4129 return randomizeImmediate(llvm::cast<Constant>(From)); | |
| 4130 } | |
| 4131 | |
| 3998 bool NeedsReg = false; | 4132 bool NeedsReg = false; |
| 3999 if (!(Allowed & Legal_Imm)) | 4133 if (!(Allowed & Legal_Imm)) |
| 4000 // Immediate specifically not allowed | 4134 // Immediate specifically not allowed |
| 4001 NeedsReg = true; | 4135 NeedsReg = true; |
| 4002 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper | 4136 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper |
| 4003 // emitter is used. | 4137 // emitter is used. |
| 4004 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) | 4138 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) |
| 4005 // Relocatable specifically not allowed | 4139 // Relocatable specifically not allowed |
| 4006 NeedsReg = true; | 4140 NeedsReg = true; |
| 4007 if (!(Allowed & Legal_Mem) && | 4141 if (!(Allowed & Legal_Mem) && |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4249 for (SizeT i = 0; i < Size; ++i) { | 4383 for (SizeT i = 0; i < Size; ++i) { |
| 4250 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4384 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 4251 } | 4385 } |
| 4252 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4386 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4253 } | 4387 } |
| 4254 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName | 4388 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName |
| 4255 << "\n"; | 4389 << "\n"; |
| 4256 } | 4390 } |
| 4257 | 4391 |
| 4258 } // end of namespace Ice | 4392 } // end of namespace Ice |
| OLD | NEW |