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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1630863002: Clean up register+immediate addresses in ARM. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 4 years, 10 months 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 | no next file » | 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698