Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 if (!BuildDefs::dump()) | 453 if (!BuildDefs::dump()) |
| 454 return InstARM32::InstSize; | 454 return InstARM32::InstSize; |
| 455 Ostream &Str = Ctx->getStrEmit(); | 455 Ostream &Str = Ctx->getStrEmit(); |
| 456 IValueT Inst = Asm.load<IValueT>(position()); | 456 IValueT Inst = Asm.load<IValueT>(position()); |
| 457 Str << "\t" | 457 Str << "\t" |
| 458 << "bl\t" << symbol(Ctx) << "\t@ .word " | 458 << "bl\t" << symbol(Ctx) << "\t@ .word " |
| 459 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; | 459 << llvm::format_hex_no_prefix(Inst, 8) << "\n"; |
| 460 return InstARM32::InstSize; | 460 return InstARM32::InstSize; |
| 461 } | 461 } |
| 462 | 462 |
| 463 void AssemblerARM32::padWithNop(intptr_t Padding) { | |
| 464 constexpr intptr_t InstWidth = sizeof(IValueT); | |
| 465 assert(Padding % InstWidth == 0 && | |
| 466 "Padding not mulitple of instruction size"); | |
|
Jim Stichnoth
2015/12/08 19:54:58
multiple
Karl
2015/12/08 20:49:36
Done.
| |
| 467 for (intptr_t i = 0; i < Padding; i += InstWidth) | |
| 468 nop(); | |
| 469 } | |
| 470 | |
| 463 BlRelocatableFixup * | 471 BlRelocatableFixup * |
| 464 AssemblerARM32::createBlFixup(const ConstantRelocatable *BlTarget) { | 472 AssemblerARM32::createBlFixup(const ConstantRelocatable *BlTarget) { |
| 465 BlRelocatableFixup *F = | 473 BlRelocatableFixup *F = |
| 466 new (allocate<BlRelocatableFixup>()) BlRelocatableFixup(); | 474 new (allocate<BlRelocatableFixup>()) BlRelocatableFixup(); |
| 467 F->set_kind(llvm::ELF::R_ARM_CALL); | 475 F->set_kind(llvm::ELF::R_ARM_CALL); |
| 468 F->set_value(BlTarget); | 476 F->set_value(BlTarget); |
| 469 Buffer.installFixup(F); | 477 Buffer.installFixup(F); |
| 470 return F; | 478 return F; |
| 471 } | 479 } |
| 472 | 480 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 644 // TODO(kschimpf): Handle far jumps. | 652 // TODO(kschimpf): Handle far jumps. |
| 645 constexpr const char *BranchName = "b"; | 653 constexpr const char *BranchName = "b"; |
| 646 if (L->isBound()) { | 654 if (L->isBound()) { |
| 647 const int32_t Dest = L->getPosition() - Buffer.size(); | 655 const int32_t Dest = L->getPosition() - Buffer.size(); |
| 648 emitType05(Cond, Dest, Link, BranchName); | 656 emitType05(Cond, Dest, Link, BranchName); |
| 649 return; | 657 return; |
| 650 } | 658 } |
| 651 const IOffsetT Position = Buffer.size(); | 659 const IOffsetT Position = Buffer.size(); |
| 652 // Use the offset field of the branch instruction for linking the sites. | 660 // Use the offset field of the branch instruction for linking the sites. |
| 653 emitType05(Cond, L->getEncodedPosition(), Link, BranchName); | 661 emitType05(Cond, L->getEncodedPosition(), Link, BranchName); |
| 654 if (!needsTextFixup()) | 662 if (!needsTextFixup() && !getPreliminary()) |
|
Jim Stichnoth
2015/12/08 20:52:27
This is clearly a problem that affects all assembl
Karl
2015/12/08 21:38:11
Moved check inside linkTo() and nearLinkTo(). Code
| |
| 655 L->linkTo(Position); | 663 L->linkTo(Position); |
| 656 } | 664 } |
| 657 | 665 |
| 658 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode, | 666 void AssemblerARM32::emitCompareOp(CondARM32::Cond Cond, IValueT Opcode, |
| 659 const Operand *OpRn, const Operand *OpSrc1, | 667 const Operand *OpRn, const Operand *OpSrc1, |
| 660 const char *InstName) { | 668 const char *InstName) { |
| 661 // XXX (register) | 669 // XXX (register) |
| 662 // XXX<c> <Rn>, <Rm>{, <shift>} | 670 // XXX<c> <Rn>, <Rm>{, <shift>} |
| 663 // | 671 // |
| 664 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii | 672 // ccccyyyxxxx1nnnn0000iiiiitt0mmmm where cccc=Cond, nnnn=Rn, mmmm=Rm, iiiii |
| (...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1265 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. | 1273 // mmmm=Rm, iiii defines shift constant, and tt=ShiftKind. |
| 1266 constexpr const char *MvnName = "mvn"; | 1274 constexpr const char *MvnName = "mvn"; |
| 1267 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName); | 1275 IValueT Rd = encodeRegister(OpRd, "Rd", MvnName); |
| 1268 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 | 1276 constexpr IValueT MvnOpcode = B3 | B2 | B1 | B0; // i.e. 1111 |
| 1269 constexpr IValueT Rn = 0; | 1277 constexpr IValueT Rn = 0; |
| 1270 constexpr bool SetFlags = false; | 1278 constexpr bool SetFlags = false; |
| 1271 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, | 1279 emitType01(Cond, MvnOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, |
| 1272 MvnName); | 1280 MvnName); |
| 1273 } | 1281 } |
| 1274 | 1282 |
| 1283 void AssemblerARM32::nop(CondARM32::Cond Cond) { | |
| 1284 // NOP - Section A8.8.119, encoding A1: | |
| 1285 // nop<c> | |
| 1286 // | |
| 1287 // cccc0011001000001111000000000000 where cccc=Cond. | |
| 1288 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
| 1289 const IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | | |
| 1290 (B25 | B24 | B21 | B15 | B14 | B13 | B12); | |
| 1291 emitInst(Encoding); | |
| 1292 } | |
| 1293 | |
| 1275 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, | 1294 void AssemblerARM32::sbc(const Operand *OpRd, const Operand *OpRn, |
| 1276 const Operand *OpSrc1, bool SetFlags, | 1295 const Operand *OpSrc1, bool SetFlags, |
| 1277 CondARM32::Cond Cond) { | 1296 CondARM32::Cond Cond) { |
| 1278 // SBC (register) - ARM section 18.8.162, encoding A1: | 1297 // SBC (register) - ARM section 18.8.162, encoding A1: |
| 1279 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 1298 // sbc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 1280 // | 1299 // |
| 1281 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 1300 // cccc0000110snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 1282 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 1301 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 1283 // | 1302 // |
| 1284 // SBC (Immediate) - ARM section A8.8.161, encoding A1: | 1303 // SBC (Immediate) - ARM section A8.8.161, encoding A1: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1357 // double by using two (32 bit) store instructions. | 1376 // double by using two (32 bit) store instructions. |
| 1358 // | 1377 // |
| 1359 // STR (immediate) - ARM section A8.8.207, encoding A1: | 1378 // STR (immediate) - ARM section A8.8.207, encoding A1: |
| 1360 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 1379 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
| 1361 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 | 1380 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 |
| 1362 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 | 1381 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 |
| 1363 // | 1382 // |
| 1364 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, | 1383 // cccc010pu1w0nnnnttttiiiiiiiiiiii where cccc=Cond, tttt=Rt, nnnn=Rn, |
| 1365 // iiiiiiiiiiii=imm12, u=1 if +. | 1384 // iiiiiiiiiiii=imm12, u=1 if +. |
| 1366 constexpr bool IsByte = false; | 1385 constexpr bool IsByte = false; |
| 1367 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName); | 1386 return emitMemOp(Cond, IsLoad, IsByte, Rt, OpAddress, TInfo, StrName); |
|
John
2015/12/08 19:45:04
Optional: I know the language allows to return a v
Jim Stichnoth
2015/12/08 19:54:58
This pattern of returning a void expression was su
Karl
2015/12/08 19:58:35
I mainly started doing this because it was much ea
Karl
2015/12/08 20:49:36
Removing returns of this form.
| |
| 1368 return setNeedsTextFixup(); | |
| 1369 } | 1387 } |
| 1370 } | 1388 } |
| 1371 } | 1389 } |
| 1372 | 1390 |
| 1373 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, | 1391 void AssemblerARM32::orr(const Operand *OpRd, const Operand *OpRn, |
| 1374 const Operand *OpSrc1, bool SetFlags, | 1392 const Operand *OpSrc1, bool SetFlags, |
| 1375 CondARM32::Cond Cond) { | 1393 CondARM32::Cond Cond) { |
| 1376 // ORR (register) - ARM Section A8.8.123, encoding A1: | 1394 // ORR (register) - ARM Section A8.8.123, encoding A1: |
| 1377 // orr{s}<c> <Rd>, <Rn>, <Rm> | 1395 // orr{s}<c> <Rd>, <Rn>, <Rm> |
| 1378 // | 1396 // |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1623 // rr defined (RotationValue) rotate. | 1641 // rr defined (RotationValue) rotate. |
| 1624 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21 | B20; | 1642 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21 | B20; |
| 1625 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName); | 1643 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName); |
| 1626 return; | 1644 return; |
| 1627 } | 1645 } |
| 1628 } | 1646 } |
| 1629 } | 1647 } |
| 1630 | 1648 |
| 1631 } // end of namespace ARM32 | 1649 } // end of namespace ARM32 |
| 1632 } // end of namespace Ice | 1650 } // end of namespace Ice |
| OLD | NEW |