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 |