Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/llvm/include/llvm/IR/Intrinsics.td
Original file line number Diff line number Diff line change
Expand Up @@ -1156,3 +1156,4 @@ include "llvm/IR/IntrinsicsBPF.td"
include "llvm/IR/IntrinsicsSystemZ.td"
include "llvm/IR/IntrinsicsWebAssembly.td"
include "llvm/IR/IntrinsicsRISCV.td"
include "llvm/IR/IntrinsicsMSP430.td"
21 changes: 21 additions & 0 deletions src/llvm/include/llvm/IR/IntrinsicsMSP430.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===- IntrinsicsMSP430.td - Defines MSP430 intrinsics -----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines all of the MSP430-specific intrinsics.
//
//===----------------------------------------------------------------------===//

let TargetPrefix = "msp430" in { // All intrinsics start with "llvm.msp430."
def int_msp430_bic_saved_status :
Intrinsic<[llvm_i16_ty], [llvm_i16_ty], []>,
GCCBuiltin<"__bic_SR_register_on_exit">;
def int_msp430_bis_saved_status :
Intrinsic<[llvm_i16_ty], [llvm_i16_ty], []>,
GCCBuiltin<"__bis_SR_register_on_exit">;
}
2 changes: 2 additions & 0 deletions src/llvm/lib/Support/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) {
case mips64:
case mips64el: return "mips";

case msp430: return "msp430";

case hexagon: return "hexagon";

case amdgcn: return "amdgcn";
Expand Down
53 changes: 53 additions & 0 deletions src/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM,
setOperationAction(ISD::VACOPY, MVT::Other, Expand);
setOperationAction(ISD::JumpTable, MVT::i16, Custom);

// Custom lowering for some intrinsics
setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);

