Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1486263002: More coverage of load/stores in ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix remaining issue in patch set 2. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 CantDecode = 0, 184 CantDecode = 0,
185 // Value is register found. 185 // Value is register found.
186 DecodedAsRegister, 186 DecodedAsRegister,
187 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 187 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
188 // value. 188 // value.
189 DecodedAsRotatedImm8, 189 DecodedAsRotatedImm8,
190 // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, 190 // Value=0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
191 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to 191 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. 192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
193 DecodedAsImmRegOffset, 193 DecodedAsImmRegOffset,
194 // Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1
195 // if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to
196 // Rn.
197 DecodedAsImmRegOffsetEnc3,
194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, 198 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift 199 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if 200 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
197 // writeback to Rn. 201 // writeback to Rn.
198 DecodedAsShiftRotateImm5, 202 DecodedAsShiftRotateImm5,
199 // Value=000000000000000000000iiiii0000000 iiii defines the Imm5 value to 203 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value
200 // shift. 204 // to shift.
201 DecodedAsShiftImm5, 205 DecodedAsShiftImm5,
202 // i.e. iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift 206 // i.e. iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift
203 // kind, and iiiii is the shift amount. 207 // kind, and iiiii is the shift amount.
204 DecodedAsShiftedRegister, 208 DecodedAsShiftedRegister,
205 // Value is 32bit integer constant. 209 // Value is 32bit integer constant.
206 DecodedAsConstI32 210 DecodedAsConstI32
207 }; 211 };
208 212
209 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 213 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
210 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 214 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 269 }
266 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { 270 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
267 const IValueT Immed5 = ShImm->getShAmtImm(); 271 const IValueT Immed5 = ShImm->getShAmtImm();
268 assert(Immed5 < (1 << kShiftImmBits)); 272 assert(Immed5 < (1 << kShiftImmBits));
269 Value = (Immed5 << kShiftImmShift); 273 Value = (Immed5 << kShiftImmShift);
270 return DecodedAsShiftImm5; 274 return DecodedAsShiftImm5;
271 } 275 }
272 return CantDecode; 276 return CantDecode;
273 } 277 }
274 278
275 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset, 279 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
276 OperandARM32Mem::AddrMode Mode) { 280 OperandARM32Mem::AddrMode Mode) {
277 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift); 281 IValueT Value = Mode | (Reg << kRnShift);
278 if (Offset < 0) { 282 if (Offset < 0) {
279 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. 283 Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
280 } else { 284 } else {
281 Value |= Offset; 285 Value |= Offset;
282 } 286 }
283 return Value; 287 return Value;
284 } 288 }
285 289
290 // Encodes immediate register offset using encoding 3.
291 IValueT encodeImmRegOffsetEnc3(IValueT Rn, IOffsetT Imm8,
292 OperandARM32Mem::AddrMode Mode) {
293 IValueT Value = Mode | (Rn << kRnShift);
294 if (Imm8 < 0) {
295 Imm8 = -Imm8;
296 Value = (Value ^ U);
297 }
298 assert(Imm8 < (1 << 8));
299 Value = Value | B22 | ((Imm8 & 0xf0) << 4) | (Imm8 & 0x0f);
300 return Value;
301 }
302
303 // Defines alternate layouts of instruction operands, should the (common)
304 // default pattern not be used.
305 enum OpEncoding {
306 // No alternate layout specified.
307 DefaultOpEncoding,
308 // Alternate encoding 3.
309 OpEncoding3
310 };
311
286 // Decodes memory address Opnd, and encodes that information into Value, 312 // Decodes memory address Opnd, and encodes that information into Value,
287 // based on how ARM represents the address. Returns how the value was encoded. 313 // based on how ARM represents the address. Returns how the value was encoded.
288 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value, 314 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value,
289 const AssemblerARM32::TargetInfo &TInfo) { 315 const AssemblerARM32::TargetInfo &TInfo,
316 OpEncoding AddressEncoding = DefaultOpEncoding) {
290 Value = 0; // Make sure initialized. 317 Value = 0; // Make sure initialized.
291 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 318 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
292 // Should be a stack variable, with an offset. 319 // Should be a stack variable, with an offset.
293 if (Var->hasReg()) 320 if (Var->hasReg())
294 return CantDecode; 321 return CantDecode;
295 IOffsetT Offset = Var->getStackOffset(); 322 IOffsetT Offset = Var->getStackOffset();
296 if (!Utils::IsAbsoluteUint(12, Offset)) 323 if (!Utils::IsAbsoluteUint(12, Offset))
297 return CantDecode; 324 return CantDecode;
298 int32_t BaseRegNum = Var->getBaseRegNum(); 325 int32_t BaseRegNum = Var->getBaseRegNum();
299 if (BaseRegNum == Variable::NoRegister) 326 if (BaseRegNum == Variable::NoRegister)
300 BaseRegNum = TInfo.FrameOrStackReg; 327 BaseRegNum = TInfo.FrameOrStackReg;
301 Value = decodeImmRegOffset(decodeGPRRegister(BaseRegNum), Offset, 328 Value = encodeImmRegOffset(BaseRegNum, Offset, OperandARM32Mem::Offset);
302 OperandARM32Mem::Offset);
303 return DecodedAsImmRegOffset; 329 return DecodedAsImmRegOffset;
304 } 330 }
305 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { 331 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) {
306 Variable *Var = Mem->getBase(); 332 Variable *Var = Mem->getBase();
307 if (!Var->hasReg()) 333 if (!Var->hasReg())
308 return CantDecode; 334 return CantDecode;
309 IValueT Rn = Var->getRegNum(); 335 IValueT Rn = Var->getRegNum();
310 if (Mem->isRegReg()) { 336 if (Mem->isRegReg()) {
311 const Variable *Index = Mem->getIndex(); 337 const Variable *Index = Mem->getIndex();
312 if (Var == nullptr) 338 if (Var == nullptr)
313 return CantDecode; 339 return CantDecode;
314 Value = (Rn << kRnShift) | Mem->getAddrMode() | 340 Value = (Rn << kRnShift) | Mem->getAddrMode() |
315 encodeShiftRotateImm5(Index->getRegNum(), Mem->getShiftOp(), 341 encodeShiftRotateImm5(Index->getRegNum(), Mem->getShiftOp(),
316 Mem->getShiftAmt()); 342 Mem->getShiftAmt());
317 return DecodedAsShiftRotateImm5; 343 return DecodedAsShiftRotateImm5;
318 } 344 }
319 // Decoded as immediate register offset. 345 // Decoded as immediate register offset.
320 ConstantInteger32 *Offset = Mem->getOffset(); 346 ConstantInteger32 *Offset = Mem->getOffset();
321 Value = decodeImmRegOffset(decodeGPRRegister(Rn), Offset->getValue(), 347 switch (AddressEncoding) {
322 Mem->getAddrMode()); 348 case DefaultOpEncoding:
323 return DecodedAsImmRegOffset; 349 Value = encodeImmRegOffset(Rn, Offset->getValue(), Mem->getAddrMode());
350 return DecodedAsImmRegOffset;
351 case OpEncoding3:
352 Value =
353 encodeImmRegOffsetEnc3(Rn, Offset->getValue(), Mem->getAddrMode());
354 return DecodedAsImmRegOffsetEnc3;
355 }
324 } 356 }
325 return CantDecode; 357 return CantDecode;
326 } 358 }
327 359
328 // Checks that Offset can fit in imm24 constant of branch (b) instruction. 360 // Checks that Offset can fit in imm24 constant of branch (b) instruction.
329 bool canEncodeBranchOffset(IOffsetT Offset) { 361 bool canEncodeBranchOffset(IOffsetT Offset) {
330 return Utils::IsAligned(Offset, 4) && 362 return Utils::IsAligned(Offset, 4) &&
331 Utils::IsInt(kBranchOffsetBits, Offset >> 2); 363 Utils::IsInt(kBranchOffsetBits, Offset >> 2);
332 } 364 }
333 365
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 IValueT Address) { 632 IValueT Address) {
601 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 633 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond))
602 return setNeedsTextFixup(); 634 return setNeedsTextFixup();
603 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 635 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
604 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 636 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
605 (InstType << kTypeShift) | (IsLoad ? L : 0) | 637 (InstType << kTypeShift) | (IsLoad ? L : 0) |
606 (IsByte ? B : 0) | (Rt << kRdShift) | Address; 638 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
607 emitInst(Encoding); 639 emitInst(Encoding);
608 } 640 }
609 641
642 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
643 IValueT Rt, const Operand *OpAddress,
644 const TargetInfo &TInfo) {
645 IValueT Address;
646 switch (decodeAddress(OpAddress, Address, TInfo)) {
647 default:
648 return setNeedsTextFixup();
649 case DecodedAsImmRegOffset: {
650 // XXX{B} (immediate):
651 // xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
652 // xxx{b}<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
653 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
654 //
655 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
656 // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and
657 // pu0w0nnnn0000iiiiiiiiiiii=Address.
658 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
659
660 // Check if conditions of rules violated.
661 if (Rn == RegARM32::Encoded_Reg_pc)
662 return setNeedsTextFixup();
663 if (!isBitSet(P, Address) && isBitSet(W, Address))
664 return setNeedsTextFixup();
665 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
666 isBitSet(U, Address) & !isBitSet(W, Address) &&
667 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
668 return setNeedsTextFixup();
669
670 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
671 }
672 case DecodedAsShiftRotateImm5: {
673 // XXX{B} (register)
674 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
675 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
676 //
677 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
678 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
679 // pu0w0nnnn0000iiiiiss0mmmm=Address.
680 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
681 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
682
683 // Check if conditions of rules violated.
684 if (isBitSet(P, Address) && isBitSet(W, Address))
685 // Instruction XXXBT!
686 return setNeedsTextFixup();
687 if (IsByte &&
688 ((Rt == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc)))
689 // Unpredictable.
690 return setNeedsTextFixup();
691 if (!IsByte && Rm == RegARM32::Encoded_Reg_pc)
692 // Unpredictable.
693 return setNeedsTextFixup();
694 if (isBitSet(W, Address) &&
695 ((Rn == RegARM32::Encoded_Reg_pc) || encodeGPRRegister(Rn) == Rt))
696 // Unpredictable
697 return setNeedsTextFixup();
698
699 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
700 }
701 }
702 }
703
704 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
705 IValueT Rt, const Operand *OpAddress,
706 const TargetInfo &TInfo) {
707 IValueT Address;
708 switch (decodeAddress(OpAddress, Address, TInfo, OpEncoding3)) {
709 default:
710 return setNeedsTextFixup();
711 case DecodedAsImmRegOffsetEnc3: {
712 // XXXH (immediate)
713 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}]
714 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]
715 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
716 //
717 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
718 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
719 // and pu0w0nnnn0000iiii0000jjjj=Address.
720 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond))
721 return setNeedsTextFixup();
722 if (!isBitSet(P, Address) && isBitSet(W, Address))
723 return setNeedsTextFixup();
724 if ((Rt == RegARM32::Encoded_Reg_pc) ||
725 (isBitSet(W, Address) &&
726 (getGPRReg(kRnShift, Address) == decodeGPRRegister(Rt))))
727 return setNeedsTextFixup();
728 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
729 Opcode | (Rt << kRdShift) | Address;
730 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
731 return emitInst(Encoding);
732 }
733 case DecodedAsShiftRotateImm5: {
734 // XXXH (register)
735 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
736 // xxxh<c> <Rt>, [<Rn>], +/-<Rm>
737 //
738 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
739 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
740 // pu0w0nnnn000000000000mmmm=Address.
741 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond))
742 return setNeedsTextFixup();
743 if (!isBitSet(P, Address) && isBitSet(W, Address))
744 return setNeedsTextFixup();
745 if (Rt == RegARM32::Encoded_Reg_pc)
746 return setNeedsTextFixup();
747 if (getGPRReg(kRmShift, Address) == RegARM32::Encoded_Reg_pc)
748 return setNeedsTextFixup();
749 const RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
750 if (isBitSet(W, Address) &&
751 ((Rn == RegARM32::Encoded_Reg_pc) || (encodeGPRRegister(Rn) == Rt)))
752 return setNeedsTextFixup();
753 if (mask(Address, kShiftImmShift, 5) != 0)
754 // For encoding 3, no shift is allowed.
755 return setNeedsTextFixup();
756 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
757 Opcode | (Rt << kRdShift) | Address;
758 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
759 return emitInst(Encoding);
760 }
761 }
762 }
763
610 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, 764 void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
611 IValueT Rn, IValueT Rm) { 765 IValueT Rn, IValueT Rm) {
612 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) || 766 if (!isGPRRegisterDefined(Rd) || !isGPRRegisterDefined(Rn) ||
613 !isGPRRegisterDefined(Rm) || !isConditionDefined(Cond)) 767 !isGPRRegisterDefined(Rm) || !isConditionDefined(Cond))
614 return setNeedsTextFixup(); 768 return setNeedsTextFixup();
615 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 769 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
616 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | 770 const IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) |
617 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 | 771 (Rn << kDivRnShift) | (Rd << kDivRdShift) | B26 |
618 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 | 772 B25 | B24 | B20 | B15 | B14 | B13 | B12 | B4 |
619 (Rm << kDivRmShift); 773 (Rm << kDivRmShift);
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 987 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
834 } 988 }
835 989
836 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 990 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
837 CondARM32::Cond Cond, const TargetInfo &TInfo) { 991 CondARM32::Cond Cond, const TargetInfo &TInfo) {
838 constexpr bool IsLoad = true; 992 constexpr bool IsLoad = true;
839 IValueT Rt; 993 IValueT Rt;
840 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 994 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
841 return setNeedsTextFixup(); 995 return setNeedsTextFixup();
842 const Type Ty = OpRt->getType(); 996 const Type Ty = OpRt->getType();
843 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 997 switch (typeWidthInBytesLog2(Ty)) {
844 return setNeedsTextFixup(); 998 case 3:
845 const bool IsByte = isByteSizedType(Ty); 999 // LDRD is not implemented because target lowering handles i64 and double by
846 IValueT Address; 1000 // using two (32-bit) load instructions. Note: Intenionally drop to default
847 switch (decodeAddress(OpAddress, Address, TInfo)) { 1001 // case.
848 default: 1002 default:
849 return setNeedsTextFixup(); 1003 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) +
850 case DecodedAsImmRegOffset: { 1004 " not implementable using ldr\n");
851 // LDR (immediate) - ARM section A8.8.63, encoding A1: 1005 case 0: {
852 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1006 // Handles i1 and i8 loads.
853 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
854 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
855 // 1007 //
856 // LDRB (immediate) - ARM section A8.8.68, encoding A1: 1008 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
857 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1009 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
858 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 1010 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
859 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 1011 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
860 // 1012 //
861 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 1013 // cccc010pu1w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
862 // iiiiiiiiiiii=imm12, b=1 if LDRB, u=1 if +, pu0w is a BlockAddr, and 1014 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
863 // pu0w0nnnn0000iiiiiiiiiiii=Address. 1015 // pu0w0nnnn0000iiiiiiiiiiii=Address.
864 1016 //
865 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 1017 // LDRB (register) - ARM section A8.8.66, encoding A1:
866 1018 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
867 // Check if conditions of rules violated. 1019 // ldrb<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
868 if (Rn == RegARM32::Encoded_Reg_pc) 1020 //
869 return setNeedsTextFixup(); 1021 // cccc011pu1w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
870 if (!isBitSet(P, Address) && isBitSet(W, Address)) 1022 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
871 return setNeedsTextFixup(); 1023 constexpr bool IsByte = true;
872 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) && 1024 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo);
873 isBitSet(U, Address) & !isBitSet(W, Address) &&
874 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
875 return setNeedsTextFixup();
876
877 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
878 } 1025 }
879 case DecodedAsShiftRotateImm5: { 1026 case 1: {
880 // LDR (register) - ARM section A8.8.66, encoding A1: 1027 // Handles i16 loads.
881 // ldr<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
882 // ldr<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
883 // 1028 //
884 // LDRB (register) - ARM section A8.8.70, encoding A1: 1029 // LDRH (immediate) - ARM section A8.8.80, encoding A1:
1030 // ldrh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
1031 // ldrh<c> <Rt>, [<Rn>], #+/-<Imm8>
1032 // ldrh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
1033 //
1034 // cccc000pu1w1nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1035 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
1036 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1037 return emitMemOpEnc3(Cond, L | B7 | B5 | B4, Rt, OpAddress, TInfo);
1038 }
1039 case 2: {
1040 // Note: Handles i32 and float loads. Target lowering handles i64 and
1041 // double by using two (32 bit) load instructions.
1042 //
1043 // LDR (immediate) - ARM section A8.8.63, encoding A1:
1044 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1045 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1046 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1047 //
1048 // cccc010pu0w1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1049 // iiiiiiiiiiii=imm12, u=1 if +, pu0w is a BlockAddr, and
1050 //
1051 // LDR (register) - ARM section A8.8.70, encoding A1:
885 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 1052 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
886 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>} 1053 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>}
887 // 1054 //
888 // cccc011pubw1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, 1055 // cccc011pu0w1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, U=1 if +, pu0b
889 // b=1 if LDRB, U=1 if +, pu0b is a BlockAddr, and 1056 // is a BlockAddr, and pu0w0nnnn0000iiiiiss0mmmm=Address.
890 // pu0w0nnnn0000iiiiiss0mmmm=Address. 1057 constexpr bool IsByte = false;
891 1058 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo);
892 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
893 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
894
895 // Check if conditions of rules violated.
896 if (isBitSet(P, Address) && isBitSet(W, Address))
897 // Instruction LDRBT!
898 return setNeedsTextFixup();
899 if (IsByte &&
900 ((Rt == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc)))
901 // Unpredictable.
902 return setNeedsTextFixup();
903 if (!IsByte && Rm == RegARM32::Encoded_Reg_pc)
904 // Unpredictable.
905 return setNeedsTextFixup();
906 if (isBitSet(W, Address) &&
907 ((Rn == RegARM32::Encoded_Reg_pc) || encodeGPRRegister(Rn) == Rt))
908 // Unpredictable
909 return setNeedsTextFixup();
910
911 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
912 } 1059 }
913 } 1060 }
914 } 1061 }
915 1062
916 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm, 1063 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
917 const Operand *OpSrc1, bool SetFlags, 1064 const Operand *OpSrc1, bool SetFlags,
918 CondARM32::Cond Cond) { 1065 CondARM32::Cond Cond) {
919 constexpr IValueT Lsl = B3 | B2 | B0; // 1101 1066 constexpr IValueT Lsl = B3 | B2 | B0; // 1101
920 constexpr IValueT Rn = 0; // Rn field is not used. 1067 constexpr IValueT Rn = 0; // Rn field is not used.
921 IValueT Rd; 1068 IValueT Rd;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1267 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1121 Rm == RegARM32::Encoded_Reg_pc) 1268 Rm == RegARM32::Encoded_Reg_pc)
1122 llvm::report_fatal_error("Sdiv instruction unpredictable on pc"); 1269 llvm::report_fatal_error("Sdiv instruction unpredictable on pc");
1123 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1270 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1124 constexpr IValueT Opcode = 0; 1271 constexpr IValueT Opcode = 0;
1125 emitDivOp(Cond, Opcode, Rd, Rn, Rm); 1272 emitDivOp(Cond, Opcode, Rd, Rn, Rm);
1126 } 1273 }
1127 1274
1128 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 1275 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
1129 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1276 CondARM32::Cond Cond, const TargetInfo &TInfo) {
1277 constexpr bool IsLoad = false;
1130 IValueT Rt; 1278 IValueT Rt;
1131 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1279 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
1132 return setNeedsTextFixup(); 1280 return setNeedsTextFixup();
1133 IValueT Address; 1281 const Type Ty = OpRt->getType();
1134 if (decodeAddress(OpAddress, Address, TInfo) != DecodedAsImmRegOffset) 1282 switch (typeWidthInBytesLog2(Ty)) {
1283 case 3:
1284 // STRD is not implemented because target lowering handles i64 and double by
1285 // using two (32-bit) store instructions. Note: Intenionally drop to
1286 // default case.
1287 default:
1288 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) +
1289 " not implementable using str\n");
1290 case 0: {
1291 // Handles i1 and i8 stores.
1292 //
1293 // STRB (immediate) - ARM section A8.8.207, encoding A1:
1294 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1295 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1296 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1297 //
1298 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1299 // iiiiiiiiiiii=imm12, u=1 if +.
1300 constexpr bool IsByte = true;
1301 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo);
1302 }
1303 case 1: {
1304 // Handles i16 stores.
1305 //
1306 // STRH (immediate) - ARM section A8.*.217, encoding A1:
1307 // strh<c> <Rt>, [<Rn>{, #+/-<Imm8>}]
1308 // strh<c> <Rt>, [<Rn>], #+/-<Imm8>
1309 // strh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
1310 //
1311 // cccc000pu1w0nnnnttttiiii1011iiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1312 // iiiiiiii=Imm8, u=1 if +, pu0w is a BlockAddr, and
1313 // pu0w0nnnn0000iiiiiiiiiiii=Address.
1314 return emitMemOpEnc3(Cond, B7 | B5 | B4, Rt, OpAddress, TInfo);
1315 }
1316 case 2: {
1317 // Note: Handles i32 and float stores. Target lowering handles i64 and
1318 // double by using two (32 bit) store instructions.
1319 //
1320 // STR (immediate) - ARM section A8.8.207, encoding A1:
1321 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1322 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1323 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1324 //
1325 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1326 // iiiiiiiiiiii=imm12, u=1 if +.
1327 constexpr bool IsByte = false;
1328 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo);
1135 return setNeedsTextFixup(); 1329 return setNeedsTextFixup();
1136 // STR (immediate) - ARM section A8.8.204, encoding A1: 1330 }
1137 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 1331 }
1138 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1139 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1140 // STRB (immediate) - ARM section A8.8.207, encoding A1:
1141 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
1142 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
1143 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
1144 //
1145 // cccc010pubw0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
1146 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
1147 constexpr bool IsLoad = false;
1148 const Type Ty = OpRt->getType();
1149 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
1150 return setNeedsTextFixup();
1151 const bool IsByte = isByteSizedType(Ty);
1152 // Check for rule violations.
1153 if ((getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc))
1154 return setNeedsTextFixup();
1155 if (!isBitSet(P, Address) && isBitSet(W, Address))
1156 return setNeedsTextFixup();
1157 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) &&
1158 isBitSet(P, Address) && !isBitSet(U, Address) && isBitSet(W, Address) &&
1159 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
1160 return setNeedsTextFixup();
1161 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
1162 } 1332 }
1163 1333
1164 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, 1334 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn,
1165 const Operand *OpSrc1, bool SetFlags, 1335 const Operand *OpSrc1, bool SetFlags,
1166 CondARM32::Cond Cond) { 1336 CondARM32::Cond Cond) {
1167 // ORR (register) - ARM Section A8.8.123, encoding A1: 1337 // ORR (register) - ARM Section A8.8.123, encoding A1:
1168 // orr{s}<c> <Rd>, <Rn>, <Rm> 1338 // orr{s}<c> <Rd>, <Rn>, <Rm>
1169 // 1339 //
1170 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 1340 // cccc0001100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
1171 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags. 1341 // mmmm=Rm, iiiii=shift, tt=ShiftKind,, and s=SetFlags.
(...skipping 12 matching lines...) Expand all
1184 // pop<c> {Rt} 1354 // pop<c> {Rt}
1185 // 1355 //
1186 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. 1356 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
1187 IValueT Rt; 1357 IValueT Rt;
1188 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1358 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
1189 return setNeedsTextFixup(); 1359 return setNeedsTextFixup();
1190 assert(Rt != RegARM32::Encoded_Reg_sp); 1360 assert(Rt != RegARM32::Encoded_Reg_sp);
1191 // Same as load instruction. 1361 // Same as load instruction.
1192 constexpr bool IsLoad = true; 1362 constexpr bool IsLoad = true;
1193 constexpr bool IsByte = false; 1363 constexpr bool IsByte = false;
1194 IValueT Address = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, 1364 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
1195 OperandARM32Mem::PostIndex); 1365 OperandARM32Mem::PostIndex);
1196 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); 1366 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
1197 } 1367 }
1198 1368
1199 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { 1369 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
1200 // POP - ARM section A8.*.131, encoding A1: 1370 // POP - ARM section A8.*.131, encoding A1:
1201 // pop<c> <registers> 1371 // pop<c> <registers>
1202 // 1372 //
1203 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and 1373 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
1204 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1374 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1205 constexpr bool IsLoad = true; 1375 constexpr bool IsLoad = true;
1206 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); 1376 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
1207 } 1377 }
1208 1378
1209 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { 1379 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
1210 // PUSH - ARM section A8.8.133, encoding A2: 1380 // PUSH - ARM section A8.8.133, encoding A2:
1211 // push<c> {Rt} 1381 // push<c> {Rt}
1212 // 1382 //
1213 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. 1383 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
1214 IValueT Rt; 1384 IValueT Rt;
1215 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1385 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
1216 return setNeedsTextFixup(); 1386 return setNeedsTextFixup();
1217 assert(Rt != RegARM32::Encoded_Reg_sp); 1387 assert(Rt != RegARM32::Encoded_Reg_sp);
1218 // Same as store instruction. 1388 // Same as store instruction.
1219 constexpr bool isLoad = false; 1389 constexpr bool isLoad = false;
1220 constexpr bool isByte = false; 1390 constexpr bool isByte = false;
1221 IValueT Address = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, 1391 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
1222 OperandARM32Mem::PreIndex); 1392 OperandARM32Mem::PreIndex);
1223 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); 1393 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address);
1224 } 1394 }
1225 1395
1226 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { 1396 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
1227 // PUSH - ARM section A8.8.133, encoding A1: 1397 // PUSH - ARM section A8.8.133, encoding A1:
1228 // push<c> <Registers> 1398 // push<c> <Registers>
1229 // 1399 //
1230 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and 1400 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
1231 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1401 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 // rr defined (RotationValue) rotate. 1577 // rr defined (RotationValue) rotate.
1408 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; 1578 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20;
1409 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1579 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation);
1410 return; 1580 return;
1411 } 1581 }
1412 } 1582 }
1413 } 1583 }
1414 1584
1415 } // end of namespace ARM32 1585 } // end of namespace ARM32
1416 } // end of namespace Ice 1586 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698