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

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: Clean up CL. 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
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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 // Rn. 192 // Rn.
193 EncodedAsImmRegOffsetEnc3, 193 EncodedAsImmRegOffsetEnc3,
194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, 194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift 195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if 196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
197 // writeback to Rn. 197 // writeback to Rn.
198 EncodedAsShiftRotateImm5, 198 EncodedAsShiftRotateImm5,
199 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value 199 // Value=000000000000000000000iiiii0000000 where iiii defines the Imm5 value
200 // to shift. 200 // to shift.
201 EncodedAsShiftImm5, 201 EncodedAsShiftImm5,
202 // i.e. iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift 202 // Value=iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift
203 // kind, and iiiii is the shift amount. 203 // kind, and iiiii is the shift amount.
204 EncodedAsShiftedRegister, 204 EncodedAsShiftedRegister,
205 // Value=ssss0tt1mmmm where mmmm=Rm, tt is an encoded ShiftKind, and ssss=Rms.
206 EncodedAsRegShiftReg,
205 // Value is 32bit integer constant. 207 // Value is 32bit integer constant.
206 EncodedAsConstI32 208 EncodedAsConstI32
207 }; 209 };
208 210
209 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 211 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
210 IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 212 IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
211 assert(RotateAmt < (1 << kRotateBits)); 213 assert(RotateAmt < (1 << kRotateBits));
212 assert(Immed8 < (1 << kImmed8Bits)); 214 assert(Immed8 < (1 << kImmed8Bits));
213 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); 215 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
214 } 216 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 return CantEncode; 248 return CantEncode;
247 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 249 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
248 return EncodedAsRotatedImm8; 250 return EncodedAsRotatedImm8;
249 } 251 }
250 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { 252 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
251 Value = Const->getValue(); 253 Value = Const->getValue();
252 return EncodedAsConstI32; 254 return EncodedAsConstI32;
253 } 255 }
254 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) { 256 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
255 Operand *Amt = FlexReg->getShiftAmt(); 257 Operand *Amt = FlexReg->getShiftAmt();
256 if (const auto *Imm5 = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) { 258 IValueT Rm;
257 IValueT Rm; 259 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister)
258 if (encodeOperand(FlexReg->getReg(), Rm) != EncodedAsRegister) 260 return CantEncode;
261 if (const auto *Var = llvm::dyn_cast<Variable>(Amt)) {
262 IValueT Rs;
263 if (encodeOperand(Var, Rs) != EncodedAsRegister)
259 return CantEncode; 264 return CantEncode;
260 Value = 265 Value = encodeShiftRotateReg(Rm, FlexReg->getShiftOp(), Rs);
261 encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5->getShAmtImm()); 266 return EncodedAsRegShiftReg;
262 return EncodedAsShiftedRegister;
263 } 267 }
264 // TODO(kschimpf): Handle case where Amt is a register? 268 // If reached, the amount is a shifted amount by some 5-bit immediate.
269 uint32_t Imm5;
270 if (const auto *ShAmt = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
271 Imm5 = ShAmt->getShAmtImm();
272 } else if (const auto *IntConst = llvm::dyn_cast<ConstantInteger32>(Amt)) {
273 int32_t Val = IntConst->getValue();
John 2015/12/11 16:40:57 is this code path still exercised? it shouldn't be
Karl 2015/12/11 17:42:16 Look at tests_lit/assembler/arm32/mov-reg.ll. If y
274 if (Val < 0)
275 return CantEncode;
276 Imm5 = static_cast<uint32_t>(Val);
277 } else
278 return CantEncode;
279 Value = encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5);
280 return EncodedAsShiftedRegister;
265 } 281 }
266 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { 282 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
267 const IValueT Immed5 = ShImm->getShAmtImm(); 283 const IValueT Immed5 = ShImm->getShAmtImm();
268 assert(Immed5 < (1 << kShiftImmBits)); 284 assert(Immed5 < (1 << kShiftImmBits));
269 Value = (Immed5 << kShiftImmShift); 285 Value = (Immed5 << kShiftImmShift);
270 return EncodedAsShiftImm5; 286 return EncodedAsShiftImm5;
271 } 287 }
272 return CantEncode; 288 return CantEncode;
273 } 289 }
274 290
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 EmitChecks RuleChecks, const char *InstName) { 600 EmitChecks RuleChecks, const char *InstName) {
585 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); 601 IValueT Rd = encodeRegister(OpRd, "Rd", InstName);
586 IValueT Rn = encodeRegister(OpRn, "Rn", InstName); 602 IValueT Rn = encodeRegister(OpRn, "Rn", InstName);
587 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName); 603 emitType01(Cond, Opcode, Rd, Rn, OpSrc1, SetFlags, RuleChecks, InstName);
588 } 604 }
589 605
590 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode, 606 void AssemblerARM32::emitType01(CondARM32::Cond Cond, IValueT Opcode,
591 IValueT Rd, IValueT Rn, const Operand *OpSrc1, 607 IValueT Rd, IValueT Rn, const Operand *OpSrc1,
592 bool SetFlags, EmitChecks RuleChecks, 608 bool SetFlags, EmitChecks RuleChecks,
593 const char *InstName) { 609 const char *InstName) {
594
595 IValueT Src1Value; 610 IValueT Src1Value;
596 // TODO(kschimpf) Other possible decodings of data operations. 611 // TODO(kschimpf) Other possible decodings of data operations.
597 switch (encodeOperand(OpSrc1, Src1Value)) { 612 switch (encodeOperand(OpSrc1, Src1Value)) {
598 default: 613 default:
599 // TODO(kschimpf): Figure out what additional cases need to be handled. 614 llvm::report_fatal_error(std::string(InstName) +
600 return setNeedsTextFixup(); 615 ": Can't encode instruction");
616 return;
601 case EncodedAsRegister: { 617 case EncodedAsRegister: {
602 // XXX (register) 618 // XXX (register)
603 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 619 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
604 // 620 //
605 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 621 // cccc000xxxxsnnnnddddiiiiitt0mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
606 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 622 // nnnn=Rn, mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
607 constexpr IValueT Imm5 = 0; 623 constexpr IValueT Imm5 = 0;
608 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); 624 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
609 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 625 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
610 RuleChecks, InstName); 626 RuleChecks, InstName);
611 return; 627 return;
612 } 628 }
613 case EncodedAsShiftedRegister: { 629 case EncodedAsShiftedRegister: {
614 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)). 630 // Form is defined in case EncodedAsRegister. (i.e. XXX (register)).
615 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 631 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
616 RuleChecks, InstName); 632 RuleChecks, InstName);
617 return; 633 return;
618 } 634 }
619 case EncodedAsConstI32: { 635 case EncodedAsConstI32: {
620 // See if we can convert this to an XXX (immediate). 636 // See if we can convert this to an XXX (immediate).
621 IValueT RotateAmt; 637 IValueT RotateAmt;
622 IValueT Imm8; 638 IValueT Imm8;
623 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) 639 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
624 llvm::report_fatal_error(std::string(InstName) + 640 llvm::report_fatal_error(std::string(InstName) +
625 ": Immediate rotated constant not valid"); 641 ": Immediate rotated constant not valid");
626 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); 642 Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
627 // Intentionally fall to next case! 643 // Intentionally fall to next case!
628 } 644 }
629 case EncodedAsRotatedImm8: { 645 case EncodedAsRotatedImm8: {
630 // XXX (Immediate) 646 // XXX (Immediate)
631 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8> 647 // xxx{s}<c> <Rd>, <Rn>, #<RotatedImm8>
632 // 648 //
633 // cccc0010100snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, 649 // cccc001xxxxsnnnnddddiiiiiiiiiiii where cccc=Cond, xxxx=Opcode, dddd=Rd,
634 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. 650 // nnnn=Rn, s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8.
635 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd, 651 emitType01(Cond, kInstTypeDataImmediate, Opcode, SetFlags, Rn, Rd,
636 Src1Value, RuleChecks, InstName); 652 Src1Value, RuleChecks, InstName);
637 return; 653 return;
638 } 654 }
655 case EncodedAsRegShiftReg: {
656 // XXX (register-shifted reg)
657 // xxx{s}<c> <Rd>, <Rn>, <Rm>, <type> <Rs>
658 //
659 // cccc000xxxxfnnnnddddssss0tt1mmmm where cccc=Cond, xxxx=Opcode, dddd=Rd,
660 // nnnn=Rn, ssss=Rs, f=SetFlags, tt is encoding of type, and
661 // Src1Value=ssss01tt1mmmm.
662 emitType01(Cond, kInstTypeDataRegShift, Opcode, SetFlags, Rn, Rd, Src1Value,
663 RuleChecks, InstName);
664 return;
665 }
639 } 666 }
640 } 667 }
641 668
642 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset, 669 void AssemblerARM32::emitType05(CondARM32::Cond Cond, IOffsetT Offset,
643 bool Link, const char *InstName) { 670 bool Link, const char *InstName) {
644 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and 671 // cccc101liiiiiiiiiiiiiiiiiiiiiiii where cccc=Cond, l=Link, and
645 // iiiiiiiiiiiiiiiiiiiiiiii= 672 // iiiiiiiiiiiiiiiiiiiiiiii=
646 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset); 673 // EncodedBranchOffset(cccc101l000000000000000000000000, Offset);
647 verifyCondDefined(Cond, InstName); 674 verifyCondDefined(Cond, InstName);
648 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 675 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 1731
1705 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, 1732 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0,
1706 CondARM32::Cond Cond) { 1733 CondARM32::Cond Cond) {
1707 constexpr const char *UxtName = "uxt"; 1734 constexpr const char *UxtName = "uxt";
1708 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; 1735 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21;
1709 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); 1736 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName);
1710 } 1737 }
1711 1738
1712 } // end of namespace ARM32 1739 } // end of namespace ARM32
1713 } // end of namespace Ice 1740 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/mov-reg.ll » ('j') | tests_lit/assembler/arm32/mov-reg.ll » ('J')

Powered by Google App Engine
This is Rietveld 408576698