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 "InputFiles.h" 19 #include "Symbols.h" 20 #include "Target.h" 21 #include "lld/Common/ErrorHandler.h" 22 #include "llvm/Object/ELF.h" 23 #include "llvm/Support/Endian.h" 24 25 using namespace llvm; 26 using namespace llvm::object; 27 using namespace llvm::support::endian; 28 using namespace llvm::ELF; 29 using namespace lld; 30 using namespace lld::elf; 31 32 namespace { 33 class MSP430 final : public TargetInfo { 34 public: 35 MSP430(); 36 RelExpr getRelExpr(RelType type, const Symbol &s, 37 const uint8_t *loc) const override; 38 void relocate(uint8_t *loc, const Relocation &rel, 39 uint64_t val) const override; 40 }; 41 } // namespace 42 43 MSP430::MSP430() { 44 // mov.b #0, r3 45 trapInstr = {0x43, 0x43, 0x43, 0x43}; 46 } 47 48 RelExpr MSP430::getRelExpr(RelType type, const Symbol &s, 49 const uint8_t *loc) const { 50 switch (type) { 51 case R_MSP430_10_PCREL: 52 case R_MSP430_16_PCREL: 53 case R_MSP430_16_PCREL_BYTE: 54 case R_MSP430_2X_PCREL: 55 case R_MSP430_RL_PCREL: 56 case R_MSP430_SYM_DIFF: 57 return R_PC; 58 default: 59 return R_ABS; 60 } 61 } 62 63 void MSP430::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { 64 switch (rel.type) { 65 case R_MSP430_8: 66 checkIntUInt(loc, val, 8, rel); 67 *loc = val; 68 break; 69 case R_MSP430_16: 70 case R_MSP430_16_PCREL: 71 case R_MSP430_16_BYTE: 72 case R_MSP430_16_PCREL_BYTE: 73 checkIntUInt(loc, val, 16, rel); 74 write16le(loc, val); 75 break; 76 case R_MSP430_32: 77 checkIntUInt(loc, val, 32, rel); 78 write32le(loc, val); 79 break; 80 case R_MSP430_10_PCREL: { 81 int16_t offset = ((int16_t)val >> 1) - 1; 82 checkInt(loc, offset, 10, rel); 83 write16le(loc, (read16le(loc) & 0xFC00) | (offset & 0x3FF)); 84 break; 85 } 86 default: 87 error(getErrorLocation(loc) + "unrecognized relocation " + 88 toString(rel.type)); 89 } 90 } 91 92 TargetInfo *elf::getMSP430TargetInfo() { 93 static MSP430 target; 94 return ⌖ 95 } 96