90 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// The MSP430 is a 16-bit microcontroller RISC architecture. The instruction set10// has only 27 core instructions orthogonally augmented with a variety11// of addressing modes for source and destination operands. Entire address space12// of MSP430 is 64KB (the extended MSP430X architecture is not considered here).13// A typical MSP430 MCU has several kilobytes of RAM and ROM, plenty14// 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 23using namespace llvm;24using namespace llvm::object;25using namespace llvm::support::endian;26using namespace llvm::ELF;27using namespace lld;28using namespace lld::elf;29 30namespace {31class MSP430 final : public TargetInfo {32public: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} // namespace40 41MSP430::MSP430(Ctx &ctx) : TargetInfo(ctx) {42 // mov.b #0, r343 trapInstr = {0x43, 0x43, 0x43, 0x43};44}45 46RelExpr 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 61void 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 89void elf::setMSP430TargetInfo(Ctx &ctx) { ctx.target.reset(new MSP430(ctx)); }90