// EABI Libcalls - EABI Section 6.2
const struct {
const RTLIB::Libcall Op;
Expand Down Expand Up @@ -349,6 +352,7 @@ SDValue MSP430TargetLowering::LowerOperation(SDValue Op,
case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
case ISD::VASTART: return LowerVASTART(Op, DAG);
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
case ISD::INTRINSIC_W_CHAIN: return LowerINTRINSIC_W_CHAIN(Op, DAG);
default:
llvm_unreachable("unimplemented operand");
}
Expand Down Expand Up @@ -938,6 +942,55 @@ SDValue MSP430TargetLowering::LowerCallResult(
return Chain;
}

SDValue MSP430TargetLowering::
LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const {
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
switch (IntNo) {
default:
break;
case Intrinsic::msp430_bis_saved_status:
case Intrinsic::msp430_bic_saved_status:
MachineFunction &MF = DAG.getMachineFunction();
MSP430MachineFunctionInfo *FuncInfo =
MF.getInfo<MSP430MachineFunctionInfo>();

int SavedSRFrameIndex = FuncInfo->getSavedSRIndex();
if (SavedSRFrameIndex == 0) {
SavedSRFrameIndex =
MF.getFrameInfo().CreateFixedObject(/*Size*/ 2, /*Offset*/-2, true);
FuncInfo->setSavedSRIndex(SavedSRFrameIndex);
}

MVT PtrVT = getPointerTy(DAG.getDataLayout());
SDValue FI = DAG.getFrameIndex(SavedSRFrameIndex, PtrVT);

SDValue Chain = Op->getOperand(0);
SDLoc DL(Op);

// Load a saved copy of status register.
SDValue SR =
DAG.getLoad(MVT::i16, DL, Chain, FI,
MachinePointerInfo::getFixedStack(MF, SavedSRFrameIndex));

SDValue Result;
if (IntNo == Intrinsic::msp430_bis_saved_status) {
Result = DAG.getNode(ISD::OR, DL, MVT::i16, SR, Op->getOperand(2));
} else {
// IntNo == Intrinsic::msp430_bic_saved_status
Result = DAG.getNOT(DL, Op->getOperand(2), MVT::i16);
Result = DAG.getNode(ISD::AND, DL, MVT::i16, SR, Result);
}

// Store the result.
Chain =
DAG.getStore(SR.getValue(1), DL, Result, FI,
MachinePointerInfo::getFixedStack(MF, SavedSRFrameIndex));
SDValue Ops[2] = { SR.getValue(0), Chain };
return DAG.getMergeValues(Ops, DL);
}
return SDValue();
}

SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
SelectionDAG &DAG) const {
unsigned Opc = Op.getOpcode();
Expand Down
1 change: 1 addition & 0 deletions src/llvm/lib/Target/MSP430/MSP430ISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ namespace llvm {
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;

TargetLowering::ConstraintType
Expand Down
10 changes: 9 additions & 1 deletion src/llvm/lib/Target/MSP430/MSP430MachineFunctionInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo {
/// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex;

/// SavedSRFrameIndex - FrameIndex for saved copy of status register
/// (interrupt handlers only).
int SavedSRFrameIndex;

/// SRetReturnReg - Some subtargets require that sret lowering includes
/// returning the value of the returned struct in a register. This field
/// holds the virtual register into which the sret argument is passed.
Expand All @@ -42,7 +46,8 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo {
MSP430MachineFunctionInfo() : CalleeSavedFrameSize(0) {}

explicit MSP430MachineFunctionInfo(MachineFunction &MF)
: CalleeSavedFrameSize(0), ReturnAddrIndex(0), SRetReturnReg(0) {}
: CalleeSavedFrameSize(0), ReturnAddrIndex(0), SavedSRFrameIndex(0),
SRetReturnReg(0) {}

unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
Expand All @@ -53,6 +58,9 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo {
int getRAIndex() const { return ReturnAddrIndex; }
void setRAIndex(int Index) { ReturnAddrIndex = Index; }

int getSavedSRIndex() const { return SavedSRFrameIndex; }
void setSavedSRIndex(int Index) { SavedSRFrameIndex = Index; }

int getVarArgsFrameIndex() const { return VarArgsFrameIndex;}
void setVarArgsFrameIndex(int Index) { VarArgsFrameIndex = Index; }
};
Expand Down
44 changes: 44 additions & 0 deletions src/llvm/test/CodeGen/MSP430/bic_bis_saved_status.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
; RUN: llc < %s | FileCheck %s

target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
target triple = "msp430-elf"

define msp430_intrcc void @bis() #0 {
; CHECK-LABEL: bis:
; CHECK: bis #5, @r1
%1 = call i16 @llvm.msp430.bis.saved.status(i16 5)
ret void
}

@a = common dso_local local_unnamed_addr global i16 0, align 2

define msp430_intrcc void @bic() #0 {
; CHECK-LABEL: bic:
; CHECK: bic &a, @r1
%1 = load i16, i16* @a, align 2
%2 = call i16 @llvm.msp430.bic.saved.status(i16 %1)
ret void
}

; Check that the intrinsic returns the value of the saved status register
; before the update.

define dso_local msp430_intrcc void @foo() #0 {
; CHECK-LABEL: foo:
; CHECK: push r13
; CHECK-NEXT: push r12
; CHECK-NEXT: mov 4(r1), r12
; CHECK-NEXT: mov r12, r13
; CHECK-NEXT: bis #5, r13
; CHECK-NEXT: mov r13, 4(r1)
; CHECK-NEXT: mov r12, &a

%1 = tail call i16 @llvm.msp430.bis.saved.status(i16 5)
store i16 %1, i16* @a, align 2
ret void
}

declare i16 @llvm.msp430.bis.saved.status(i16)
declare i16 @llvm.msp430.bic.saved.status(i16)

attributes #0 = {"interrupt"="1"}
19 changes: 19 additions & 0 deletions src/llvm/tools/clang/include/clang/Basic/BuiltinsMSP430.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===-- BuiltinsMips.def - Mips Builtin function database --------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MIPS-specific builtin function database. Users of
// this file must define the BUILTIN macro to make use of this information.
//
//===----------------------------------------------------------------------===//

// The format of this database matches clang/Basic/Builtins.def.

// Add/subtract with optional saturation
BUILTIN(__bic_SR_register_on_exit, "UsUs", "")
BUILTIN(__bis_SR_register_on_exit, "UsUs", "")
Original file line number Diff line number Diff line change
Expand Up @@ -8309,6 +8309,8 @@ def err_hexagon_builtin_requires_hvx : Error<
"builtin requires HVX">;
def err_hexagon_builtin_unsupported_hvx : Error<
"builtin is not supported on this version of HVX">;
def err_msp430_builtin_not_isr_caller : Error<
"builtin is only available within interrupt routines">;

def err_builtin_target_unsupported : Error<
"builtin is not supported on this target">;
Expand Down
10 changes: 10 additions & 0 deletions src/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ namespace clang {
};
}

