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 relocateOne(uint8_t *Loc, RelType Type, 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::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 63 switch (Type) { 64 case R_MSP430_8: 65 checkIntUInt(Loc, Val, 8, Type); 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, Type); 73 write16le(Loc, Val); 74 break; 75 case R_MSP430_32: 76 checkIntUInt(Loc, Val, 32, Type); 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, Type); 82 write16le(Loc, (read16le(Loc) & 0xFC00) | (Offset & 0x3FF)); 83 break; 84 } 85 default: 86 error(getErrorLocation(Loc) + "unrecognized relocation " + toString(Type)); 87 } 88 } 89 90 TargetInfo *elf::getMSP430TargetInfo() { 91 static MSP430 Target; 92 return &Target; 93 } 94