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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1458523002: Add LDR/LDRB (register) to ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 1 month 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 | « no previous file | 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 95
96 // Div instruction register field encodings. 96 // Div instruction register field encodings.
97 static constexpr IValueT kDivRdShift = 16; 97 static constexpr IValueT kDivRdShift = 16;
98 static constexpr IValueT kDivRmShift = 8; 98 static constexpr IValueT kDivRmShift = 8;
99 static constexpr IValueT kDivRnShift = 0; 99 static constexpr IValueT kDivRnShift = 0;
100 100
101 // Type of instruction encoding (bits 25-27). See ARM section A5.1 101 // Type of instruction encoding (bits 25-27). See ARM section A5.1
102 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000 102 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000
103 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001 103 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001
104 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010 104 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010
105 static constexpr IValueT kInstTypeRegisterShift = 3; // i.e. 011
105 106
106 // Offset modifier to current PC for next instruction. The offset is off by 8 107 // Offset modifier to current PC for next instruction. The offset is off by 8
107 // due to the way the ARM CPUs read PC. 108 // due to the way the ARM CPUs read PC.
108 static constexpr IOffsetT kPCReadOffset = 8; 109 static constexpr IOffsetT kPCReadOffset = 8;
109 110
110 // Mask to pull out PC offset from branch (b) instruction. 111 // Mask to pull out PC offset from branch (b) instruction.
111 static constexpr int kBranchOffsetBits = 24; 112 static constexpr int kBranchOffsetBits = 24;
112 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; 113 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff;
113 114
114 inline IValueT encodeBool(bool B) { return B ? 1 : 0; } 115 inline IValueT encodeBool(bool B) { return B ? 1 : 0; }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 enum DecodedResult { 181 enum DecodedResult {
181 // Unable to decode, value left undefined. 182 // Unable to decode, value left undefined.
182 CantDecode = 0, 183 CantDecode = 0,
183 // Value is register found. 184 // Value is register found.
184 DecodedAsRegister, 185 DecodedAsRegister,
185 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 186 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8
186 // value. 187 // value.
187 DecodedAsRotatedImm8, 188 DecodedAsRotatedImm8,
188 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, 189 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn,
189 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to 190 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to
190 // Rn should be used, and iiiiiiiiiiii is the offset. 191 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
191 DecodedAsImmRegOffset, 192 DecodedAsImmRegOffset,
193 // i.e. 0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
194 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
195 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
196 // writeback to Rn.
197 DecodedAsShiftRotateImm5,
192 // Value is 32bit integer constant. 198 // Value is 32bit integer constant.
193 DecodedAsConstI32 199 DecodedAsConstI32
194 }; 200 };
195 201
196 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 202 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
197 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 203 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
198 assert(RotateAmt < (1 << kRotateBits)); 204 assert(RotateAmt < (1 << kRotateBits));
199 assert(Immed8 < (1 << kImmed8Bits)); 205 assert(Immed8 < (1 << kImmed8Bits));
200 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); 206 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
201 } 207 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 if (BaseRegNum == Variable::NoRegister) { 262 if (BaseRegNum == Variable::NoRegister) {
257 BaseRegNum = TInfo.FrameOrStackReg; 263 BaseRegNum = TInfo.FrameOrStackReg;
258 if (!TInfo.HasFramePointer) 264 if (!TInfo.HasFramePointer)
259 Offset += TInfo.StackAdjustment; 265 Offset += TInfo.StackAdjustment;
260 } 266 }
261 Value = decodeImmRegOffset(decodeGPRRegister(BaseRegNum), Offset, 267 Value = decodeImmRegOffset(decodeGPRRegister(BaseRegNum), Offset,
262 OperandARM32Mem::Offset); 268 OperandARM32Mem::Offset);
263 return DecodedAsImmRegOffset; 269 return DecodedAsImmRegOffset;
264 } 270 }
265 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { 271 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) {
266 if (Mem->isRegReg())
267 // TODO(kschimpf) Add this case.
268 return CantDecode;
269 Variable *Var = Mem->getBase(); 272 Variable *Var = Mem->getBase();
270 if (!Var->hasReg()) 273 if (!Var->hasReg())
271 return CantDecode; 274 return CantDecode;
275 IValueT Rn = Var->getRegNum();
276 if (Mem->isRegReg()) {
277 const Variable *Index = Mem->getIndex();
278 if (Var == nullptr)
279 return CantDecode;
280 Value = (Rn << kRnShift) | Mem->getAddrMode() |
281 encodeShiftRotateImm5(Index->getRegNum(), Mem->getShiftOp(),
282 Mem->getShiftAmt());
283 return DecodedAsShiftRotateImm5;
284 }
285 // Decoded as immediate register offset.
272 ConstantInteger32 *Offset = Mem->getOffset(); 286 ConstantInteger32 *Offset = Mem->getOffset();
273 Value = decodeImmRegOffset(decodeGPRRegister(Var->getRegNum()), 287 Value = decodeImmRegOffset(decodeGPRRegister(Rn), Offset->getValue(),
274 Offset->getValue(), Mem->getAddrMode()); 288 Mem->getAddrMode());
275 return DecodedAsImmRegOffset; 289 return DecodedAsImmRegOffset;
276 } 290 }
277 return CantDecode; 291 return CantDecode;
278 } 292 }
279 293
280 // Checks that Offset can fit in imm24 constant of branch (b) instruction. 294 // Checks that Offset can fit in imm24 constant of branch (b) instruction.
281 bool canEncodeBranchOffset(IOffsetT Offset) { 295 bool canEncodeBranchOffset(IOffsetT Offset) {
282 return Utils::IsAligned(Offset, 4) && 296 return Utils::IsAligned(Offset, 4) &&
283 Utils::IsInt(kBranchOffsetBits, Offset >> 2); 297 Utils::IsInt(kBranchOffsetBits, Offset >> 2);
284 } 298 }
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8 730 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8
717 // 731 //
718 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 732 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
719 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 733 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
720 constexpr IValueT Eor = B0; // 0001 734 constexpr IValueT Eor = B0; // 0001
721 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond); 735 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond);
722 } 736 }
723 737
724 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 738 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
725 CondARM32::Cond Cond, const TargetInfo &TInfo) { 739 CondARM32::Cond Cond, const TargetInfo &TInfo) {
740 constexpr bool IsLoad = true;
726 IValueT Rt; 741 IValueT Rt;
727 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 742 if (decodeOperand(OpRt, Rt) != DecodedAsRegister)
728 return setNeedsTextFixup(); 743 return setNeedsTextFixup();
729 IValueT Address;
730 if (decodeAddress(OpAddress, Address, TInfo) != DecodedAsImmRegOffset)
731 return setNeedsTextFixup();
732 // LDR (immediate) - ARM section A8.8.63, encoding A1:
733 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
734 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
735 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
736 //
737 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
738 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
739 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
740 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
741 //
742 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
743 // iiiiiiiiiiii=imm12, b=1 if STRB, u=1 if +.
744 constexpr bool IsLoad = true;
745 const Type Ty = OpRt->getType(); 744 const Type Ty = OpRt->getType();
746 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand? 745 if (!(Ty == IceType_i32 || Ty == IceType_i8)) // TODO(kschimpf) Expand?
747 return setNeedsTextFixup(); 746 return setNeedsTextFixup();
748 const bool IsByte = isByteSizedType(Ty); 747 const bool IsByte = isByteSizedType(Ty);
749 // Check conditions of rules violated. 748 IValueT Address;
750 if (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_pc) 749 switch (decodeAddress(OpAddress, Address, TInfo)) {
750 default:
751 return setNeedsTextFixup(); 751 return setNeedsTextFixup();
752 if (!isBitSet(P, Address) && isBitSet(W, Address)) 752 case DecodedAsImmRegOffset: {
753 return setNeedsTextFixup(); 753 // LDR (immediate) - ARM section A8.8.63, encoding A1:
754 if (!IsByte && (getGPRReg(kRnShift, Address) == RegARM32::Encoded_Reg_sp) && 754 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
755 !isBitSet(P, Address) && isBitSet(U, Address) & !isBitSet(W, Address) && 755 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
756 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) 756 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
757 return setNeedsTextFixup(); 757 //
758 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); 758 // LDRB (immediate) - ARM section A8.8.68, encoding A1:
759 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0
760 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1
761 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
762 //
763 // cccc010pubw1nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
764 // iiiiiiiiiiii=imm12, b=1 if LDRB, u=1 if +, pu0w is a BlockAddr, and
765 // pu0w0nnnn0000iiiiiiiiiiii=Address.
766
767 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
768
769 // Check if conditions of rules violated.
770 if (Rn == RegARM32::Encoded_Reg_pc)
771 return setNeedsTextFixup();
772 if (!isBitSet(P, Address) && isBitSet(W, Address))
773 return setNeedsTextFixup();
774 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
775 isBitSet(U, Address) & !isBitSet(W, Address) &&
776 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
777 return setNeedsTextFixup();
778
779 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
780 }
781 case DecodedAsShiftRotateImm5: {
782 // LDR (register) - ARM section A8.8.66, encoding A1:
783 // ldr<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
784 // ldr<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
785 //
786 // LDRB (register) - ARM section A8.8.70, encoding A1:
787 // ldrb<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
788 // ldrb<c> <Rt>, [<Rn>], +-<Rm>{, <shift>}
789 //
790 // cccc011pubw1nnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
791 // b=1 if LDRB, U=1 if +, pu0b is a BlockAddr, and
792 // pu0w0nnnn0000iiiiiss0mmmm=Address.
793
794 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
795 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
796
797 // Check if conditions of rules violated.
798 if (isBitSet(P, Address) && isBitSet(W, Address))
799 // Instruction LDRBT!
800 return setNeedsTextFixup();
801 if (IsByte &&
802 ((Rt == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc)))
803 // Unpredictable.
804 return setNeedsTextFixup();
805 if (!IsByte && Rm == RegARM32::Encoded_Reg_pc)
806 // Unpredictable.
807 return setNeedsTextFixup();
808 if (isBitSet(W, Address) &&
809 ((Rn == RegARM32::Encoded_Reg_pc) || encodeGPRRegister(Rn) == Rt))
810 // Unpredictable
811 return setNeedsTextFixup();
812
813 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
814 }
815 }
759 } 816 }
760 817
761 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 818 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
762 CondARM32::Cond Cond) { 819 CondARM32::Cond Cond) {
763 // MOV (register) - ARM section A8.8.104, encoding A1: 820 // MOV (register) - ARM section A8.8.104, encoding A1:
764 // mov{S}<c> <Rd>, <Rn> 821 // mov{S}<c> <Rd>, <Rn>
765 // 822 //
766 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 823 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
767 // and nnnn=Rn. 824 // and nnnn=Rn.
768 // 825 //
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
1185 // rr defined (RotationValue) rotate. 1242 // rr defined (RotationValue) rotate.
1186 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; 1243 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20;
1187 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1244 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation);
1188 return; 1245 return;
1189 } 1246 }
1190 } 1247 }
1191 } 1248 }
1192 1249
1193 } // end of namespace ARM32 1250 } // end of namespace ARM32
1194 } // end of namespace Ice 1251 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698