1 //===- MSP430.cpp ---------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // The MSP430 is a 16-bit microcontroller RISC architecture. The instruction set 10 // has only 27 core instructions orthogonally augmented with a variety 11 // of addressing modes for source and destination operands. Entire address space 12 // of MSP430 is 64KB (the extended MSP430X architecture is not considered here). 13 // A typical MSP430 MCU has several kilobytes of RAM and ROM, plenty 14 // of peripherals and is generally optimized for a low power consumption. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "Symbols.h" 19 #include "Target.h" 20 #include "lld/Common/ErrorHandler.h" 21 #include "llvm/BinaryFormat/ELF.h" 22 #include "llvm/Support/Endian.h" 23 24 using namespace llvm; 25 using namespace llvm::object; 26 using namespace llvm::support::endian; 27 using namespace llvm::ELF; 28 using namespace lld; 29 using namespace lld::elf; 30 31 namespace { 32 class MSP430 final : public TargetInfo { 33 public: 34 MSP430(); 35 RelExpr getRelExpr(RelType type, const Symbol &s, 36 const uint8_t *loc) const override; 37 void relocate(uint8_t *loc, const Relocation &rel, 38 uint64_t val) const override; 39 }; 40 } // namespace 41 42 MSP430::MSP430() { 43 // mov.b #0, r3 44 trapInstr = {0x43, 0x43, 0x43, 0x43}; 45 } 46 47 RelExpr MSP430::getRelExpr(RelType type, const Symbol &s, 48 const uint8_t *loc) const { 49 switch (type) { 50 case R_MSP430_10_PCREL: 51 case R_MSP430_16_PCREL: 52 case R_MSP430_16_PCREL_BYTE: 53 case R_MSP430_2X_PCREL: 54 case R_MSP430_RL_PCREL: 55 case R_MSP430_SYM_DIFF: 56 return R_PC; 57 default: 58 return R_ABS; 59 } 60 } 61 62 void MSP430::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { 63 switch (rel.type) { 64 case R_MSP430_8: 65 checkIntUInt(loc, val, 8, rel); 66 *loc = val; 67 break; 68 case R_MSP430_16: 69 case R_MSP430_16_PCREL: 70 case R_MSP430_16_BYTE: 71 case R_MSP430_16_PCREL_BYTE: 72 checkIntUInt(loc, val, 16, rel); 73 write16le(loc, val); 74 break; 75 case R_MSP430_32: 76 checkIntUInt(loc, val, 32, rel); 77 write32le(loc, val); 78 break; 79 case R_MSP430_10_PCREL: { 80 int16_t offset = ((int16_t)val >> 1) - 1; 81 checkInt(loc, offset, 10, rel); 82 write16le(loc, (read16le(loc) & 0xFC00) | (offset & 0x3FF)); 83 break; 84 } 85 default: 86 error(getErrorLocation(loc) + "unrecognized relocation " + 87 toString(rel.type)); 88 } 89 } 90 91 TargetInfo *elf::getMSP430TargetInfo() { 92 static MSP430 target; 93 return ⌖ 94 } 95