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 30 namespace lld { 31 namespace elf { 32 33 namespace { 34 class MSP430 final : public TargetInfo { 35 public: 36 MSP430(); 37 RelExpr getRelExpr(RelType type, const Symbol &s, 38 const uint8_t *loc) const override; 39 void relocateOne(uint8_t *loc, RelType type, 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::relocateOne(uint8_t *loc, RelType type, uint64_t val) const { 64 switch (type) { 65 case R_MSP430_8: 66 checkIntUInt(loc, val, 8, type); 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, type); 74 write16le(loc, val); 75 break; 76 case R_MSP430_32: 77 checkIntUInt(loc, val, 32, type); 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, type); 83 write16le(loc, (read16le(loc) & 0xFC00) | (offset & 0x3FF)); 84 break; 85 } 86 default: 87 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type)); 88 } 89 } 90 91 TargetInfo *getMSP430TargetInfo() { 92 static MSP430 target; 93 return ⌖ 94 } 95 96 } // namespace elf 97 } // namespace lld 98