OLD | NEW |
---|---|
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// | 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// |
2 // | 2 // |
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
6 // | 6 // |
7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
8 // | 8 // |
9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
10 // | 10 // |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
168 } | 168 } |
169 | 169 |
170 // Extract out a Bit in Value. | 170 // Extract out a Bit in Value. |
171 bool isBitSet(IValueT Bit, IValueT Value) { return (Value & Bit) == Bit; } | 171 bool isBitSet(IValueT Bit, IValueT Value) { return (Value & Bit) == Bit; } |
172 | 172 |
173 // Returns the GPR register at given Shift in Value. | 173 // Returns the GPR register at given Shift in Value. |
174 RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { | 174 RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { |
175 return decodeGPRRegister((Value >> Shift) & 0xF); | 175 return decodeGPRRegister((Value >> Shift) & 0xF); |
176 } | 176 } |
177 | 177 |
178 // Defines alternate layouts of instruction operands, should the (common) | |
179 // default pattern not be used. | |
180 enum OpEncoding { | |
181 // No alternate layout specified. | |
182 DefaultOpEncoding, | |
183 // Alternate encoding for ImmRegOffset, where the offset is divided by 4 | |
184 // before encoding. | |
185 ImmRegOffsetDiv4, | |
186 // Alternate encoding 3 for memory operands (like in strb, strh, ldrb, and | |
187 // ldrh. | |
188 OpEncoding3, | |
189 // Alternate encoding for memory operands for ldrex and strex, which only | |
190 // actually expect a register. | |
191 OpEncodingMemEx | |
192 }; | |
193 | |
194 IValueT getEncodedGPRegNum(const Variable *Var) { | 178 IValueT getEncodedGPRegNum(const Variable *Var) { |
195 assert(Var->hasReg()); | 179 assert(Var->hasReg()); |
196 int32_t Reg = Var->getRegNum(); | 180 int32_t Reg = Var->getRegNum(); |
197 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) | 181 return llvm::isa<Variable64On32>(Var) ? RegARM32::getI64PairFirstGPRNum(Reg) |
198 : RegARM32::getEncodedGPR(Reg); | 182 : RegARM32::getEncodedGPR(Reg); |
199 } | 183 } |
200 | 184 |
201 IValueT getEncodedSRegNum(const Variable *Var) { | 185 IValueT getEncodedSRegNum(const Variable *Var) { |
202 assert(Var->hasReg()); | 186 assert(Var->hasReg()); |
203 return RegARM32::getEncodedSReg(Var->getRegNum()); | 187 return RegARM32::getEncodedSReg(Var->getRegNum()); |
204 } | 188 } |
205 | 189 |
206 IValueT getEncodedDRegNum(const Variable *Var) { | 190 IValueT getEncodedDRegNum(const Variable *Var) { |
207 return RegARM32::getEncodedDReg(Var->getRegNum()); | 191 return RegARM32::getEncodedDReg(Var->getRegNum()); |
208 } | 192 } |
209 | 193 |
210 IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; } | 194 IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; } |
211 | 195 |
212 IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; } | 196 IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; } |
213 | 197 |
214 IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; } | 198 IValueT getYInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX >> 4; } |
215 | 199 |
216 IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; } | 200 IValueT getXXXXInRegYXXXX(IValueT RegYXXXX) { return RegYXXXX & 0x0f; } |
217 | 201 |
202 // Defines layouts of an operand representing a (register) memory address, | |
203 // possibly modified by an immediate value. | |
204 enum EncodedImmAddress { | |
205 // Address modified by a rotated immediate 8-bit value. | |
206 RotatedImm8Address, | |
207 // Alternate encoding for RotatedImm8Address, where the offset is divided by 4 | |
Jim Stichnoth
2016/01/25 20:37:50
Optional: Consider adding a blank line after each
Karl
2016/01/25 23:59:16
Added blank lines. Did same for following enum Enc
| |
208 // before encoding. | |
209 RotatedImm8Div4Address, | |
210 // Address modified by an immediate 12-bit value. | |
211 Imm12Address, | |
212 // Alternate encoding 3, for an address modified by a rotated immediate 8-bit | |
213 // value. | |
214 RotatedImm8Enc3Address, | |
215 // Encoding where no immediate offset is used. | |
216 NoImmOffsetAddress | |
217 }; | |
218 | |
218 // The way an operand is encoded into a sequence of bits in functions | 219 // The way an operand is encoded into a sequence of bits in functions |
219 // encodeOperand and encodeAddress below. | 220 // encodeOperand and encodeAddress below. |
220 enum EncodedOperand { | 221 enum EncodedOperand { |
221 // Unable to encode, value left undefined. | 222 // Unable to encode, value left undefined. |
222 CantEncode = 0, | 223 CantEncode = 0, |
223 // Value is register found. | 224 // Value is register found. |
224 EncodedAsRegister, | 225 EncodedAsRegister, |
225 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 | 226 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 |
226 // value. | 227 // value. |
227 EncodedAsRotatedImm8, | 228 EncodedAsRotatedImm8, |
228 // EncodedAsImmRegOffset is a memory operand that can take three forms, based | 229 // EncodedAsImmRegOffset is a memory operand that can take three forms, based |
229 // on OpEncoding: | 230 // on type EncodedImmAddress: |
230 // | 231 // |
231 // ***** DefaultOpEncoding ***** | 232 // ***** RotatedImm8Address ***** |
232 // | 233 // |
233 // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, | 234 // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, |
234 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to | 235 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to |
235 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. | 236 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. |
236 // | 237 // |
237 // ***** OpEncoding3 ***** | 238 // ***** RotatedImm8Div4Address ***** |
238 // | 239 // |
239 // Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1 | 240 // Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1 |
240 // if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to | 241 // if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to |
241 // Rn. | 242 // Rn. |
242 // | 243 // |
243 // ***** OpEncodingMemEx ***** | 244 // ***** Imm12Address ***** |
244 // | 245 // |
245 // Value=00000000U000nnnn00000000xxxxxxxx where nnnn=Rn, xxxxxxxx=abs(Offset), | 246 // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, |
246 // and U=1 Offset>=0. | 247 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to |
248 // Rn should be used, and iiiiiiiiiiii defines the immediate 12-bit value. | |
249 // | |
250 // ***** NoImmOffsetAddress ***** | |
251 // | |
252 // Value=000000001000nnnn0000000000000000 where nnnn=Rn. | |
247 EncodedAsImmRegOffset, | 253 EncodedAsImmRegOffset, |
248 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, | 254 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, |
249 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift | 255 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift |
250 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if | 256 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if |
251 // writeback to Rn. | 257 // writeback to Rn. |
252 EncodedAsShiftRotateImm5, | 258 EncodedAsShiftRotateImm5, |
253 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value | 259 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value |
254 // to shift. | 260 // to shift. |
255 EncodedAsShiftImm5, | 261 EncodedAsShiftImm5, |
256 // Value=iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift | 262 // Value=iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 } | 355 } |
350 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { | 356 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { |
351 const IValueT Immed5 = ShImm->getShAmtImm(); | 357 const IValueT Immed5 = ShImm->getShAmtImm(); |
352 assert(Immed5 < (1 << kShiftImmBits)); | 358 assert(Immed5 < (1 << kShiftImmBits)); |
353 Value = (Immed5 << kShiftImmShift); | 359 Value = (Immed5 << kShiftImmShift); |
354 return EncodedAsShiftImm5; | 360 return EncodedAsShiftImm5; |
355 } | 361 } |
356 return CantEncode; | 362 return CantEncode; |
357 } | 363 } |
358 | 364 |
359 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset, | 365 inline IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset, |
Jim Stichnoth
2016/01/25 20:37:50
Why inline here? This seems inconsistent with the
Karl
2016/01/25 23:59:16
Removed.
| |
360 OperandARM32Mem::AddrMode Mode, | 366 OperandARM32Mem::AddrMode Mode, |
361 IValueT OffsetShift = 0) { | 367 IOffsetT MaxOffset, IValueT OffsetShift) { |
362 IValueT Value = Mode | (Reg << kRnShift); | 368 IValueT Value = Mode | (Reg << kRnShift); |
363 if (Offset < 0) { | 369 if (Offset < 0) { |
364 Offset = -Offset; | 370 Offset = -Offset; |
365 Value ^= U; // Flip U to adjust sign. | 371 Value ^= U; // Flip U to adjust sign. |
366 } | 372 } |
373 assert(Offset <= MaxOffset); | |
374 (void)MaxOffset; | |
367 return Value | (Offset >> OffsetShift); | 375 return Value | (Offset >> OffsetShift); |
368 } | 376 } |
369 | 377 |
370 // Encodes immediate register offset using encoding 3. | 378 // Encodes immediate register offset using encoding 3. |
371 IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8, | 379 IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8, |
372 OperandARM32Mem::AddrMode Mode) { | 380 OperandARM32Mem::AddrMode Mode) { |
373 IValueT Value = Mode | (Rn << kRnShift); | 381 IValueT Value = Mode | (Rn << kRnShift); |
374 if (Imm8 < 0) { | 382 if (Imm8 < 0) { |
375 Imm8 = -Imm8; | 383 Imm8 = -Imm8; |
376 Value = (Value ^ U); | 384 Value = (Value ^ U); |
377 } | 385 } |
378 assert(Imm8 < (1 << 8)); | 386 assert(Imm8 < (1 << 8)); |
379 Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f); | 387 Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f); |
380 return Value; | 388 return Value; |
381 } | 389 } |
382 | 390 |
383 IValueT encodeImmRegOffset(OpEncoding AddressEncoding, IValueT Reg, | 391 IValueT encodeImmRegOffset(EncodedImmAddress ImmEncoding, IValueT Reg, |
384 IOffsetT Offset, OperandARM32Mem::AddrMode Mode) { | 392 IOffsetT Offset, OperandARM32Mem::AddrMode Mode) { |
385 switch (AddressEncoding) { | 393 switch (ImmEncoding) { |
386 case DefaultOpEncoding: | 394 case RotatedImm8Address: { |
387 return encodeImmRegOffset(Reg, Offset, Mode); | 395 constexpr IOffsetT MaxOffset = (1 << 8) - 1; |
388 case ImmRegOffsetDiv4: { | 396 constexpr IValueT NoRightShift = 0; |
397 return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift); | |
398 } | |
399 case RotatedImm8Div4Address: { | |
389 assert((Offset & 0x3) == 0); | 400 assert((Offset & 0x3) == 0); |
401 constexpr IOffsetT MaxOffset = (1 << 8) - 1; | |
390 constexpr IValueT RightShift2 = 2; | 402 constexpr IValueT RightShift2 = 2; |
391 return encodeImmRegOffset(Reg, Offset, Mode, RightShift2); | 403 return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, RightShift2); |
392 } | 404 } |
393 case OpEncoding3: | 405 case Imm12Address: { |
406 constexpr IOffsetT MaxOffset = (1 << 12) - 1; | |
407 constexpr IValueT NoRightShift = 0; | |
408 return encodeImmRegOffset(Reg, Offset, Mode, MaxOffset, NoRightShift); | |
409 } | |
410 case RotatedImm8Enc3Address: | |
394 return encodeImmRegOffsetEnc3(Reg, Offset, Mode); | 411 return encodeImmRegOffsetEnc3(Reg, Offset, Mode); |
395 case OpEncodingMemEx: | 412 case NoImmOffsetAddress: { |
396 assert(Offset == 0); | 413 assert(Offset == 0); |
397 assert(Mode == OperandARM32Mem::Offset); | 414 assert(Mode == OperandARM32Mem::Offset); |
398 return Reg << kRnShift; | 415 return Reg << kRnShift; |
399 } | 416 } |
417 } | |
400 llvm_unreachable("(silence g++ warning)"); | 418 llvm_unreachable("(silence g++ warning)"); |
401 } | 419 } |
402 | 420 |
403 // Encodes memory address Opnd, and encodes that information into Value, based | 421 // Encodes memory address Opnd, and encodes that information into Value, based |
404 // on how ARM represents the address. Returns how the value was encoded. | 422 // on how ARM represents the address. Returns how the value was encoded. |
405 EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value, | 423 EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value, |
406 const AssemblerARM32::TargetInfo &TInfo, | 424 const AssemblerARM32::TargetInfo &TInfo, |
407 OpEncoding AddressEncoding = DefaultOpEncoding) { | 425 EncodedImmAddress ImmEncoding) { |
408 Value = 0; // Make sure initialized. | 426 Value = 0; // Make sure initialized. |
409 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 427 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
410 // Should be a stack variable, with an offset. | 428 // Should be a stack variable, with an offset. |
411 if (Var->hasReg()) | 429 if (Var->hasReg()) |
412 return CantEncode; | 430 return CantEncode; |
413 IOffsetT Offset = Var->getStackOffset(); | 431 IOffsetT Offset = Var->getStackOffset(); |
414 if (!Utils::IsAbsoluteUint(12, Offset)) | 432 if (!Utils::IsAbsoluteUint(12, Offset)) |
415 return CantEncode; | 433 return CantEncode; |
416 int32_t BaseRegNum = Var->getBaseRegNum(); | 434 int32_t BaseRegNum = Var->getBaseRegNum(); |
417 if (BaseRegNum == Variable::NoRegister) | 435 if (BaseRegNum == Variable::NoRegister) |
418 BaseRegNum = TInfo.FrameOrStackReg; | 436 BaseRegNum = TInfo.FrameOrStackReg; |
419 Value = encodeImmRegOffset(AddressEncoding, BaseRegNum, Offset, | 437 Value = encodeImmRegOffset(ImmEncoding, BaseRegNum, Offset, |
420 OperandARM32Mem::Offset); | 438 OperandARM32Mem::Offset); |
421 return EncodedAsImmRegOffset; | 439 return EncodedAsImmRegOffset; |
422 } | 440 } |
423 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { | 441 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { |
424 Variable *Var = Mem->getBase(); | 442 Variable *Var = Mem->getBase(); |
425 if (!Var->hasReg()) | 443 if (!Var->hasReg()) |
426 return CantEncode; | 444 return CantEncode; |
427 IValueT Rn = getEncodedGPRegNum(Var); | 445 IValueT Rn = getEncodedGPRegNum(Var); |
428 if (Mem->isRegReg()) { | 446 if (Mem->isRegReg()) { |
429 const Variable *Index = Mem->getIndex(); | 447 const Variable *Index = Mem->getIndex(); |
430 if (Var == nullptr) | 448 if (Var == nullptr) |
431 return CantEncode; | 449 return CantEncode; |
432 Value = (Rn << kRnShift) | Mem->getAddrMode() | | 450 Value = (Rn << kRnShift) | Mem->getAddrMode() | |
433 encodeShiftRotateImm5(getEncodedGPRegNum(Index), | 451 encodeShiftRotateImm5(getEncodedGPRegNum(Index), |
434 Mem->getShiftOp(), Mem->getShiftAmt()); | 452 Mem->getShiftOp(), Mem->getShiftAmt()); |
435 return EncodedAsShiftRotateImm5; | 453 return EncodedAsShiftRotateImm5; |
436 } | 454 } |
437 // Encoded as immediate register offset. | 455 // Encoded as immediate register offset. |
438 ConstantInteger32 *Offset = Mem->getOffset(); | 456 ConstantInteger32 *Offset = Mem->getOffset(); |
439 Value = encodeImmRegOffset(AddressEncoding, Rn, Offset->getValue(), | 457 Value = encodeImmRegOffset(ImmEncoding, Rn, Offset->getValue(), |
440 Mem->getAddrMode()); | 458 Mem->getAddrMode()); |
441 return EncodedAsImmRegOffset; | 459 return EncodedAsImmRegOffset; |
442 } | 460 } |
443 return CantEncode; | 461 return CantEncode; |
444 } | 462 } |
445 | 463 |
446 // Checks that Offset can fit in imm24 constant of branch (b) instruction. | 464 // Checks that Offset can fit in imm24 constant of branch (b) instruction. |
447 bool canEncodeBranchOffset(IOffsetT Offset) { | 465 bool canEncodeBranchOffset(IOffsetT Offset) { |
448 return Utils::IsAligned(Offset, 4) && | 466 return Utils::IsAligned(Offset, 4) && |
449 Utils::IsInt(kBranchOffsetBits, Offset >> 2); | 467 Utils::IsInt(kBranchOffsetBits, Offset >> 2); |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
795 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | 813 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | |
796 (InstType << kTypeShift) | (IsLoad ? L : 0) | | 814 (InstType << kTypeShift) | (IsLoad ? L : 0) | |
797 (IsByte ? B : 0) | (Rt << kRdShift) | Address; | 815 (IsByte ? B : 0) | (Rt << kRdShift) | Address; |
798 emitInst(Encoding); | 816 emitInst(Encoding); |
799 } | 817 } |
800 | 818 |
801 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, | 819 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, |
802 IValueT Rt, const Operand *OpAddress, | 820 IValueT Rt, const Operand *OpAddress, |
803 const TargetInfo &TInfo, const char *InstName) { | 821 const TargetInfo &TInfo, const char *InstName) { |
804 IValueT Address; | 822 IValueT Address; |
805 switch (encodeAddress(OpAddress, Address, TInfo)) { | 823 switch (encodeAddress(OpAddress, Address, TInfo, Imm12Address)) { |
806 default: | 824 default: |
807 llvm::report_fatal_error(std::string(InstName) + | 825 llvm::report_fatal_error(std::string(InstName) + |
808 ": Memory address not understood"); | 826 ": Memory address not understood"); |
809 case EncodedAsImmRegOffset: { | 827 case EncodedAsImmRegOffset: { |
810 // XXX{B} (immediate): | 828 // XXX{B} (immediate): |
811 // xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 829 // xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
812 // xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 | 830 // xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 |
813 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 | 831 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 |
814 // | 832 // |
815 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, | 833 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
853 return; | 871 return; |
854 } | 872 } |
855 } | 873 } |
856 } | 874 } |
857 | 875 |
858 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, | 876 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, |
859 IValueT Rt, const Operand *OpAddress, | 877 IValueT Rt, const Operand *OpAddress, |
860 const TargetInfo &TInfo, | 878 const TargetInfo &TInfo, |
861 const char *InstName) { | 879 const char *InstName) { |
862 IValueT Address; | 880 IValueT Address; |
863 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) { | 881 switch (encodeAddress(OpAddress, Address, TInfo, RotatedImm8Enc3Address)) { |
864 default: | 882 default: |
865 llvm::report_fatal_error(std::string(InstName) + | 883 llvm::report_fatal_error(std::string(InstName) + |
866 ": Memory address not understood"); | 884 ": Memory address not understood"); |
867 case EncodedAsImmRegOffset: { | 885 case EncodedAsImmRegOffset: { |
868 // XXXH (immediate) | 886 // XXXH (immediate) |
869 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] | 887 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] |
870 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] | 888 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] |
871 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! | 889 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! |
872 // | 890 // |
873 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, | 891 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, |
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1349 break; | 1367 break; |
1350 case IceType_i16: | 1368 case IceType_i16: |
1351 MemExOpcode |= B2 | B1; | 1369 MemExOpcode |= B2 | B1; |
1352 break; | 1370 break; |
1353 case IceType_i32: | 1371 case IceType_i32: |
1354 break; | 1372 break; |
1355 case IceType_i64: | 1373 case IceType_i64: |
1356 MemExOpcode |= B1; | 1374 MemExOpcode |= B1; |
1357 } | 1375 } |
1358 IValueT AddressRn; | 1376 IValueT AddressRn; |
1359 if (encodeAddress(OpAddress, AddressRn, TInfo, OpEncodingMemEx) != | 1377 if (encodeAddress(OpAddress, AddressRn, TInfo, NoImmOffsetAddress) != |
1360 EncodedAsImmRegOffset) | 1378 EncodedAsImmRegOffset) |
1361 llvm::report_fatal_error(std::string(InstName) + | 1379 llvm::report_fatal_error(std::string(InstName) + |
1362 ": Can't extract Rn from address"); | 1380 ": Can't extract Rn from address"); |
1363 assert(Utils::IsAbsoluteUint(3, MemExOpcode)); | 1381 assert(Utils::IsAbsoluteUint(3, MemExOpcode)); |
1364 assert(Rd < RegARM32::getNumGPRegs()); | 1382 assert(Rd < RegARM32::getNumGPRegs()); |
1365 assert(Rt < RegARM32::getNumGPRegs()); | 1383 assert(Rt < RegARM32::getNumGPRegs()); |
1366 assert(CondARM32::isDefined(Cond)); | 1384 assert(CondARM32::isDefined(Cond)); |
1367 IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 | | 1385 IValueT Encoding = (Cond << kConditionShift) | B24 | B23 | B11 | B10 | B9 | |
1368 B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) | | 1386 B8 | B7 | B4 | (MemExOpcode << kMemExOpcodeShift) | |
1369 AddressRn | (Rd << kRdShift) | (Rt << kRmShift); | 1387 AddressRn | (Rd << kRdShift) | (Rt << kRmShift); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1723 // POP - ARM section A8.8.132, encoding A2: | 1741 // POP - ARM section A8.8.132, encoding A2: |
1724 // pop<c> {Rt} | 1742 // pop<c> {Rt} |
1725 // | 1743 // |
1726 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. | 1744 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. |
1727 constexpr const char *Pop = "pop"; | 1745 constexpr const char *Pop = "pop"; |
1728 IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop); | 1746 IValueT Rt = encodeGPRegister(OpRt, "Rt", Pop); |
1729 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop); | 1747 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Pop); |
1730 // Same as load instruction. | 1748 // Same as load instruction. |
1731 constexpr bool IsLoad = true; | 1749 constexpr bool IsLoad = true; |
1732 constexpr bool IsByte = false; | 1750 constexpr bool IsByte = false; |
1733 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, | 1751 constexpr IOffsetT MaxOffset = (1 << 8) - 1; |
1734 OperandARM32Mem::PostIndex); | 1752 constexpr IValueT NoShiftRight = 0; |
1753 IValueT Address = | |
1754 encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, | |
1755 OperandARM32Mem::PostIndex, MaxOffset, NoShiftRight); | |
1735 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); | 1756 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); |
1736 } | 1757 } |
1737 | 1758 |
1738 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { | 1759 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { |
1739 // POP - ARM section A8.*.131, encoding A1: | 1760 // POP - ARM section A8.*.131, encoding A1: |
1740 // pop<c> <registers> | 1761 // pop<c> <registers> |
1741 // | 1762 // |
1742 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and | 1763 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and |
1743 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). | 1764 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). |
1744 constexpr bool IsLoad = true; | 1765 constexpr bool IsLoad = true; |
1745 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); | 1766 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); |
1746 } | 1767 } |
1747 | 1768 |
1748 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { | 1769 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { |
1749 // PUSH - ARM section A8.8.133, encoding A2: | 1770 // PUSH - ARM section A8.8.133, encoding A2: |
1750 // push<c> {Rt} | 1771 // push<c> {Rt} |
1751 // | 1772 // |
1752 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. | 1773 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. |
1753 constexpr const char *Push = "push"; | 1774 constexpr const char *Push = "push"; |
1754 IValueT Rt = encodeGPRegister(OpRt, "Rt", Push); | 1775 IValueT Rt = encodeGPRegister(OpRt, "Rt", Push); |
1755 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push); | 1776 verifyRegsNotEq(Rt, "Rt", RegARM32::Encoded_Reg_sp, "sp", Push); |
1756 // Same as store instruction. | 1777 // Same as store instruction. |
1757 constexpr bool isLoad = false; | 1778 constexpr bool isLoad = false; |
1758 constexpr bool isByte = false; | 1779 constexpr bool isByte = false; |
1759 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, | 1780 constexpr IOffsetT MaxOffset = (1 << 8) - 1; |
1760 OperandARM32Mem::PreIndex); | 1781 constexpr IValueT NoShiftRight = 0; |
1782 IValueT Address = | |
1783 encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, | |
1784 OperandARM32Mem::PreIndex, MaxOffset, NoShiftRight); | |
1761 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); | 1785 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); |
1762 } | 1786 } |
1763 | 1787 |
1764 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { | 1788 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { |
1765 // PUSH - ARM section A8.8.133, encoding A1: | 1789 // PUSH - ARM section A8.8.133, encoding A1: |
1766 // push<c> <Registers> | 1790 // push<c> <Registers> |
1767 // | 1791 // |
1768 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and | 1792 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and |
1769 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). | 1793 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). |
1770 constexpr bool IsLoad = false; | 1794 constexpr bool IsLoad = false; |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2315 // VLDR - ARM section A8.8.333, encoding A1. | 2339 // VLDR - ARM section A8.8.333, encoding A1. |
2316 // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}] | 2340 // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}] |
2317 // | 2341 // |
2318 // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd, | 2342 // cccc1101UD01nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd, |
2319 // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0. | 2343 // iiiiiiii=abs(Imm >> 2), and U=1 if Opcode>=0. |
2320 constexpr const char *Vldrd = "vldrd"; | 2344 constexpr const char *Vldrd = "vldrd"; |
2321 IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd); | 2345 IValueT Dd = encodeDRegister(OpDd, "Dd", Vldrd); |
2322 assert(CondARM32::isDefined(Cond)); | 2346 assert(CondARM32::isDefined(Cond)); |
2323 IValueT Address; | 2347 IValueT Address; |
2324 EncodedOperand AddressEncoding = | 2348 EncodedOperand AddressEncoding = |
2325 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4); | 2349 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
2326 (void)AddressEncoding; | 2350 (void)AddressEncoding; |
2327 assert(AddressEncoding == EncodedAsImmRegOffset); | 2351 assert(AddressEncoding == EncodedAsImmRegOffset); |
2328 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 | | 2352 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | B8 | |
2329 (encodeCondition(Cond) << kConditionShift) | | 2353 (encodeCondition(Cond) << kConditionShift) | |
2330 (getYInRegYXXXX(Dd) << 22) | | 2354 (getYInRegYXXXX(Dd) << 22) | |
2331 (getXXXXInRegYXXXX(Dd) << 12) | Address; | 2355 (getXXXXInRegYXXXX(Dd) << 12) | Address; |
2332 emitInst(Encoding); | 2356 emitInst(Encoding); |
2333 } | 2357 } |
2334 | 2358 |
2335 void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress, | 2359 void AssemblerARM32::vldrs(const Operand *OpSd, const Operand *OpAddress, |
2336 CondARM32::Cond Cond, const TargetInfo &TInfo) { | 2360 CondARM32::Cond Cond, const TargetInfo &TInfo) { |
2337 // VDLR - ARM section A8.8.333, encoding A2. | 2361 // VDLR - ARM section A8.8.333, encoding A2. |
2338 // vldr<c> <Sd>, [<Rn>{, #+/-<imm>]] | 2362 // vldr<c> <Sd>, [<Rn>{, #+/-<imm>]] |
2339 // | 2363 // |
2340 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd, | 2364 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd, |
2341 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0; | 2365 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0; |
2342 constexpr const char *Vldrs = "vldrs"; | 2366 constexpr const char *Vldrs = "vldrs"; |
2343 IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs); | 2367 IValueT Sd = encodeSRegister(OpSd, "Sd", Vldrs); |
2344 assert(CondARM32::isDefined(Cond)); | 2368 assert(CondARM32::isDefined(Cond)); |
2345 IValueT Address; | 2369 IValueT Address; |
2346 EncodedOperand AddressEncoding = | 2370 EncodedOperand AddressEncoding = |
2347 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4); | 2371 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
2348 (void)AddressEncoding; | 2372 (void)AddressEncoding; |
2349 assert(AddressEncoding == EncodedAsImmRegOffset); | 2373 assert(AddressEncoding == EncodedAsImmRegOffset); |
2350 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | | 2374 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | |
2351 (encodeCondition(Cond) << kConditionShift) | | 2375 (encodeCondition(Cond) << kConditionShift) | |
2352 (getYInRegXXXXY(Sd) << 22) | | 2376 (getYInRegXXXXY(Sd) << 22) | |
2353 (getXXXXInRegXXXXY(Sd) << 12) | Address; | 2377 (getXXXXInRegXXXXY(Sd) << 12) | Address; |
2354 emitInst(Encoding); | 2378 emitInst(Encoding); |
2355 } | 2379 } |
2356 | 2380 |
2357 void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt, | 2381 void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2422 // VSTR - ARM section A8.8.413, encoding A1: | 2446 // VSTR - ARM section A8.8.413, encoding A1: |
2423 // vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}] | 2447 // vstr<c> <Dd>, [<Rn>{, #+/-<Imm>}] |
2424 // | 2448 // |
2425 // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd, | 2449 // cccc1101UD00nnnndddd1011iiiiiiii where cccc=Cond, nnnn=Rn, Ddddd=Rd, |
2426 // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0. | 2450 // iiiiiiii=abs(Imm >> 2), and U=1 if Imm>=0. |
2427 constexpr const char *Vstrd = "vstrd"; | 2451 constexpr const char *Vstrd = "vstrd"; |
2428 IValueT Dd = encodeDRegister(OpDd, "Dd", Vstrd); | 2452 IValueT Dd = encodeDRegister(OpDd, "Dd", Vstrd); |
2429 assert(CondARM32::isDefined(Cond)); | 2453 assert(CondARM32::isDefined(Cond)); |
2430 IValueT Address; | 2454 IValueT Address; |
2431 IValueT AddressEncoding = | 2455 IValueT AddressEncoding = |
2432 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4); | 2456 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
2433 (void)AddressEncoding; | 2457 (void)AddressEncoding; |
2434 assert(AddressEncoding == EncodedAsImmRegOffset); | 2458 assert(AddressEncoding == EncodedAsImmRegOffset); |
2435 IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 | | 2459 IValueT Encoding = B27 | B26 | B24 | B11 | B9 | B8 | |
2436 (encodeCondition(Cond) << kConditionShift) | | 2460 (encodeCondition(Cond) << kConditionShift) | |
2437 (getYInRegYXXXX(Dd) << 22) | | 2461 (getYInRegYXXXX(Dd) << 22) | |
2438 (getXXXXInRegYXXXX(Dd) << 12) | Address; | 2462 (getXXXXInRegYXXXX(Dd) << 12) | Address; |
2439 emitInst(Encoding); | 2463 emitInst(Encoding); |
2440 } | 2464 } |
2441 | 2465 |
2442 void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress, | 2466 void AssemblerARM32::vstrs(const Operand *OpSd, const Operand *OpAddress, |
2443 CondARM32::Cond Cond, const TargetInfo &TInfo) { | 2467 CondARM32::Cond Cond, const TargetInfo &TInfo) { |
2444 // VSTR - ARM section A8.8.413, encoding A2: | 2468 // VSTR - ARM section A8.8.413, encoding A2: |
2445 // vstr<c> <Sd>, [<Rn>{, #+/-<imm>]] | 2469 // vstr<c> <Sd>, [<Rn>{, #+/-<imm>]] |
2446 // | 2470 // |
2447 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd, | 2471 // cccc1101UD01nnnndddd1010iiiiiiii where cccc=Cond, nnnn=Rn, ddddD=Sd, |
2448 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0; | 2472 // iiiiiiii=abs(Opcode), and U=1 if Opcode >= 0; |
2449 constexpr const char *Vstrs = "vstrs"; | 2473 constexpr const char *Vstrs = "vstrs"; |
2450 IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs); | 2474 IValueT Sd = encodeSRegister(OpSd, "Sd", Vstrs); |
2451 assert(CondARM32::isDefined(Cond)); | 2475 assert(CondARM32::isDefined(Cond)); |
2452 IValueT Address; | 2476 IValueT Address; |
2453 IValueT AddressEncoding = | 2477 IValueT AddressEncoding = |
2454 encodeAddress(OpAddress, Address, TInfo, ImmRegOffsetDiv4); | 2478 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
2455 (void)AddressEncoding; | 2479 (void)AddressEncoding; |
2456 assert(AddressEncoding == EncodedAsImmRegOffset); | 2480 assert(AddressEncoding == EncodedAsImmRegOffset); |
2457 IValueT Encoding = | 2481 IValueT Encoding = |
2458 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | | 2482 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | |
2459 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; | 2483 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; |
2460 emitInst(Encoding); | 2484 emitInst(Encoding); |
2461 } | 2485 } |
2462 | 2486 |
2463 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, | 2487 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, |
2464 const Operand *OpSm, CondARM32::Cond Cond) { | 2488 const Operand *OpSm, CondARM32::Cond Cond) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2531 // | 2555 // |
2532 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and | 2556 // cccc11010D101101dddd1010iiiiiiii where cccc=Cond, ddddD=BaseReg, and |
2533 // iiiiiiii=NumConsecRegs. | 2557 // iiiiiiii=NumConsecRegs. |
2534 constexpr IValueT VpushOpcode = | 2558 constexpr IValueT VpushOpcode = |
2535 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; | 2559 B27 | B26 | B24 | B21 | B19 | B18 | B16 | B11 | B9; |
2536 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs); | 2560 emitVStackOp(Cond, VpushOpcode, OpBaseReg, NumConsecRegs); |
2537 } | 2561 } |
2538 | 2562 |
2539 } // end of namespace ARM32 | 2563 } // end of namespace ARM32 |
2540 } // end of namespace Ice | 2564 } // end of namespace Ice |
OLD | NEW |