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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1516063002: Add some missing encodings in the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nit. 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 | tests_lit/assembler/arm32/mov-reg.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 // Rn. 196 // Rn.
197 EncodedAsImmRegOffsetEnc3, 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 EncodedAsShiftRotateImm5, 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 EncodedAsShiftImm5, 205 EncodedAsShiftImm5,
206 // i.e. iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift 206 // Value=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 EncodedAsShiftedRegister, 208 EncodedAsShiftedRegister,
209 // Value=ssss0tt1mmmm where mmmm=Rm, tt is an encoded ShiftKind, and ssss=Rms.
210 EncodedAsRegShiftReg,
209 // Value is 32bit integer constant. 211 // Value is 32bit integer constant.
210 EncodedAsConstI32 212 EncodedAsConstI32
211 }; 213 };
212 214
213 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 215 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
214 IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 216 IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
215 assert(RotateAmt < (1 << kRotateBits)); 217 assert(RotateAmt < (1 << kRotateBits));
216 assert(Immed8 < (1 << kImmed8Bits)); 218 assert(Immed8 < (1 << kImmed8Bits));
217 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); 219 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
218 } 220 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 return CantEncode; 252 return CantEncode;
251 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 253 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
252 return EncodedAsRotatedImm8; 254 return EncodedAsRotatedImm8;
253 } 255 }
254 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { 256 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
255 Value = Const->getValue(); 257 Value = Const->getValue();
256 return EncodedAsConstI32; 258 return EncodedAsConstI32;
257 } 259 }
258 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { 260 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
259 Operand *Amt = FlexReg->getShiftAmt(); 261 Operand *Amt = FlexReg->getShiftAmt();
260 if (const auto *Imm5 = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { 262 IValueT Rm;
261 IValueT Rm; 263 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister)
262 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister) 264 return CantEncode;
265 if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) {
266 IValueT Rs;
267 if (encodeOperand(Var, Rs) != EncodedAsRegister)
263 return CantEncode; 268 return CantEncode;
264 Value = 269 Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs);
265 encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5->getShAmtImm()); 270 return EncodedAsRegShiftReg;
266 return EncodedAsShiftedRegister;
267 } 271 }
268 // TODO(kschimpf): Handle case where Amt is a register? 272 // If reached, the amount is a shifted amount by some 5-bit immediate.
273 uint32_t Imm5;
274 if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
275 Imm5 = ShAmt->getShAmtImm();
276 } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) {
277 int32_t Val = IntConst->getValue();
278 if (Val < 0)
279 return CantEncode;
280 Imm5 = static_cast<uint32_t>(Val);
281 } else
282 return CantEncode;
283 Value = encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5);
284 return EncodedAsShiftedRegister;
269 } 285 }
270 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { 286 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
271 const IValueT Immed5 = ShImm->getShAmtImm(); 287 const IValueT Immed5 = ShImm->getShAmtImm();
272 assert(Immed5 < (1 << kShiftImmBits)); 288 assert(Immed5 < (1 << kShiftImmBits));
273 Value = (Immed5 << kShiftImmShift); 289 Value = (Immed5 << kShiftImmShift);
274 return EncodedAsShiftImm5; 290 return EncodedAsShiftImm5;
275 } 291 }
276 return CantEncode; 292 return CantEncode;
277 } 293 }
278 294
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 EmitChecks RuleChecks, const char *InstName) { 604 EmitChecks RuleChecks, const char *InstName) {
589 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 605 IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
590 IValueT Rn = encodeRegister(OpRn, "Rn", InstName); 606 IValueT Rn = encodeRegister(OpRn, "Rn", InstName);
591 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName); 607 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
592 } 608 }
593 609
594 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, 610 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
595 IValueT Rd, IValueT Rn, const Operand *OpSrc1, 611 IValueT Rd, IValueT Rn, const Operand *OpSrc1,
596 bool SetFlags, EmitChecks RuleChecks, 612 bool SetFlags, EmitChecks RuleChecks,
597 const char *InstName) { 613 const char *InstName) {
598
599 IValueT Src1Value; 614 IValueT Src1Value;
600 // TODO(kschimpf) Other possible decodings of data operations. 615 // TODO(kschimpf) Other possible decodings of data operations.
601 switch (encodeOperand(OpSrc1, Src1Value)) { 616 switch (encodeOperand(OpSrc1, Src1Value)) {
602 default: 617 default:
603 // TODO(kschimpf): Figure out what additional cases need to be handled. 618 llvm::report_fatal_error(std::string(InstName) +
604 return setNeedsTextFixup(); 619 ": Can't encode instruction");
620 return;
605 case EncodedAsRegister: { 621 case EncodedAsRegister: {
606 // XXX (register) 622 // XXX (register)
607 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 623 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
608 // 624 //
609 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 625 // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
610 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 626 // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
611 constexpr IValueT Imm5 = 0; 627 constexpr IValueT Imm5 = 0;
612 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); 628 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
613 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 629 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
614 RuleChecks, InstName); 630 RuleChecks, InstName);
615 return; 631 return;
616 } 632 }
617 case EncodedAsShiftedRegister: { 633 case EncodedAsShiftedRegister: {
618 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)). 634 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)).
619 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 635 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
620 RuleChecks, InstName); 636 RuleChecks, InstName);
621 return; 637 return;
622 } 638 }
623 case EncodedAsConstI32: { 639 case EncodedAsConstI32: {
624 // See if we can convert this to an XXX (immediate). 640 // See if we can convert this to an XXX (immediate).
625 IValueT RotateAmt; 641 IValueT RotateAmt;
626 IValueT Imm8; 642 IValueT Imm8;
627 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) 643 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
628 llvm::report_fatal_error(std::string(InstName) + 644 llvm::report_fatal_error(std::string(InstName) +
629 ": Immediate rotated constant not valid"); 645 ": Immediate rotated constant not valid");
630 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); 646 Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
631 // Intentionally fall to next case! 647 // Intentionally fall to next case!
632 } 648 }
633 case EncodedAsRotatedImm8: { 649 case EncodedAsRotatedImm8: {
634 // XXX (Immediate) 650 // XXX (Immediate)
635 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> 651 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
636 // 652 //
637 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 653 // cccc001xxxxsnnnnddddiiiiiiiiiiii where cccc=Cond, xxxx=Opcode, dddd=Rd,
638 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 654 // nnnn=Rn, s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
639 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, 655 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
640 Src1Value, RuleChecks, InstName); 656 Src1Value, RuleChecks, InstName);
641 return; 657 return;
642 } 658 }
659 case EncodedAsRegShiftReg: {
660 // XXX (register-shifted reg)
661 // xxx{s}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
662 //
663 // cccc000xxxxfnnnnddddssss0tt1mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
664 // nnnn=Rn, ssss=Rs, f=SetFlags, tt is encoding of type, and
665 // Src1Value=ssss01tt1mmmm.
666 emitType01(Cond, kInstTypeDataRegShift, Opcode, SetFlags, Rn, Rd, Src1Value,
667 RuleChecks, InstName);
668 return;
669 }
643 } 670 }
644 } 671 }
645 672
646 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, 673 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
647 bool Link, const char *InstName) { 674 bool Link, const char *InstName) {
648 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and 675 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
649 // iiiiiiiiiiiiiiiiiiiiiiii= 676 // iiiiiiiiiiiiiiiiiiiiiiii=
650 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); 677 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
651 verifyCondDefined(Cond, InstName); 678 verifyCondDefined(Cond, InstName);
652 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 679 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 1778
1752 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 1779 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
1753 CondARM32::Cond Cond) { 1780 CondARM32::Cond Cond) {
1754 constexpr const char *UxtName = "uxt"; 1781 constexpr const char *UxtName = "uxt";
1755 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; 1782 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
1756 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); 1783 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
1757 } 1784 }
1758 1785
1759 } // end of namespace ARM32 1786 } // end of namespace ARM32
1760 } // end of namespace Ice 1787 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/mov-reg.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698