/// MSP430 builtins
namespace MSP430 {
enum {
LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
#define BUILTIN(ID, TYPE, ATTRS) BI##ID,
#include "clang/Basic/BuiltinsMSP430.def"
LastTSBuiltin
};
}

/// XCore builtins
namespace XCore {
enum {
Expand Down
1 change: 1 addition & 0 deletions src/llvm/tools/clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -10514,6 +10514,7 @@ class Sema {
bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall);
bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
bool CheckMSP430BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);

bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);
Expand Down
12 changes: 12 additions & 0 deletions src/llvm/tools/clang/lib/Basic/Targets/MSP430.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "MSP430.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetBuiltins.h"

using namespace clang;
using namespace clang::targets;
Expand All @@ -22,6 +23,17 @@ const char *const MSP430TargetInfo::GCCRegNames[] = {
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};

const Builtin::Info MSP430TargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
{#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
#include "clang/Basic/BuiltinsMSP430.def"
};

ArrayRef<Builtin::Info> MSP430TargetInfo::getTargetBuiltins() const {
return llvm::makeArrayRef(
BuiltinInfo, clang::MSP430::LastTSBuiltin - Builtin::FirstTSBuiltin);
}

ArrayRef<const char *> MSP430TargetInfo::getGCCRegNames() const {
return llvm::makeArrayRef(GCCRegNames);
}
Expand Down
6 changes: 2 additions & 4 deletions src/llvm/tools/clang/lib/Basic/Targets/MSP430.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ namespace targets {

class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo {
static const char *const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];

public:
MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &)
Expand All @@ -48,10 +49,7 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo {
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;

ArrayRef<Builtin::Info> getTargetBuiltins() const override {
// FIXME: Implement.
return None;
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override;

bool allowsLargerPreferedTypeAlignment() const override { return false; }

Expand Down
21 changes: 21 additions & 0 deletions src/llvm/tools/clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (CheckPPCBuiltinFunctionCall(BuiltinID, TheCall))
return ExprError();
break;
case llvm::Triple::msp430:
if (CheckMSP430BuiltinFunctionCall(BuiltinID, TheCall))
return ExprError();
break;
default:
break;
}
Expand Down Expand Up @@ -3919,6 +3923,23 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return SemaBuiltinConstantArgRange(TheCall, i, l, u, /*RangeIsError*/ false);
}

bool Sema::CheckMSP430BuiltinFunctionCall(unsigned BuiltinID,
CallExpr *TheCall) {
switch (BuiltinID) {
default:
return false;
case MSP430::BI__bic_SR_register_on_exit:
case MSP430::BI__bis_SR_register_on_exit:
auto *FD = cast<FunctionDecl>(CurContext);
// These builtins can only be used inside interrupt handlers.
if (!FD->hasAttr<MSP430InterruptAttr>())
return
Diag(TheCall->getBeginLoc(), diag::err_msp430_builtin_not_isr_caller)
<< TheCall->getSourceRange();
}
return false;
}

/// Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo
/// parameter with the FormatAttr's correct format_idx and firstDataArg.
/// Returns true when the format fits the function and the FormatStringInfo has
Expand Down
11 changes: 11 additions & 0 deletions src/llvm/tools/clang/test/CodeGen/builtins-msp430.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// REQUIRES: msp430-registered-target
// RUN: %clang_cc1 -triple msp430-elf -emit-llvm -o - %s | FileCheck %s

__attribute__((interrupt(1))) void foo(void) {
// CHECK: call i16 @llvm.msp430.bic.saved.status(i16 1)
__bic_SR_register_on_exit(1);

// CHECK: call i16 @llvm.msp430.bis.saved.status(i16 1)
__bis_SR_register_on_exit(1);
}

14 changes: 14 additions & 0 deletions src/llvm/tools/clang/test/Sema/builtins-msp430.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// REQUIRES: msp430-registered-target
// RUN: %clang_cc1 %s -triple msp430-elf -fsyntax-only -verify

void f(void) {
__bic_SR_register_on_exit(1); // expected-error {{builtin is only available within interrupt routines}}
__bis_SR_register_on_exit(1); // expected-error {{builtin is only available within interrupt routines}}
}

__attribute__((interrupt(1)))
void ISR(void) {
__bic_SR_register_on_exit(1);
__bis_SR_register_on_exit(1);
}