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