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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1490383002: Clean up use of encode/decode in the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. 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 | « 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 // Extract out a Bit in Value. 170 // Extract out a Bit in Value.
171 inline bool isBitSet(IValueT Bit, IValueT Value) { 171 inline bool isBitSet(IValueT Bit, IValueT Value) {
172 return (Value & Bit) == Bit; 172 return (Value & Bit) == Bit;
173 } 173 }
174 174
175 // Returns the GPR register at given Shift in Value. 175 // Returns the GPR register at given Shift in Value.
176 inline RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { 176 inline RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) {
177 return decodeGPRRegister((Value >> Shift) & 0xF); 177 return decodeGPRRegister((Value >> Shift) & 0xF);
178 } 178 }
179 179
180 // The way an operand was decoded in functions decodeOperand and decodeAddress 180 // The way an operand is encoded into a sequence of bits in functions
181 // below. 181 // encodeOperand and encodeAddress below.
182 enum DecodedResult { 182 enum EncodedOperand {
183 // Unable to decode, value left undefined. 183 // Unable to encode, value left undefined.
184 CantDecode = 0, 184 CantEncode = 0,
185 // Value is register found. 185 // Value is register found.
186 DecodedAsRegister, 186 EncodedAsRegister,
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 EncodedAsRotatedImm8,
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 EncodedAsImmRegOffset,
194 // Value=00000000pu0w0nnnn0000iiii0000jjjj where nnnn=Rn, iiiijjjj=Imm8, p=1 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 195 // if pre-indexed addressing, u=1 if offset positive, and w=1 if writeback to
196 // Rn. 196 // Rn.
197 DecodedAsImmRegOffsetEnc3, 197 EncodedAsImmRegOffsetEnc3,
198 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, 198 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
199 // 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
200 // 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
201 // writeback to Rn. 201 // writeback to Rn.
202 DecodedAsShiftRotateImm5, 202 EncodedAsShiftRotateImm5,
203 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value 203 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value
204 // to shift. 204 // to shift.
205 DecodedAsShiftImm5, 205 EncodedAsShiftImm5,
206 // 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
207 // kind, and iiiii is the shift amount. 207 // kind, and iiiii is the shift amount.
208 DecodedAsShiftedRegister, 208 EncodedAsShiftedRegister,
209 // Value is 32bit integer constant. 209 // Value is 32bit integer constant.
210 DecodedAsConstI32 210 EncodedAsConstI32
211 }; 211 };
212 212
213 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 213 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
214 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 214 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
215 assert(RotateAmt < (1 << kRotateBits)); 215 assert(RotateAmt < (1 << kRotateBits));
216 assert(Immed8 < (1 << kImmed8Bits)); 216 assert(Immed8 < (1 << kImmed8Bits));
217 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); 217 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
218 } 218 }
219 219
220 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, 220 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
221 // tt=Shift, and mmmm=Rm. 221 // tt=Shift, and mmmm=Rm.
222 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, 222 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
223 IOffsetT imm5) { 223 IOffsetT imm5) {
224 (void)kShiftImmBits; 224 (void)kShiftImmBits;
225 assert(imm5 < (1 << kShiftImmBits)); 225 assert(imm5 < (1 << kShiftImmBits));
226 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; 226 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
227 } 227 }
228 228
229 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and 229 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and
230 // tt=Shift. 230 // tt=Shift.
231 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, 231 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
232 IValueT Rs) { 232 IValueT Rs) {
233 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | 233 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
234 (Rm << kRmShift); 234 (Rm << kRmShift);
235 } 235 }
236 236
237 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { 237 EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value) {
238 Value = 0; // Make sure initialized. 238 Value = 0; // Make sure initialized.
239 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 239 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
240 if (Var->hasReg()) { 240 if (Var->hasReg()) {
241 Value = Var->getRegNum(); 241 Value = Var->getRegNum();
242 return DecodedAsRegister; 242 return EncodedAsRegister;
243 } 243 }
244 return CantDecode; 244 return CantEncode;
245 } 245 }
246 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 246 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
247 const IValueT Immed8 = FlexImm->getImm(); 247 const IValueT Immed8 = FlexImm->getImm();
248 const IValueT Rotate = FlexImm->getRotateAmt(); 248 const IValueT Rotate = FlexImm->getRotateAmt();
249 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) 249 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
250 return CantDecode; 250 return CantEncode;
251 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 251 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
252 return DecodedAsRotatedImm8; 252 return EncodedAsRotatedImm8;
253 } 253 }
254 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { 254 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
255 Value = Const->getValue(); 255 Value = Const->getValue();
256 return DecodedAsConstI32; 256 return EncodedAsConstI32;
257 } 257 }
258 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { 258 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
259 Operand *Amt = FlexReg->getShiftAmt(); 259 Operand *Amt = FlexReg->getShiftAmt();
260 if (const auto *Imm5 = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { 260 if (const auto *Imm5 = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
261 IValueT Rm; 261 IValueT Rm;
262 if (decodeOperand(FlexReg->getReg(), Rm) != DecodedAsRegister) 262 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister)
263 return CantDecode; 263 return CantEncode;
264 Value = 264 Value =
265 encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5->getShAmtImm()); 265 encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5->getShAmtImm());
266 return DecodedAsShiftedRegister; 266 return EncodedAsShiftedRegister;
267 } 267 }
268 // TODO(kschimpf): Handle case where Amt is a register? 268 // TODO(kschimpf): Handle case where Amt is a register?
269 } 269 }
270 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { 270 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
271 const IValueT Immed5 = ShImm->getShAmtImm(); 271 const IValueT Immed5 = ShImm->getShAmtImm();
272 assert(Immed5 < (1 << kShiftImmBits)); 272 assert(Immed5 < (1 << kShiftImmBits));
273 Value = (Immed5 << kShiftImmShift); 273 Value = (Immed5 << kShiftImmShift);
274 return DecodedAsShiftImm5; 274 return EncodedAsShiftImm5;
275 } 275 }
276 return CantDecode; 276 return CantEncode;
277 } 277 }
278 278
279 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset, 279 IValueT encodeImmRegOffset(IValueT Reg, IOffsetT Offset,
280 OperandARM32Mem::AddrMode Mode) { 280 OperandARM32Mem::AddrMode Mode) {
281 IValueT Value = Mode | (Reg << kRnShift); 281 IValueT Value = Mode | (Reg << kRnShift);
282 if (Offset < 0) { 282 if (Offset < 0) {
283 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. 283 Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
284 } else { 284 } else {
285 Value |= Offset; 285 Value |= Offset;
286 } 286 }
(...skipping 15 matching lines...) Expand all
302 302
303 // Defines alternate layouts of instruction operands, should the (common) 303 // Defines alternate layouts of instruction operands, should the (common)
304 // default pattern not be used. 304 // default pattern not be used.
305 enum OpEncoding { 305 enum OpEncoding {
306 // No alternate layout specified. 306 // No alternate layout specified.
307 DefaultOpEncoding, 307 DefaultOpEncoding,
308 // Alternate encoding 3. 308 // Alternate encoding 3.
309 OpEncoding3 309 OpEncoding3
310 }; 310 };
311 311
312 // Decodes memory address Opnd, and encodes that information into Value, 312 // Encodes memory address Opnd, and encodes that information into Value, based
313 // based on how ARM represents the address. Returns how the value was encoded. 313 // on how ARM represents the address. Returns how the value was encoded.
314 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value, 314 EncodedOperand encodeAddress(const Operand *Opnd, IValueT &Value,
315 const AssemblerARM32::TargetInfo &TInfo, 315 const AssemblerARM32::TargetInfo &TInfo,
316 OpEncoding AddressEncoding = DefaultOpEncoding) { 316 OpEncoding AddressEncoding = DefaultOpEncoding) {
317 Value = 0; // Make sure initialized. 317 Value = 0; // Make sure initialized.
318 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 318 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
319 // Should be a stack variable, with an offset. 319 // Should be a stack variable, with an offset.
320 if (Var->hasReg()) 320 if (Var->hasReg())
321 return CantDecode; 321 return CantEncode;
322 IOffsetT Offset = Var->getStackOffset(); 322 IOffsetT Offset = Var->getStackOffset();
323 if (!Utils::IsAbsoluteUint(12, Offset)) 323 if (!Utils::IsAbsoluteUint(12, Offset))
324 return CantDecode; 324 return CantEncode;
325 int32_t BaseRegNum = Var->getBaseRegNum(); 325 int32_t BaseRegNum = Var->getBaseRegNum();
326 if (BaseRegNum == Variable::NoRegister) 326 if (BaseRegNum == Variable::NoRegister)
327 BaseRegNum = TInfo.FrameOrStackReg; 327 BaseRegNum = TInfo.FrameOrStackReg;
328 Value = encodeImmRegOffset(BaseRegNum, Offset, OperandARM32Mem::Offset); 328 Value = encodeImmRegOffset(BaseRegNum, Offset, OperandARM32Mem::Offset);
329 return DecodedAsImmRegOffset; 329 return EncodedAsImmRegOffset;
330 } 330 }
331 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { 331 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) {
332 Variable *Var = Mem->getBase(); 332 Variable *Var = Mem->getBase();
333 if (!Var->hasReg()) 333 if (!Var->hasReg())
334 return CantDecode; 334 return CantEncode;
335 IValueT Rn = Var->getRegNum(); 335 IValueT Rn = Var->getRegNum();
336 if (Mem->isRegReg()) { 336 if (Mem->isRegReg()) {
337 const Variable *Index = Mem->getIndex(); 337 const Variable *Index = Mem->getIndex();
338 if (Var == nullptr) 338 if (Var == nullptr)
339 return CantDecode; 339 return CantEncode;
340 Value = (Rn << kRnShift) | Mem->getAddrMode() | 340 Value = (Rn << kRnShift) | Mem->getAddrMode() |
341 encodeShiftRotateImm5(Index->getRegNum(), Mem->getShiftOp(), 341 encodeShiftRotateImm5(Index->getRegNum(), Mem->getShiftOp(),
342 Mem->getShiftAmt()); 342 Mem->getShiftAmt());
343 return DecodedAsShiftRotateImm5; 343 return EncodedAsShiftRotateImm5;
344 } 344 }
345 // Decoded as immediate register offset. 345 // Encoded as immediate register offset.
346 ConstantInteger32 *Offset = Mem->getOffset(); 346 ConstantInteger32 *Offset = Mem->getOffset();
347 switch (AddressEncoding) { 347 switch (AddressEncoding) {
348 case DefaultOpEncoding: 348 case DefaultOpEncoding:
349 Value = encodeImmRegOffset(Rn, Offset->getValue(), Mem->getAddrMode()); 349 Value = encodeImmRegOffset(Rn, Offset->getValue(), Mem->getAddrMode());
350 return DecodedAsImmRegOffset; 350 return EncodedAsImmRegOffset;
351 case OpEncoding3: 351 case OpEncoding3:
352 Value = 352 Value =
353 encodeImmRegOffsetEnc3(Rn, Offset->getValue(), Mem->getAddrMode()); 353 encodeImmRegOffsetEnc3(Rn, Offset->getValue(), Mem->getAddrMode());
354 return DecodedAsImmRegOffsetEnc3; 354 return EncodedAsImmRegOffsetEnc3;
355 } 355 }
356 } 356 }
357 return CantDecode; 357 return CantEncode;
358 } 358 }
359 359
360 // 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.
361 bool canEncodeBranchOffset(IOffsetT Offset) { 361 bool canEncodeBranchOffset(IOffsetT Offset) {
362 return Utils::IsAligned(Offset, 4) && 362 return Utils::IsAligned(Offset, 4) &&
363 Utils::IsInt(kBranchOffsetBits, Offset >> 2); 363 Utils::IsInt(kBranchOffsetBits, Offset >> 2);
364 } 364 }
365 365
366 } // end of anonymous namespace 366 } // end of anonymous namespace
367 367
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 assert(IsGoodOffset); 454 assert(IsGoodOffset);
455 // Note: Following cast is for MINIMAL build. 455 // Note: Following cast is for MINIMAL build.
456 (void)IsGoodOffset; 456 (void)IsGoodOffset;
457 457
458 // Properly preserve only the bits supported in the instruction. 458 // Properly preserve only the bits supported in the instruction.
459 Offset >>= 2; 459 Offset >>= 2;
460 Offset &= kBranchOffsetMask; 460 Offset &= kBranchOffsetMask;
461 return (Inst & ~kBranchOffsetMask) | Offset; 461 return (Inst & ~kBranchOffsetMask) | Offset;
462 } 462 }
463 463
464 // Pull out offset from branch Inst.
464 IOffsetT AssemblerARM32::decodeBranchOffset(IValueT Inst) { 465 IOffsetT AssemblerARM32::decodeBranchOffset(IValueT Inst) {
465 // Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC. 466 // Sign-extend, left-shift by 2, and adjust to the way ARM CPUs read PC.
466 IOffsetT Offset = static_cast<IOffsetT>((Inst & kBranchOffsetMask) << 8); 467 IOffsetT Offset = static_cast<IOffsetT>((Inst & kBranchOffsetMask) << 8);
467 return (Offset >> 6) + kPCReadOffset; 468 return (Offset >> 6) + kPCReadOffset;
468 } 469 }
469 470
470 void AssemblerARM32::bind(Label *L) { 471 void AssemblerARM32::bind(Label *L) {
471 IOffsetT BoundPc = Buffer.size(); 472 IOffsetT BoundPc = Buffer.size();
472 assert(!L->isBound()); // Labels can only be bound once. 473 assert(!L->isBound()); // Labels can only be bound once.
473 while (L->isLinked()) { 474 while (L->isLinked()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 (encodeBool(SetFlags) << kSShift) | 512 (encodeBool(SetFlags) << kSShift) |
512 (Rn << kRnShift) | (Rd << kRdShift) | Imm12; 513 (Rn << kRnShift) | (Rd << kRdShift) | Imm12;
513 emitInst(Encoding); 514 emitInst(Encoding);
514 } 515 }
515 516
516 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd, 517 void AssemblerARM32::emitType01(IValueT Opcode, const Operand *OpRd,
517 const Operand *OpRn, const Operand *OpSrc1, 518 const Operand *OpRn, const Operand *OpSrc1,
518 bool SetFlags, CondARM32::Cond Cond, 519 bool SetFlags, CondARM32::Cond Cond,
519 EmitChecks RuleChecks) { 520 EmitChecks RuleChecks) {
520 IValueT Rd; 521 IValueT Rd;
521 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 522 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
522 return setNeedsTextFixup(); 523 return setNeedsTextFixup();
523 IValueT Rn; 524 IValueT Rn;
524 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 525 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
525 return setNeedsTextFixup(); 526 return setNeedsTextFixup();
526 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, RuleChecks); 527 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, RuleChecks);
527 } 528 }
528 529
529 void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn, 530 void AssemblerARM32::emitType01(IValueT Opcode, IValueT Rd, IValueT Rn,
530 const Operand *OpSrc1, bool SetFlags, 531 const Operand *OpSrc1, bool SetFlags,
531 CondARM32::Cond Cond, EmitChecks RuleChecks) { 532 CondARM32::Cond Cond, EmitChecks RuleChecks) {
532 533
533 IValueT Src1Value; 534 IValueT Src1Value;
534 // TODO(kschimpf) Other possible decodings of data operations. 535 // TODO(kschimpf) Other possible decodings of data operations.
535 switch (decodeOperand(OpSrc1, Src1Value)) { 536 switch (encodeOperand(OpSrc1, Src1Value)) {
536 default: 537 default:
537 return setNeedsTextFixup(); 538 return setNeedsTextFixup();
538 case DecodedAsRegister: { 539 case EncodedAsRegister: {
539 // XXX (register) 540 // XXX (register)
540 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 541 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
541 // 542 //
542 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 543 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
543 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 544 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
544 constexpr IValueT Imm5 = 0; 545 constexpr IValueT Imm5 = 0;
545 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); 546 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
546 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 547 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
547 RuleChecks); 548 RuleChecks);
548 return; 549 return;
549 } 550 }
550 case DecodedAsShiftedRegister: { 551 case EncodedAsShiftedRegister: {
551 // Form is defined in case DecodedAsRegister. (i.e. XXX (register)). 552 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)).
552 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 553 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
553 RuleChecks); 554 RuleChecks);
554 return; 555 return;
555 } 556 }
556 case DecodedAsConstI32: { 557 case EncodedAsConstI32: {
557 // See if we can convert this to an XXX (immediate). 558 // See if we can convert this to an XXX (immediate).
558 IValueT RotateAmt; 559 IValueT RotateAmt;
559 IValueT Imm8; 560 IValueT Imm8;
560 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) 561 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
561 return setNeedsTextFixup(); 562 return setNeedsTextFixup();
562 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); 563 Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
563 // Intentionally fall to next case! 564 // Intentionally fall to next case!
564 } 565 }
565 case DecodedAsRotatedImm8: { 566 case EncodedAsRotatedImm8: {
566 // XXX (Immediate) 567 // XXX (Immediate)
567 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> 568 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
568 // 569 //
569 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 570 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
570 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 571 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
571 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, 572 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
572 Src1Value, RuleChecks); 573 Src1Value, RuleChecks);
573 return; 574 return;
574 } 575 }
575 } 576 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 // 616 //
616 // XXX (immediate) 617 // XXX (immediate)
617 // XXX<c> <Rn>, #<RotatedImm8> 618 // XXX<c> <Rn>, #<RotatedImm8>
618 // 619 //
619 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 620 // ccccyyyxxxx1nnnn0000iiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
620 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value 621 // yyy=kInstTypeDataImmdiate, xxxx=Opcode, and iiiiiiiiiiii=Src1Value
621 // defining RotatedImm8. 622 // defining RotatedImm8.
622 constexpr bool SetFlags = true; 623 constexpr bool SetFlags = true;
623 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0; 624 constexpr IValueT Rd = RegARM32::Encoded_Reg_r0;
624 IValueT Rn; 625 IValueT Rn;
625 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 626 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
626 return setNeedsTextFixup(); 627 return setNeedsTextFixup();
627 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, NoChecks); 628 emitType01(Opcode, Rd, Rn, OpSrc1, SetFlags, Cond, NoChecks);
628 } 629 }
629 630
630 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType, 631 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, IValueT InstType,
631 bool IsLoad, bool IsByte, IValueT Rt, 632 bool IsLoad, bool IsByte, IValueT Rt,
632 IValueT Address) { 633 IValueT Address) {
633 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 634 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond))
634 return setNeedsTextFixup(); 635 return setNeedsTextFixup();
635 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 636 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
636 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 637 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
637 (InstType << kTypeShift) | (IsLoad ? L : 0) | 638 (InstType << kTypeShift) | (IsLoad ? L : 0) |
638 (IsByte ? B : 0) | (Rt << kRdShift) | Address; 639 (IsByte ? B : 0) | (Rt << kRdShift) | Address;
639 emitInst(Encoding); 640 emitInst(Encoding);
640 } 641 }
641 642
642 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte, 643 void AssemblerARM32::emitMemOp(CondARM32::Cond Cond, bool IsLoad, bool IsByte,
643 IValueT Rt, const Operand *OpAddress, 644 IValueT Rt, const Operand *OpAddress,
644 const TargetInfo &TInfo) { 645 const TargetInfo &TInfo) {
645 IValueT Address; 646 IValueT Address;
646 switch (decodeAddress(OpAddress, Address, TInfo)) { 647 switch (encodeAddress(OpAddress, Address, TInfo)) {
647 default: 648 default:
648 return setNeedsTextFixup(); 649 return setNeedsTextFixup();
649 case DecodedAsImmRegOffset: { 650 case EncodedAsImmRegOffset: {
650 // XXX{B} (immediate): 651 // XXX{B} (immediate):
651 // xxx{b}<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 652 // 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=1, w=1
653 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 654 // xxx{b}<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1
654 // 655 //
655 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, 656 // cccc010pubwlnnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn,
656 // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and 657 // iiiiiiiiiiii=imm12, b=IsByte, pu0w<<21 is a BlockAddr, l=IsLoad, and
657 // pu0w0nnnn0000iiiiiiiiiiii=Address. 658 // pu0w0nnnn0000iiiiiiiiiiii=Address.
658 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 659 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
659 660
660 // Check if conditions of rules violated. 661 // Check if conditions of rules violated.
661 if (Rn == RegARM32::Encoded_Reg_pc) 662 if (Rn == RegARM32::Encoded_Reg_pc)
662 return setNeedsTextFixup(); 663 return setNeedsTextFixup();
663 if (!isBitSet(P, Address) && isBitSet(W, Address)) 664 if (!isBitSet(P, Address) && isBitSet(W, Address))
664 return setNeedsTextFixup(); 665 return setNeedsTextFixup();
665 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) && 666 if (!IsByte && (Rn == RegARM32::Encoded_Reg_sp) && !isBitSet(P, Address) &&
666 isBitSet(U, Address) & !isBitSet(W, Address) && 667 isBitSet(U, Address) & !isBitSet(W, Address) &&
667 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */)) 668 (mask(Address, kImm12Shift, kImmed12Bits) == 0x8 /* 000000000100 */))
668 return setNeedsTextFixup(); 669 return setNeedsTextFixup();
669 670
670 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); 671 return emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
671 } 672 }
672 case DecodedAsShiftRotateImm5: { 673 case EncodedAsShiftRotateImm5: {
673 // XXX{B} (register) 674 // XXX{B} (register)
674 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!} 675 // xxx{b}<c> <Rt>, [<Rn>, +/-<Rm>{, <shift>}]{!}
675 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>} 676 // xxx{b}<c> <Rt>, [<Rn>], +/-<Rm>{, <shift>}
676 // 677 //
677 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt, 678 // cccc011pubwlnnnnttttiiiiiss0mmmm where cccc=Cond, tttt=Rt,
678 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and 679 // b=IsByte, U=1 if +, pu0b is a BlockAddr, l=IsLoad, and
679 // pu0w0nnnn0000iiiiiss0mmmm=Address. 680 // pu0w0nnnn0000iiiiiss0mmmm=Address.
680 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address); 681 RegARM32::GPRRegister Rn = getGPRReg(kRnShift, Address);
681 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address); 682 RegARM32::GPRRegister Rm = getGPRReg(kRmShift, Address);
682 683
(...skipping 15 matching lines...) Expand all
698 699
699 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address); 700 return emitMemOp(Cond, kInstTypeRegisterShift, IsLoad, IsByte, Rt, Address);
700 } 701 }
701 } 702 }
702 } 703 }
703 704
704 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode, 705 void AssemblerARM32::emitMemOpEnc3(CondARM32::Cond Cond, IValueT Opcode,
705 IValueT Rt, const Operand *OpAddress, 706 IValueT Rt, const Operand *OpAddress,
706 const TargetInfo &TInfo) { 707 const TargetInfo &TInfo) {
707 IValueT Address; 708 IValueT Address;
708 switch (decodeAddress(OpAddress, Address, TInfo, OpEncoding3)) { 709 switch (encodeAddress(OpAddress, Address, TInfo, OpEncoding3)) {
709 default: 710 default:
710 return setNeedsTextFixup(); 711 return setNeedsTextFixup();
711 case DecodedAsImmRegOffsetEnc3: { 712 case EncodedAsImmRegOffsetEnc3: {
712 // XXXH (immediate) 713 // XXXH (immediate)
713 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}] 714 // xxxh<c> <Rt>, [<Rn>{, #+-<Imm8>}]
714 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>] 715 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]
715 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]! 716 // xxxh<c> <Rt>, [<Rn>, #+/-<Imm8>]!
716 // 717 //
717 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt, 718 // cccc000pu0wxnnnnttttiiiiyyyyjjjj where cccc=Cond, nnnn=Rn, tttt=Rt,
718 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, 719 // iiiijjjj=Imm8, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode,
719 // and pu0w0nnnn0000iiii0000jjjj=Address. 720 // and pu0w0nnnn0000iiii0000jjjj=Address.
720 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 721 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond))
721 return setNeedsTextFixup(); 722 return setNeedsTextFixup();
722 if (!isBitSet(P, Address) && isBitSet(W, Address)) 723 if (!isBitSet(P, Address) && isBitSet(W, Address))
723 return setNeedsTextFixup(); 724 return setNeedsTextFixup();
724 if ((Rt == RegARM32::Encoded_Reg_pc) || 725 if ((Rt == RegARM32::Encoded_Reg_pc) ||
725 (isBitSet(W, Address) && 726 (isBitSet(W, Address) &&
726 (getGPRReg(kRnShift, Address) == decodeGPRRegister(Rt)))) 727 (getGPRReg(kRnShift, Address) == decodeGPRRegister(Rt))))
727 return setNeedsTextFixup(); 728 return setNeedsTextFixup();
728 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | 729 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) |
729 Opcode | (Rt << kRdShift) | Address; 730 Opcode | (Rt << kRdShift) | Address;
730 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 731 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
731 return emitInst(Encoding); 732 return emitInst(Encoding);
732 } 733 }
733 case DecodedAsShiftRotateImm5: { 734 case EncodedAsShiftRotateImm5: {
734 // XXXH (register) 735 // XXXH (register)
735 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!} 736 // xxxh<c> <Rt>, [<Rn>, +/-<Rm>]{!}
736 // xxxh<c> <Rt>, [<Rn>], +/-<Rm> 737 // xxxh<c> <Rt>, [<Rn>], +/-<Rm>
737 // 738 //
738 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn, 739 // cccc000pu0wxnnnntttt00001011mmmm where cccc=Cond, tttt=Rt, nnnn=Rn,
739 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and 740 // mmmm=Rm, pu0w<<21 is a BlockAddr, x000000000000yyyy0000=Opcode, and
740 // pu0w0nnnn000000000000mmmm=Address. 741 // pu0w0nnnn000000000000mmmm=Address.
741 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond)) 742 if (!isGPRRegisterDefined(Rt) || !isConditionDefined(Cond))
742 return setNeedsTextFixup(); 743 return setNeedsTextFixup();
743 if (!isBitSet(P, Address) && isBitSet(W, Address)) 744 if (!isBitSet(P, Address) && isBitSet(W, Address))
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to. 915 // and iiiiiiiiiiiiiiiiiiiiiiii is the (encoded) Target to branch to.
915 emitFixup(createBlFixup(Target)); 916 emitFixup(createBlFixup(Target));
916 constexpr CondARM32::Cond Cond = CondARM32::AL; 917 constexpr CondARM32::Cond Cond = CondARM32::AL;
917 constexpr IValueT Immed = 0; 918 constexpr IValueT Immed = 0;
918 constexpr bool Link = true; 919 constexpr bool Link = true;
919 emitType05(Cond, Immed, Link); 920 emitType05(Cond, Immed, Link);
920 } 921 }
921 922
922 void AssemblerARM32::blx(const Operand *Target) { 923 void AssemblerARM32::blx(const Operand *Target) {
923 IValueT Rm; 924 IValueT Rm;
924 if (decodeOperand(Target, Rm) != DecodedAsRegister) 925 if (encodeOperand(Target, Rm) != EncodedAsRegister)
925 return setNeedsTextFixup(); 926 return setNeedsTextFixup();
926 // BLX (register) - ARM section A8.8.26, encoding A1: 927 // BLX (register) - ARM section A8.8.26, encoding A1:
927 // blx<c> <Rm> 928 // blx<c> <Rm>
928 // 929 //
929 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed) 930 // cccc000100101111111111110011mmmm where cccc=Cond (not currently allowed)
930 // and mmmm=Rm. 931 // and mmmm=Rm.
931 if (Rm == RegARM32::Encoded_Reg_pc) 932 if (Rm == RegARM32::Encoded_Reg_pc)
932 // Unpredictable. 933 // Unpredictable.
933 return setNeedsTextFixup(); 934 return setNeedsTextFixup();
934 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 935 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 985 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn,
985 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 986 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
986 constexpr IValueT Eor = B0; // 0001 987 constexpr IValueT Eor = B0; // 0001
987 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 988 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
988 } 989 }
989 990
990 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, 991 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress,
991 CondARM32::Cond Cond, const TargetInfo &TInfo) { 992 CondARM32::Cond Cond, const TargetInfo &TInfo) {
992 constexpr bool IsLoad = true; 993 constexpr bool IsLoad = true;
993 IValueT Rt; 994 IValueT Rt;
994 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 995 if (encodeOperand(OpRt, Rt) != EncodedAsRegister)
995 return setNeedsTextFixup(); 996 return setNeedsTextFixup();
996 const Type Ty = OpRt->getType(); 997 const Type Ty = OpRt->getType();
997 switch (typeWidthInBytesLog2(Ty)) { 998 switch (typeWidthInBytesLog2(Ty)) {
998 case 3: 999 case 3:
999 // LDRD is not implemented because target lowering handles i64 and double by 1000 // LDRD is not implemented because target lowering handles i64 and double by
1000 // using two (32-bit) load instructions. Note: Intenionally drop to default 1001 // using two (32-bit) load instructions. Note: Intenionally drop to default
1001 // case. 1002 // case.
1002 default: 1003 default:
1003 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) + 1004 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) +
1004 " not implementable using ldr\n"); 1005 " not implementable using ldr\n");
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 } 1060 }
1060 } 1061 }
1061 } 1062 }
1062 1063
1063 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm, 1064 void AssemblerARM32::lsl(const Operand *OpRd, const Operand *OpRm,
1064 const Operand *OpSrc1, bool SetFlags, 1065 const Operand *OpSrc1, bool SetFlags,
1065 CondARM32::Cond Cond) { 1066 CondARM32::Cond Cond) {
1066 constexpr IValueT Lsl = B3 | B2 | B0; // 1101 1067 constexpr IValueT Lsl = B3 | B2 | B0; // 1101
1067 constexpr IValueT Rn = 0; // Rn field is not used. 1068 constexpr IValueT Rn = 0; // Rn field is not used.
1068 IValueT Rd; 1069 IValueT Rd;
1069 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1070 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1070 return setNeedsTextFixup(); 1071 return setNeedsTextFixup();
1071 IValueT Rm; 1072 IValueT Rm;
1072 if (decodeOperand(OpRm, Rm) != DecodedAsRegister) 1073 if (encodeOperand(OpRm, Rm) != EncodedAsRegister)
1073 return setNeedsTextFixup(); 1074 return setNeedsTextFixup();
1074 IValueT Value; 1075 IValueT Value;
1075 switch (decodeOperand(OpSrc1, Value)) { 1076 switch (encodeOperand(OpSrc1, Value)) {
1076 default: 1077 default:
1077 return setNeedsTextFixup(); 1078 return setNeedsTextFixup();
1078 case DecodedAsShiftImm5: { 1079 case EncodedAsShiftImm5: {
1079 // LSL (immediate) - ARM section A8.8.94, encoding A1: 1080 // LSL (immediate) - ARM section A8.8.94, encoding A1:
1080 // lsl{s}<c> <Rd>, <Rm>, #imm5 1081 // lsl{s}<c> <Rd>, <Rm>, #imm5
1081 // 1082 //
1082 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1083 // cccc0001101s0000ddddiiiii000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1083 // iiiii=imm5, and mmmm=Rm. 1084 // iiiii=imm5, and mmmm=Rm.
1084 Value = Value | (Rm << kRmShift); 1085 Value = Value | (Rm << kRmShift);
1085 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, Value, 1086 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, Value,
1086 RdIsPcAndSetFlags); 1087 RdIsPcAndSetFlags);
1087 return; 1088 return;
1088 } 1089 }
1089 case DecodedAsRegister: { 1090 case EncodedAsRegister: {
1090 // LSL (register) - ARM section A8.8.95, encoding A1: 1091 // LSL (register) - ARM section A8.8.95, encoding A1:
1091 // lsl{S}<c> <Rd>, <Rm>, <Rs> 1092 // lsl{S}<c> <Rd>, <Rm>, <Rs>
1092 // 1093 //
1093 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1094 // cccc0001101s0000ddddssss0001mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1094 // mmmm=Rm, and ssss=Rs. 1095 // mmmm=Rm, and ssss=Rs.
1095 IValueT Rs; 1096 IValueT Rs;
1096 if (decodeOperand(OpSrc1, Rs) != DecodedAsRegister) 1097 if (encodeOperand(OpSrc1, Rs) != EncodedAsRegister)
1097 return setNeedsTextFixup(); 1098 return setNeedsTextFixup();
1098 if ((Rd == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc) || 1099 if ((Rd == RegARM32::Encoded_Reg_pc) || (Rm == RegARM32::Encoded_Reg_pc) ||
1099 (Rs == RegARM32::Encoded_Reg_pc)) 1100 (Rs == RegARM32::Encoded_Reg_pc))
1100 setNeedsTextFixup(); 1101 setNeedsTextFixup();
1101 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd, 1102 emitType01(Cond, kInstTypeDataRegShift, Lsl, SetFlags, Rn, Rd,
1102 encodeShiftRotateReg(Rm, OperandARM32::kNoShift, Rs), NoChecks); 1103 encodeShiftRotateReg(Rm, OperandARM32::kNoShift, Rs), NoChecks);
1103 return; 1104 return;
1104 } 1105 }
1105 } 1106 }
1106 } 1107 }
1107 1108
1108 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc, 1109 void AssemblerARM32::mov(const Operand *OpRd, const Operand *OpSrc,
1109 CondARM32::Cond Cond) { 1110 CondARM32::Cond Cond) {
1110 // MOV (register) - ARM section A8.8.104, encoding A1: 1111 // MOV (register) - ARM section A8.8.104, encoding A1:
1111 // mov{S}<c> <Rd>, <Rn> 1112 // mov{S}<c> <Rd>, <Rn>
1112 // 1113 //
1113 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd, 1114 // cccc0001101s0000dddd00000000mmmm where cccc=Cond, s=SetFlags, dddd=Rd,
1114 // and nnnn=Rn. 1115 // and nnnn=Rn.
1115 // 1116 //
1116 // MOV (immediate) - ARM section A8.8.102, encoding A1: 1117 // MOV (immediate) - ARM section A8.8.102, encoding A1:
1117 // mov{S}<c> <Rd>, #<RotatedImm8> 1118 // mov{S}<c> <Rd>, #<RotatedImm8>
1118 // 1119 //
1119 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd, 1120 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags, dddd=Rd,
1120 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this 1121 // and iiiiiiiiiiii=RotatedImm8=Src. Note: We don't use movs in this
1121 // assembler. 1122 // assembler.
1122 IValueT Rd; 1123 IValueT Rd;
1123 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1124 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1124 return setNeedsTextFixup(); 1125 return setNeedsTextFixup();
1125 constexpr bool SetFlags = false; 1126 constexpr bool SetFlags = false;
1126 constexpr IValueT Rn = 0; 1127 constexpr IValueT Rn = 0;
1127 constexpr IValueT Mov = B3 | B2 | B0; // 1101. 1128 constexpr IValueT Mov = B3 | B2 | B0; // 1101.
1128 emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags); 1129 emitType01(Mov, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags);
1129 } 1130 }
1130 1131
1131 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16, 1132 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16,
1132 bool SetFlags, CondARM32::Cond Cond) { 1133 bool SetFlags, CondARM32::Cond Cond) {
1133 if (!isConditionDefined(Cond) || !Utils::IsAbsoluteUint(16, Imm16)) 1134 if (!isConditionDefined(Cond) || !Utils::IsAbsoluteUint(16, Imm16))
1134 return setNeedsTextFixup(); 1135 return setNeedsTextFixup();
1135 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 1136 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
1136 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | 1137 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode |
1137 (encodeBool(SetFlags) << kSShift) | 1138 (encodeBool(SetFlags) << kSShift) |
1138 ((Imm16 >> 12) << 16) | Rd << kRdShift | 1139 ((Imm16 >> 12) << 16) | Rd << kRdShift |
1139 (Imm16 & 0xfff); 1140 (Imm16 & 0xfff);
1140 emitInst(Encoding); 1141 emitInst(Encoding);
1141 } 1142 }
1142 1143
1143 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, 1144 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc,
1144 CondARM32::Cond Cond) { 1145 CondARM32::Cond Cond) {
1145 IValueT Rd; 1146 IValueT Rd;
1146 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1147 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1147 return setNeedsTextFixup(); 1148 return setNeedsTextFixup();
1148 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { 1149 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) {
1149 // MOVW (immediate) - ARM section A8.8.102, encoding A2: 1150 // MOVW (immediate) - ARM section A8.8.102, encoding A2:
1150 // movw<c> <Rd>, #<imm16> 1151 // movw<c> <Rd>, #<imm16>
1151 // 1152 //
1152 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and 1153 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
1153 // iiiiiiiiiiiiiiii=imm16. 1154 // iiiiiiiiiiiiiiii=imm16.
1154 if (!isConditionDefined(Cond)) 1155 if (!isConditionDefined(Cond))
1155 // Conditions of rule violated. 1156 // Conditions of rule violated.
1156 return setNeedsTextFixup(); 1157 return setNeedsTextFixup();
1157 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to 1158 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to
1158 // install the correct bits. 1159 // install the correct bits.
1159 constexpr bool IsMovW = true; 1160 constexpr bool IsMovW = true;
1160 emitFixup(createMoveFixup(IsMovW, Src)); 1161 emitFixup(createMoveFixup(IsMovW, Src));
1161 constexpr IValueT Imm16 = 0; 1162 constexpr IValueT Imm16 = 0;
1162 constexpr bool SetFlags = false; 1163 constexpr bool SetFlags = false;
1163 emitMovw(B25 | B24, Rd, Imm16, SetFlags, Cond); 1164 emitMovw(B25 | B24, Rd, Imm16, SetFlags, Cond);
1164 return; 1165 return;
1165 } 1166 }
1166 IValueT ConstVal; 1167 IValueT ConstVal;
1167 if (decodeOperand(OpSrc, ConstVal) != DecodedAsConstI32) 1168 if (encodeOperand(OpSrc, ConstVal) != EncodedAsConstI32)
1168 return setNeedsTextFixup(); 1169 return setNeedsTextFixup();
1169 // TODO(kschimpf): Determine if we want to handle rotated immediate 8 values 1170 // TODO(kschimpf): Determine if we want to handle rotated immediate 8 values
1170 // to handle cases where the constant is greater than 16 bits (encoding A1 1171 // to handle cases where the constant is greater than 16 bits (encoding A1
1171 // below). For now, handle using encoding A2. 1172 // below). For now, handle using encoding A2.
1172 constexpr bool SetFlags = 0; 1173 constexpr bool SetFlags = 0;
1173 emitMovw(B25 | B24, Rd, ConstVal, SetFlags, Cond); 1174 emitMovw(B25 | B24, Rd, ConstVal, SetFlags, Cond);
1174 return; 1175 return;
1175 1176
1176 // MOVW (immediate) - ARM section A8.8.102, encoding A1: 1177 // MOVW (immediate) - ARM section A8.8.102, encoding A1:
1177 // movw<c> <Rd>, #<RotatedImm8> 1178 // movw<c> <Rd>, #<RotatedImm8>
1178 // 1179 //
1179 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, s=SetFlags=0, 1180 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, s=SetFlags=0,
1180 // and iiiiiiiiiiii is a shift-rotated value defining RotatedImm8. 1181 // and iiiiiiiiiiii is a shift-rotated value defining RotatedImm8.
1181 } 1182 }
1182 1183
1183 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc, 1184 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc,
1184 CondARM32::Cond Cond) { 1185 CondARM32::Cond Cond) {
1185 IValueT Rd; 1186 IValueT Rd;
1186 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1187 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1187 return setNeedsTextFixup(); 1188 return setNeedsTextFixup();
1188 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc); 1189 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc);
1189 if (Src == nullptr) 1190 if (Src == nullptr)
1190 return setNeedsTextFixup(); 1191 return setNeedsTextFixup();
1191 // MOVT - ARM section A8.8.102, encoding A2: 1192 // MOVT - ARM section A8.8.102, encoding A2:
1192 // movt<c> <Rd>, #<imm16> 1193 // movt<c> <Rd>, #<imm16>
1193 // 1194 //
1194 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and 1195 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and
1195 // iiiiiiiiiiiiiiii=imm16. 1196 // iiiiiiiiiiiiiiii=imm16.
1196 if (!isConditionDefined(Cond)) 1197 if (!isConditionDefined(Cond))
(...skipping 18 matching lines...) Expand all
1215 // 1216 //
1216 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, 1217 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd,
1217 // and iiiiiiiiiiii=const 1218 // and iiiiiiiiiiii=const
1218 // 1219 //
1219 // MVN (register) - ARM section A8.8.116, encoding A1: 1220 // MVN (register) - ARM section A8.8.116, encoding A1:
1220 // mvn{s}<c> <Rd>, <Rm>{, <shift> 1221 // mvn{s}<c> <Rd>, <Rm>{, <shift>
1221 // 1222 //
1222 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd, 1223 // cccc0001111s0000ddddiiiiitt0mmmm where cccc=Cond, s=SetFlags=0, dddd=Rd,
1223 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. 1224 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind.
1224 IValueT Rd; 1225 IValueT Rd;
1225 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1226 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1226 return setNeedsTextFixup(); 1227 return setNeedsTextFixup();
1227 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 1228 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111
1228 constexpr IValueT Rn = 0; 1229 constexpr IValueT Rn = 0;
1229 constexpr bool SetFlags = false; 1230 constexpr bool SetFlags = false;
1230 emitType01(MvnOpcode, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags); 1231 emitType01(MvnOpcode, Rd, Rn, OpSrc, SetFlags, Cond, RdIsPcAndSetFlags);
1231 } 1232 }
1232 1233
1233 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, 1234 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn,
1234 const Operand *OpSrc1, bool SetFlags, 1235 const Operand *OpSrc1, bool SetFlags,
1235 CondARM32::Cond Cond) { 1236 CondARM32::Cond Cond) {
(...skipping 13 matching lines...) Expand all
1249 } 1250 }
1250 1251
1251 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn, 1252 void AssemblerARM32::sdiv(const Operand *OpRd, const Operand *OpRn,
1252 const Operand *OpSrc1, CondARM32::Cond Cond) { 1253 const Operand *OpSrc1, CondARM32::Cond Cond) {
1253 // SDIV - ARM section A8.8.165, encoding A1. 1254 // SDIV - ARM section A8.8.165, encoding A1.
1254 // sdiv<c> <Rd>, <Rn>, <Rm> 1255 // sdiv<c> <Rd>, <Rn>, <Rm>
1255 // 1256 //
1256 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 1257 // cccc01110001dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
1257 // mmmm=Rm. 1258 // mmmm=Rm.
1258 IValueT Rd; 1259 IValueT Rd;
1259 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1260 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1260 return setNeedsTextFixup(); 1261 return setNeedsTextFixup();
1261 IValueT Rn; 1262 IValueT Rn;
1262 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 1263 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
1263 return setNeedsTextFixup(); 1264 return setNeedsTextFixup();
1264 IValueT Rm; 1265 IValueT Rm;
1265 if (decodeOperand(OpSrc1, Rm) != DecodedAsRegister) 1266 if (encodeOperand(OpSrc1, Rm) != EncodedAsRegister)
1266 return setNeedsTextFixup(); 1267 return setNeedsTextFixup();
1267 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1268 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1268 Rm == RegARM32::Encoded_Reg_pc) 1269 Rm == RegARM32::Encoded_Reg_pc)
1269 llvm::report_fatal_error("Sdiv instruction unpredictable on pc"); 1270 llvm::report_fatal_error("Sdiv instruction unpredictable on pc");
1270 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1271 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1271 constexpr IValueT Opcode = 0; 1272 constexpr IValueT Opcode = 0;
1272 emitDivOp(Cond, Opcode, Rd, Rn, Rm); 1273 emitDivOp(Cond, Opcode, Rd, Rn, Rm);
1273 } 1274 }
1274 1275
1275 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, 1276 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress,
1276 CondARM32::Cond Cond, const TargetInfo &TInfo) { 1277 CondARM32::Cond Cond, const TargetInfo &TInfo) {
1277 constexpr bool IsLoad = false; 1278 constexpr bool IsLoad = false;
1278 IValueT Rt; 1279 IValueT Rt;
1279 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1280 if (encodeOperand(OpRt, Rt) != EncodedAsRegister)
1280 return setNeedsTextFixup(); 1281 return setNeedsTextFixup();
1281 const Type Ty = OpRt->getType(); 1282 const Type Ty = OpRt->getType();
1282 switch (typeWidthInBytesLog2(Ty)) { 1283 switch (typeWidthInBytesLog2(Ty)) {
1283 case 3: 1284 case 3:
1284 // STRD is not implemented because target lowering handles i64 and double by 1285 // STRD is not implemented because target lowering handles i64 and double by
1285 // using two (32-bit) store instructions. Note: Intenionally drop to 1286 // using two (32-bit) store instructions. Note: Intenionally drop to
1286 // default case. 1287 // default case.
1287 default: 1288 default:
1288 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) + 1289 llvm::report_fatal_error(std::string("Type ") + typeString(Ty) +
1289 " not implementable using str\n"); 1290 " not implementable using str\n");
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 constexpr IValueT Orr = B3 | B2; // i.e. 1100 1349 constexpr IValueT Orr = B3 | B2; // i.e. 1100
1349 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags); 1350 emitType01(Orr, OpRd, OpRn, OpSrc1, SetFlags, Cond, RdIsPcAndSetFlags);
1350 } 1351 }
1351 1352
1352 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) { 1353 void AssemblerARM32::pop(const Operand *OpRt, CondARM32::Cond Cond) {
1353 // POP - ARM section A8.8.132, encoding A2: 1354 // POP - ARM section A8.8.132, encoding A2:
1354 // pop<c> {Rt} 1355 // pop<c> {Rt}
1355 // 1356 //
1356 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond. 1357 // cccc010010011101dddd000000000100 where dddd=Rt and cccc=Cond.
1357 IValueT Rt; 1358 IValueT Rt;
1358 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1359 if (encodeOperand(OpRt, Rt) != EncodedAsRegister)
1359 return setNeedsTextFixup(); 1360 return setNeedsTextFixup();
1360 assert(Rt != RegARM32::Encoded_Reg_sp); 1361 assert(Rt != RegARM32::Encoded_Reg_sp);
1361 // Same as load instruction. 1362 // Same as load instruction.
1362 constexpr bool IsLoad = true; 1363 constexpr bool IsLoad = true;
1363 constexpr bool IsByte = false; 1364 constexpr bool IsByte = false;
1364 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize, 1365 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, kWordSize,
1365 OperandARM32Mem::PostIndex); 1366 OperandARM32Mem::PostIndex);
1366 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address); 1367 emitMemOp(Cond, kInstTypeMemImmediate, IsLoad, IsByte, Rt, Address);
1367 } 1368 }
1368 1369
1369 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) { 1370 void AssemblerARM32::popList(const IValueT Registers, CondARM32::Cond Cond) {
1370 // POP - ARM section A8.*.131, encoding A1: 1371 // POP - ARM section A8.*.131, encoding A1:
1371 // pop<c> <registers> 1372 // pop<c> <registers>
1372 // 1373 //
1373 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and 1374 // cccc100010111101rrrrrrrrrrrrrrrr where cccc=Cond and
1374 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1375 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1375 constexpr bool IsLoad = true; 1376 constexpr bool IsLoad = true;
1376 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); 1377 emitMultiMemOp(Cond, IA_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
1377 } 1378 }
1378 1379
1379 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) { 1380 void AssemblerARM32::push(const Operand *OpRt, CondARM32::Cond Cond) {
1380 // PUSH - ARM section A8.8.133, encoding A2: 1381 // PUSH - ARM section A8.8.133, encoding A2:
1381 // push<c> {Rt} 1382 // push<c> {Rt}
1382 // 1383 //
1383 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond. 1384 // cccc010100101101dddd000000000100 where dddd=Rt and cccc=Cond.
1384 IValueT Rt; 1385 IValueT Rt;
1385 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) 1386 if (encodeOperand(OpRt, Rt) != EncodedAsRegister)
1386 return setNeedsTextFixup(); 1387 return setNeedsTextFixup();
1387 assert(Rt != RegARM32::Encoded_Reg_sp); 1388 assert(Rt != RegARM32::Encoded_Reg_sp);
1388 // Same as store instruction. 1389 // Same as store instruction.
1389 constexpr bool isLoad = false; 1390 constexpr bool isLoad = false;
1390 constexpr bool isByte = false; 1391 constexpr bool isByte = false;
1391 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize, 1392 IValueT Address = encodeImmRegOffset(RegARM32::Encoded_Reg_sp, -kWordSize,
1392 OperandARM32Mem::PreIndex); 1393 OperandARM32Mem::PreIndex);
1393 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address); 1394 emitMemOp(Cond, kInstTypeMemImmediate, isLoad, isByte, Rt, Address);
1394 } 1395 }
1395 1396
1396 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) { 1397 void AssemblerARM32::pushList(const IValueT Registers, CondARM32::Cond Cond) {
1397 // PUSH - ARM section A8.8.133, encoding A1: 1398 // PUSH - ARM section A8.8.133, encoding A1:
1398 // push<c> <Registers> 1399 // push<c> <Registers>
1399 // 1400 //
1400 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and 1401 // cccc100100101101rrrrrrrrrrrrrrrr where cccc=Cond and
1401 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register). 1402 // rrrrrrrrrrrrrrrr=Registers (one bit for each GP register).
1402 constexpr bool IsLoad = false; 1403 constexpr bool IsLoad = false;
1403 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers); 1404 emitMultiMemOp(Cond, DB_W, IsLoad, RegARM32::Encoded_Reg_sp, Registers);
1404 } 1405 }
1405 1406
1406 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn, 1407 void AssemblerARM32::mla(const Operand *OpRd, const Operand *OpRn,
1407 const Operand *OpRm, const Operand *OpRa, 1408 const Operand *OpRm, const Operand *OpRa,
1408 CondARM32::Cond Cond) { 1409 CondARM32::Cond Cond) {
1409 IValueT Rd; 1410 IValueT Rd;
1410 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1411 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1411 return setNeedsTextFixup(); 1412 return setNeedsTextFixup();
1412 IValueT Rn; 1413 IValueT Rn;
1413 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 1414 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
1414 return setNeedsTextFixup(); 1415 return setNeedsTextFixup();
1415 IValueT Rm; 1416 IValueT Rm;
1416 if (decodeOperand(OpRm, Rm) != DecodedAsRegister) 1417 if (encodeOperand(OpRm, Rm) != EncodedAsRegister)
1417 return setNeedsTextFixup(); 1418 return setNeedsTextFixup();
1418 IValueT Ra; 1419 IValueT Ra;
1419 if (decodeOperand(OpRa, Ra) != DecodedAsRegister) 1420 if (encodeOperand(OpRa, Ra) != EncodedAsRegister)
1420 return setNeedsTextFixup(); 1421 return setNeedsTextFixup();
1421 // MLA - ARM section A8.8.114, encoding A1. 1422 // MLA - ARM section A8.8.114, encoding A1.
1422 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra> 1423 // mla{s}<c> <Rd>, <Rn>, <Rm>, <Ra>
1423 // 1424 //
1424 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd, 1425 // cccc0000001sddddaaaammmm1001nnnn where cccc=Cond, s=SetFlags, dddd=Rd,
1425 // aaaa=Ra, mmmm=Rm, and nnnn=Rn. 1426 // aaaa=Ra, mmmm=Rm, and nnnn=Rn.
1426 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1427 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1427 Rm == RegARM32::Encoded_Reg_pc || Ra == RegARM32::Encoded_Reg_pc) 1428 Rm == RegARM32::Encoded_Reg_pc || Ra == RegARM32::Encoded_Reg_pc)
1428 llvm::report_fatal_error("Mul instruction unpredictable on pc"); 1429 llvm::report_fatal_error("Mul instruction unpredictable on pc");
1429 constexpr IValueT MlaOpcode = B21; 1430 constexpr IValueT MlaOpcode = B21;
1430 constexpr bool SetFlags = false; 1431 constexpr bool SetFlags = false;
1431 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 1432 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd.
1432 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, SetFlags); 1433 emitMulOp(Cond, MlaOpcode, Ra, Rd, Rn, Rm, SetFlags);
1433 } 1434 }
1434 1435
1435 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn, 1436 void AssemblerARM32::mul(const Operand *OpRd, const Operand *OpRn,
1436 const Operand *OpSrc1, bool SetFlags, 1437 const Operand *OpSrc1, bool SetFlags,
1437 CondARM32::Cond Cond) { 1438 CondARM32::Cond Cond) {
1438 IValueT Rd; 1439 IValueT Rd;
1439 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1440 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1440 return setNeedsTextFixup(); 1441 return setNeedsTextFixup();
1441 IValueT Rn; 1442 IValueT Rn;
1442 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 1443 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
1443 return setNeedsTextFixup(); 1444 return setNeedsTextFixup();
1444 IValueT Rm; 1445 IValueT Rm;
1445 if (decodeOperand(OpSrc1, Rm) != DecodedAsRegister) 1446 if (encodeOperand(OpSrc1, Rm) != EncodedAsRegister)
1446 return setNeedsTextFixup(); 1447 return setNeedsTextFixup();
1447 // MUL - ARM section A8.8.114, encoding A1. 1448 // MUL - ARM section A8.8.114, encoding A1.
1448 // mul{s}<c> <Rd>, <Rn>, <Rm> 1449 // mul{s}<c> <Rd>, <Rn>, <Rm>
1449 // 1450 //
1450 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, 1451 // cccc0000000sdddd0000mmmm1001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn,
1451 // mmmm=Rm, and s=SetFlags. 1452 // mmmm=Rm, and s=SetFlags.
1452 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1453 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1453 Rm == RegARM32::Encoded_Reg_pc) 1454 Rm == RegARM32::Encoded_Reg_pc)
1454 llvm::report_fatal_error("Mul instruction unpredictable on pc"); 1455 llvm::report_fatal_error("Mul instruction unpredictable on pc");
1455 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1456 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1456 constexpr IValueT MulOpcode = 0; 1457 constexpr IValueT MulOpcode = 0;
1457 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags); 1458 emitMulOp(Cond, MulOpcode, RegARM32::Encoded_Reg_r0, Rd, Rn, Rm, SetFlags);
1458 } 1459 }
1459 1460
1460 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn, 1461 void AssemblerARM32::udiv(const Operand *OpRd, const Operand *OpRn,
1461 const Operand *OpSrc1, CondARM32::Cond Cond) { 1462 const Operand *OpSrc1, CondARM32::Cond Cond) {
1462 // UDIV - ARM section A8.8.248, encoding A1. 1463 // UDIV - ARM section A8.8.248, encoding A1.
1463 // udiv<c> <Rd>, <Rn>, <Rm> 1464 // udiv<c> <Rd>, <Rn>, <Rm>
1464 // 1465 //
1465 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and 1466 // cccc01110011dddd1111mmmm0001nnnn where cccc=Cond, dddd=Rd, nnnn=Rn, and
1466 // mmmm=Rm. 1467 // mmmm=Rm.
1467 IValueT Rd; 1468 IValueT Rd;
1468 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1469 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1469 return setNeedsTextFixup(); 1470 return setNeedsTextFixup();
1470 IValueT Rn; 1471 IValueT Rn;
1471 if (decodeOperand(OpRn, Rn) != DecodedAsRegister) 1472 if (encodeOperand(OpRn, Rn) != EncodedAsRegister)
1472 return setNeedsTextFixup(); 1473 return setNeedsTextFixup();
1473 IValueT Rm; 1474 IValueT Rm;
1474 if (decodeOperand(OpSrc1, Rm) != DecodedAsRegister) 1475 if (encodeOperand(OpSrc1, Rm) != EncodedAsRegister)
1475 return setNeedsTextFixup(); 1476 return setNeedsTextFixup();
1476 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || 1477 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc ||
1477 Rm == RegARM32::Encoded_Reg_pc) 1478 Rm == RegARM32::Encoded_Reg_pc)
1478 llvm::report_fatal_error("Udiv instruction unpredictable on pc"); 1479 llvm::report_fatal_error("Udiv instruction unpredictable on pc");
1479 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 1480 // Assembler registers rd, rn, rm are encoded as rn, rm, rs.
1480 constexpr IValueT Opcode = B21; 1481 constexpr IValueT Opcode = B21;
1481 emitDivOp(Cond, Opcode, Rd, Rn, Rm); 1482 emitDivOp(Cond, Opcode, Rd, Rn, Rm);
1482 } 1483 }
1483 1484
1484 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, 1485 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 CondARM32::Cond Cond) { 1526 CondARM32::Cond Cond) {
1526 // UMULL - ARM section A8.8.257, encoding A1: 1527 // UMULL - ARM section A8.8.257, encoding A1:
1527 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm> 1528 // umull<c> <RdLo>, <RdHi>, <Rn>, <Rm>
1528 // 1529 //
1529 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn, 1530 // cccc0000100shhhhllllmmmm1001nnnn where hhhh=RdHi, llll=RdLo, nnnn=Rn,
1530 // mmmm=Rm, and s=SetFlags 1531 // mmmm=Rm, and s=SetFlags
1531 IValueT RdLo; 1532 IValueT RdLo;
1532 IValueT RdHi; 1533 IValueT RdHi;
1533 IValueT Rn; 1534 IValueT Rn;
1534 IValueT Rm; 1535 IValueT Rm;
1535 if (decodeOperand(OpRdLo, RdLo) != DecodedAsRegister || 1536 if (encodeOperand(OpRdLo, RdLo) != EncodedAsRegister ||
1536 decodeOperand(OpRdHi, RdHi) != DecodedAsRegister || 1537 encodeOperand(OpRdHi, RdHi) != EncodedAsRegister ||
1537 decodeOperand(OpRn, Rn) != DecodedAsRegister || 1538 encodeOperand(OpRn, Rn) != EncodedAsRegister ||
1538 decodeOperand(OpRm, Rm) != DecodedAsRegister) 1539 encodeOperand(OpRm, Rm) != EncodedAsRegister)
1539 return setNeedsTextFixup(); 1540 return setNeedsTextFixup();
1540 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc || 1541 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc ||
1541 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc || 1542 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc ||
1542 RdHi == RdLo) 1543 RdHi == RdLo)
1543 llvm::report_fatal_error("Umull instruction unpredictable on pc"); 1544 llvm::report_fatal_error("Umull instruction unpredictable on pc");
1544 constexpr bool SetFlags = false; 1545 constexpr bool SetFlags = false;
1545 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags); 1546 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags);
1546 } 1547 }
1547 1548
1548 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 1549 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
1549 CondARM32::Cond Cond) { 1550 CondARM32::Cond Cond) {
1550 IValueT Rd; 1551 IValueT Rd;
1551 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) 1552 if (encodeOperand(OpRd, Rd) != EncodedAsRegister)
1552 return setNeedsTextFixup(); 1553 return setNeedsTextFixup();
1553 // Note: For the moment, we assume no rotation is specified. 1554 // Note: For the moment, we assume no rotation is specified.
1554 RotationValue Rotation = kRotateNone; 1555 RotationValue Rotation = kRotateNone;
1555 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; 1556 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc;
1556 IValueT Rm; 1557 IValueT Rm;
1557 if (decodeOperand(OpSrc0, Rm) != DecodedAsRegister) 1558 if (encodeOperand(OpSrc0, Rm) != EncodedAsRegister)
1558 return setNeedsTextFixup(); 1559 return setNeedsTextFixup();
1559 switch (typeWidthInBytes(OpSrc0->getType())) { 1560 switch (typeWidthInBytes(OpSrc0->getType())) {
1560 default: 1561 default:
1561 return setNeedsTextFixup(); 1562 return setNeedsTextFixup();
1562 case 1: { 1563 case 1: {
1563 // UXTB - ARM section A8.8.274, encoding A1: 1564 // UXTB - ARM section A8.8.274, encoding A1:
1564 // uxtb<c> <Rd>, <Rm>{, <rotate>} 1565 // uxtb<c> <Rd>, <Rm>{, <rotate>}
1565 // 1566 //
1566 // cccc011011101111ddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and 1567 // cccc011011101111ddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
1567 // rr defined (RotationValue) rotate. 1568 // rr defined (RotationValue) rotate.
1568 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21; 1569 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21;
1569 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1570 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation);
1570 return; 1571 return;
1571 } 1572 }
1572 case 2: { 1573 case 2: {
1573 // UXTH - ARM section A8.8.276, encoding A1: 1574 // UXTH - ARM section A8.8.276, encoding A1:
1574 // uxth<c> <Rd>< <Rm>{, <rotate>} 1575 // uxth<c> <Rd>< <Rm>{, <rotate>}
1575 // 1576 //
1576 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and 1577 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and
1577 // rr defined (RotationValue) rotate. 1578 // rr defined (RotationValue) rotate.
1578 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; 1579 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20;
1579 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1580 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation);
1580 return; 1581 return;
1581 } 1582 }
1582 } 1583 }
1583 } 1584 }
1584 1585
1585 } // end of namespace ARM32 1586 } // end of namespace ARM32
1586 } // end of namespace Ice 1587 } // 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