mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[MSP430] Add SRet support to MSP430 target
This patch adds support for struct return values to the MSP430 target backend. It also reverses the order of argument and return registers in the calling convention to bring it into closer alignment with the published EABI from TI. Patch by Andrew Wygle (awygle). Differential Revision: https://reviews.llvm.org/D29069 llvm-svn: 296807
This commit is contained in:
parent
b4c9dc6b06
commit
bdc6e663e7
@ -13,11 +13,11 @@
|
||||
// MSP430 Return Value Calling Convention
|
||||
//===----------------------------------------------------------------------===//
|
||||
def RetCC_MSP430 : CallingConv<[
|
||||
// i8 are returned in registers R15B, R14B, R13B, R12B
|
||||
CCIfType<[i8], CCAssignToReg<[R15B, R14B, R13B, R12B]>>,
|
||||
// i8 are returned in registers R12B, R13B, R14B, R15B
|
||||
CCIfType<[i8], CCAssignToReg<[R12B, R13B, R14B, R15B]>>,
|
||||
|
||||
// i16 are returned in registers R15, R14, R13, R12
|
||||
CCIfType<[i16], CCAssignToReg<[R15, R14, R13, R12]>>
|
||||
// i16 are returned in registers R12, R13, R14, R15
|
||||
CCIfType<[i16], CCAssignToReg<[R12, R13, R14, R15]>>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -245,13 +245,20 @@ MSP430TargetLowering::getRegForInlineAsmConstraint(
|
||||
template<typename ArgT>
|
||||
static void ParseFunctionArgs(const SmallVectorImpl<ArgT> &Args,
|
||||
SmallVectorImpl<unsigned> &Out) {
|
||||
unsigned CurrentArgIndex = ~0U;
|
||||
for (unsigned i = 0, e = Args.size(); i != e; i++) {
|
||||
if (CurrentArgIndex == Args[i].OrigArgIndex) {
|
||||
Out.back()++;
|
||||
unsigned CurrentArgIndex;
|
||||
|
||||
if (Args.empty())
|
||||
return;
|
||||
|
||||
CurrentArgIndex = Args[0].OrigArgIndex;
|
||||
Out.push_back(0);
|
||||
|
||||
for (auto &Arg : Args) {
|
||||
if (CurrentArgIndex == Arg.OrigArgIndex) {
|
||||
Out.back() += 1;
|
||||
} else {
|
||||
Out.push_back(1);
|
||||
CurrentArgIndex++;
|
||||
CurrentArgIndex = Arg.OrigArgIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -275,7 +282,7 @@ static void AnalyzeArguments(CCState &State,
|
||||
SmallVectorImpl<CCValAssign> &ArgLocs,
|
||||
const SmallVectorImpl<ArgT> &Args) {
|
||||
static const MCPhysReg RegList[] = {
|
||||
MSP430::R15, MSP430::R14, MSP430::R13, MSP430::R12
|
||||
MSP430::R12, MSP430::R13, MSP430::R14, MSP430::R15
|
||||
};
|
||||
static const unsigned NbRegs = array_lengthof(RegList);
|
||||
|
||||
@ -288,7 +295,7 @@ static void AnalyzeArguments(CCState &State,
|
||||
ParseFunctionArgs(Args, ArgsParts);
|
||||
|
||||
unsigned RegsLeft = NbRegs;
|
||||
bool UseStack = false;
|
||||
bool UsedStack = false;
|
||||
unsigned ValNo = 0;
|
||||
|
||||
for (unsigned i = 0, e = ArgsParts.size(); i != e; i++) {
|
||||
@ -316,20 +323,22 @@ static void AnalyzeArguments(CCState &State,
|
||||
|
||||
unsigned Parts = ArgsParts[i];
|
||||
|
||||
if (!UseStack && Parts <= RegsLeft) {
|
||||
unsigned FirstVal = ValNo;
|
||||
if (!UsedStack && Parts == 2 && RegsLeft == 1) {
|
||||
// Special case for 32-bit register split, see EABI section 3.3.3
|
||||
unsigned Reg = State.AllocateReg(RegList);
|
||||
State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
|
||||
RegsLeft -= 1;
|
||||
|
||||
UsedStack = true;
|
||||
CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
|
||||
} else if (Parts <= RegsLeft) {
|
||||
for (unsigned j = 0; j < Parts; j++) {
|
||||
unsigned Reg = State.AllocateReg(RegList);
|
||||
State.addLoc(CCValAssign::getReg(ValNo++, ArgVT, Reg, LocVT, LocInfo));
|
||||
RegsLeft--;
|
||||
}
|
||||
|
||||
// Reverse the order of the pieces to agree with the "big endian" format
|
||||
// required in the calling convention ABI.
|
||||
SmallVectorImpl<CCValAssign>::iterator B = ArgLocs.begin() + FirstVal;
|
||||
std::reverse(B, B + Parts);
|
||||
} else {
|
||||
UseStack = true;
|
||||
UsedStack = true;
|
||||
for (unsigned j = 0; j < Parts; j++)
|
||||
CC_MSP430_AssignStack(ValNo++, ArgVT, LocVT, LocInfo, ArgFlags, State);
|
||||
}
|
||||
@ -351,10 +360,6 @@ static void AnalyzeReturnValues(CCState &State,
|
||||
SmallVectorImpl<CCValAssign> &RVLocs,
|
||||
const SmallVectorImpl<ArgT> &Args) {
|
||||
AnalyzeRetResult(State, Args);
|
||||
|
||||
// Reverse splitted return values to get the "big endian" format required
|
||||
// to agree with the calling convention ABI.
|
||||
std::reverse(RVLocs.begin(), RVLocs.end());
|
||||
}
|
||||
|
||||
SDValue MSP430TargetLowering::LowerFormalArguments(
|
||||
@ -496,9 +501,33 @@ SDValue MSP430TargetLowering::LowerCCCArguments(
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
|
||||
if (Ins[i].Flags.isSRet()) {
|
||||
unsigned Reg = FuncInfo->getSRetReturnReg();
|
||||
if (!Reg) {
|
||||
Reg = MF.getRegInfo().createVirtualRegister(
|
||||
getRegClassFor(MVT::i16));
|
||||
FuncInfo->setSRetReturnReg(Reg);
|
||||
}
|
||||
SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[i]);
|
||||
Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Copy, Chain);
|
||||
}
|
||||
}
|
||||
|
||||
return Chain;
|
||||
}
|
||||
|
||||
bool
|
||||
MSP430TargetLowering::CanLowerReturn(CallingConv::ID CallConv,
|
||||
MachineFunction &MF,
|
||||
bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
LLVMContext &Context) const {
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
|
||||
return CCInfo.CheckReturn(Outs, RetCC_MSP430);
|
||||
}
|
||||
|
||||
SDValue
|
||||
MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
bool isVarArg,
|
||||
@ -506,6 +535,8 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
const SDLoc &dl, SelectionDAG &DAG) const {
|
||||
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
|
||||
// CCValAssign - represent the assignment of the return value to a location
|
||||
SmallVector<CCValAssign, 16> RVLocs;
|
||||
|
||||
@ -537,6 +568,22 @@ MSP430TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
||||
RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
|
||||
}
|
||||
|
||||
if (MF.getFunction()->hasStructRetAttr()) {
|
||||
MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
|
||||
unsigned Reg = FuncInfo->getSRetReturnReg();
|
||||
|
||||
if (!Reg)
|
||||
llvm_unreachable("sret virtual register not created in entry block");
|
||||
|
||||
SDValue Val =
|
||||
DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy(DAG.getDataLayout()));
|
||||
unsigned R12 = MSP430::R12;
|
||||
|
||||
Chain = DAG.getCopyToReg(Chain, dl, R12, Val, Flag);
|
||||
Flag = Chain.getValue(1);
|
||||
RetOps.push_back(DAG.getRegister(R12, getPointerTy(DAG.getDataLayout())));
|
||||
}
|
||||
|
||||
unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
|
||||
MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
|
||||
|
||||
|
@ -158,6 +158,12 @@ namespace llvm {
|
||||
LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
||||
SmallVectorImpl<SDValue> &InVals) const override;
|
||||
|
||||
bool CanLowerReturn(CallingConv::ID CallConv,
|
||||
MachineFunction &MF,
|
||||
bool IsVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
LLVMContext &Context) const override;
|
||||
|
||||
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
|
||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||
const SmallVectorImpl<SDValue> &OutVals,
|
||||
|
@ -33,15 +33,23 @@ class MSP430MachineFunctionInfo : public MachineFunctionInfo {
|
||||
/// VarArgsFrameIndex - FrameIndex for start of varargs area.
|
||||
int VarArgsFrameIndex;
|
||||
|
||||
/// 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.
|
||||
unsigned SRetReturnReg;
|
||||
|
||||
public:
|
||||
MSP430MachineFunctionInfo() : CalleeSavedFrameSize(0) {}
|
||||
|
||||
explicit MSP430MachineFunctionInfo(MachineFunction &MF)
|
||||
: CalleeSavedFrameSize(0), ReturnAddrIndex(0) {}
|
||||
: CalleeSavedFrameSize(0), ReturnAddrIndex(0), SRetReturnReg(0) {}
|
||||
|
||||
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
|
||||
void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; }
|
||||
|
||||
unsigned getSRetReturnReg() const { return SRetReturnReg; }
|
||||
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
|
||||
|
||||
int getRAIndex() const { return ReturnAddrIndex; }
|
||||
void setRAIndex(int Index) { ReturnAddrIndex = Index; }
|
||||
|
||||
|
@ -8,7 +8,7 @@ define i16 @am1(i16 %x, i16* %a) nounwind {
|
||||
ret i16 %2
|
||||
}
|
||||
; CHECK-LABEL: am1:
|
||||
; CHECK: bis.w 0(r14), r15
|
||||
; CHECK: bis.w 0(r13), r12
|
||||
|
||||
@foo = external global i16
|
||||
|
||||
@ -18,7 +18,7 @@ define i16 @am2(i16 %x) nounwind {
|
||||
ret i16 %2
|
||||
}
|
||||
; CHECK-LABEL: am2:
|
||||
; CHECK: bis.w &foo, r15
|
||||
; CHECK: bis.w &foo, r12
|
||||
|
||||
@bar = internal constant [2 x i8] [ i8 32, i8 64 ]
|
||||
|
||||
@ -29,7 +29,7 @@ define i8 @am3(i8 %x, i16 %n) nounwind {
|
||||
ret i8 %3
|
||||
}
|
||||
; CHECK-LABEL: am3:
|
||||
; CHECK: bis.b bar(r14), r15
|
||||
; CHECK: bis.b bar(r13), r12
|
||||
|
||||
define i16 @am4(i16 %x) nounwind {
|
||||
%1 = load volatile i16, i16* inttoptr(i16 32 to i16*)
|
||||
@ -37,7 +37,7 @@ define i16 @am4(i16 %x) nounwind {
|
||||
ret i16 %2
|
||||
}
|
||||
; CHECK-LABEL: am4:
|
||||
; CHECK: bis.w &32, r15
|
||||
; CHECK: bis.w &32, r12
|
||||
|
||||
define i16 @am5(i16 %x, i16* %a) nounwind {
|
||||
%1 = getelementptr i16, i16* %a, i16 2
|
||||
@ -46,7 +46,7 @@ define i16 @am5(i16 %x, i16* %a) nounwind {
|
||||
ret i16 %3
|
||||
}
|
||||
; CHECK-LABEL: am5:
|
||||
; CHECK: bis.w 4(r14), r15
|
||||
; CHECK: bis.w 4(r13), r12
|
||||
|
||||
%S = type { i16, i16 }
|
||||
@baz = common global %S zeroinitializer, align 1
|
||||
@ -57,7 +57,7 @@ define i16 @am6(i16 %x) nounwind {
|
||||
ret i16 %2
|
||||
}
|
||||
; CHECK-LABEL: am6:
|
||||
; CHECK: bis.w &baz+2, r15
|
||||
; CHECK: bis.w &baz+2, r12
|
||||
|
||||
%T = type { i16, [2 x i8] }
|
||||
@duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
|
||||
@ -70,5 +70,5 @@ define i8 @am7(i8 %x, i16 %n) nounwind {
|
||||
ret i8 %4
|
||||
}
|
||||
; CHECK-LABEL: am7:
|
||||
; CHECK: bis.b duh+2(r14), r15
|
||||
; CHECK: bis.b duh+2(r13), r12
|
||||
|
||||
|
@ -9,7 +9,7 @@ define void @am1(i16* %a, i16 %x) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am1:
|
||||
; CHECK: bis.w r14, 0(r15)
|
||||
; CHECK: bis.w r13, 0(r12)
|
||||
|
||||
@foo = external global i16
|
||||
|
||||
@ -20,7 +20,7 @@ define void @am2(i16 %x) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am2:
|
||||
; CHECK: bis.w r15, &foo
|
||||
; CHECK: bis.w r12, &foo
|
||||
|
||||
@bar = external global [2 x i8]
|
||||
|
||||
@ -32,7 +32,7 @@ define void @am3(i16 %i, i8 %x) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am3:
|
||||
; CHECK: bis.b r14, bar(r15)
|
||||
; CHECK: bis.b r13, bar(r12)
|
||||
|
||||
define void @am4(i16 %x) nounwind {
|
||||
%1 = load volatile i16, i16* inttoptr(i16 32 to i16*)
|
||||
@ -41,7 +41,7 @@ define void @am4(i16 %x) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am4:
|
||||
; CHECK: bis.w r15, &32
|
||||
; CHECK: bis.w r12, &32
|
||||
|
||||
define void @am5(i16* %a, i16 %x) readonly {
|
||||
%1 = getelementptr inbounds i16, i16* %a, i16 2
|
||||
@ -51,7 +51,7 @@ define void @am5(i16* %a, i16 %x) readonly {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am5:
|
||||
; CHECK: bis.w r14, 4(r15)
|
||||
; CHECK: bis.w r13, 4(r12)
|
||||
|
||||
%S = type { i16, i16 }
|
||||
@baz = common global %S zeroinitializer
|
||||
@ -63,7 +63,7 @@ define void @am6(i16 %x) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am6:
|
||||
; CHECK: bis.w r15, &baz+2
|
||||
; CHECK: bis.w r12, &baz+2
|
||||
|
||||
%T = type { i16, [2 x i8] }
|
||||
@duh = external global %T
|
||||
@ -77,5 +77,5 @@ define void @am7(i16 %n, i8 %x) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am7:
|
||||
; CHECK: bis.b r14, duh+2(r15)
|
||||
; CHECK: bis.b r13, duh+2(r12)
|
||||
|
||||
|
@ -7,7 +7,7 @@ define i16 @am1(i16* %a) nounwind {
|
||||
ret i16 %1
|
||||
}
|
||||
; CHECK-LABEL: am1:
|
||||
; CHECK: mov.w 0(r15), r15
|
||||
; CHECK: mov.w 0(r12), r12
|
||||
|
||||
@foo = external global i16
|
||||
|
||||
@ -16,7 +16,7 @@ define i16 @am2() nounwind {
|
||||
ret i16 %1
|
||||
}
|
||||
; CHECK-LABEL: am2:
|
||||
; CHECK: mov.w &foo, r15
|
||||
; CHECK: mov.w &foo, r12
|
||||
|
||||
@bar = internal constant [2 x i8] [ i8 32, i8 64 ]
|
||||
|
||||
@ -26,14 +26,14 @@ define i8 @am3(i16 %n) nounwind {
|
||||
ret i8 %2
|
||||
}
|
||||
; CHECK-LABEL: am3:
|
||||
; CHECK: mov.b bar(r15), r15
|
||||
; CHECK: mov.b bar(r12), r12
|
||||
|
||||
define i16 @am4() nounwind {
|
||||
%1 = load volatile i16, i16* inttoptr(i16 32 to i16*)
|
||||
ret i16 %1
|
||||
}
|
||||
; CHECK-LABEL: am4:
|
||||
; CHECK: mov.w &32, r15
|
||||
; CHECK: mov.w &32, r12
|
||||
|
||||
define i16 @am5(i16* %a) nounwind {
|
||||
%1 = getelementptr i16, i16* %a, i16 2
|
||||
@ -41,7 +41,7 @@ define i16 @am5(i16* %a) nounwind {
|
||||
ret i16 %2
|
||||
}
|
||||
; CHECK-LABEL: am5:
|
||||
; CHECK: mov.w 4(r15), r15
|
||||
; CHECK: mov.w 4(r12), r12
|
||||
|
||||
%S = type { i16, i16 }
|
||||
@baz = common global %S zeroinitializer, align 1
|
||||
@ -51,7 +51,7 @@ define i16 @am6() nounwind {
|
||||
ret i16 %1
|
||||
}
|
||||
; CHECK-LABEL: am6:
|
||||
; CHECK: mov.w &baz+2, r15
|
||||
; CHECK: mov.w &baz+2, r12
|
||||
|
||||
%T = type { i16, [2 x i8] }
|
||||
@duh = internal constant %T { i16 16, [2 x i8][i8 32, i8 64 ] }
|
||||
@ -63,5 +63,5 @@ define i8 @am7(i16 %n) nounwind {
|
||||
ret i8 %3
|
||||
}
|
||||
; CHECK-LABEL: am7:
|
||||
; CHECK: mov.b duh+2(r15), r15
|
||||
; CHECK: mov.b duh+2(r12), r12
|
||||
|
||||
|
@ -7,7 +7,7 @@ define void @am1(i16* %a, i16 %b) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am1:
|
||||
; CHECK: mov.w r14, 0(r15)
|
||||
; CHECK: mov.w r13, 0(r12)
|
||||
|
||||
@foo = external global i16
|
||||
|
||||
@ -16,7 +16,7 @@ define void @am2(i16 %a) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am2:
|
||||
; CHECK: mov.w r15, &foo
|
||||
; CHECK: mov.w r12, &foo
|
||||
|
||||
@bar = external global [2 x i8]
|
||||
|
||||
@ -26,14 +26,14 @@ define void @am3(i16 %i, i8 %a) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am3:
|
||||
; CHECK: mov.b r14, bar(r15)
|
||||
; CHECK: mov.b r13, bar(r12)
|
||||
|
||||
define void @am4(i16 %a) nounwind {
|
||||
store volatile i16 %a, i16* inttoptr(i16 32 to i16*)
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am4:
|
||||
; CHECK: mov.w r15, &32
|
||||
; CHECK: mov.w r12, &32
|
||||
|
||||
define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {
|
||||
%1 = getelementptr inbounds i16, i16* %p, i16 2
|
||||
@ -41,7 +41,7 @@ define void @am5(i16* nocapture %p, i16 %a) nounwind readonly {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am5:
|
||||
; CHECK: mov.w r14, 4(r15)
|
||||
; CHECK: mov.w r13, 4(r12)
|
||||
|
||||
%S = type { i16, i16 }
|
||||
@baz = common global %S zeroinitializer, align 1
|
||||
@ -51,7 +51,7 @@ define void @am6(i16 %a) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am6:
|
||||
; CHECK: mov.w r15, &baz+2
|
||||
; CHECK: mov.w r12, &baz+2
|
||||
|
||||
%T = type { i16, [2 x i8] }
|
||||
@duh = external global %T
|
||||
@ -63,5 +63,5 @@ define void @am7(i16 %n, i8 %a) nounwind {
|
||||
ret void
|
||||
}
|
||||
; CHECK-LABEL: am7:
|
||||
; CHECK: mov.b r14, duh+2(r15)
|
||||
; CHECK: mov.b r13, duh+2(r12)
|
||||
|
||||
|
@ -5,14 +5,14 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define void @mov(i16 %a) nounwind {
|
||||
; CHECK-LABEL: mov:
|
||||
; CHECK: mov.w r15, &foo
|
||||
; CHECK: mov.w r12, &foo
|
||||
store i16 %a, i16* @foo
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @add(i16 %a) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.w r15, &foo
|
||||
; CHECK: add.w r12, &foo
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = add i16 %a, %1
|
||||
store i16 %2, i16* @foo
|
||||
@ -21,7 +21,7 @@ define void @add(i16 %a) nounwind {
|
||||
|
||||
define void @and(i16 %a) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.w r15, &foo
|
||||
; CHECK: and.w r12, &foo
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = and i16 %a, %1
|
||||
store i16 %2, i16* @foo
|
||||
@ -30,7 +30,7 @@ define void @and(i16 %a) nounwind {
|
||||
|
||||
define void @bis(i16 %a) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.w r15, &foo
|
||||
; CHECK: bis.w r12, &foo
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = or i16 %a, %1
|
||||
store i16 %2, i16* @foo
|
||||
@ -39,7 +39,7 @@ define void @bis(i16 %a) nounwind {
|
||||
|
||||
define void @bic(i16 zeroext %m) nounwind {
|
||||
; CHECK-LABEL: bic:
|
||||
; CHECK: bic.w r15, &foo
|
||||
; CHECK: bic.w r12, &foo
|
||||
%1 = xor i16 %m, -1
|
||||
%2 = load i16, i16* @foo
|
||||
%3 = and i16 %2, %1
|
||||
@ -49,7 +49,7 @@ define void @bic(i16 zeroext %m) nounwind {
|
||||
|
||||
define void @xor(i16 %a) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.w r15, &foo
|
||||
; CHECK: xor.w r12, &foo
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = xor i16 %a, %1
|
||||
store i16 %2, i16* @foo
|
||||
|
@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define i16 @mov() nounwind {
|
||||
; CHECK-LABEL: mov:
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: mov.w #1, r12
|
||||
ret i16 1
|
||||
}
|
||||
|
||||
define i16 @add(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.w #1, r15
|
||||
; CHECK: add.w #1, r12
|
||||
%1 = add i16 %a, 1
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @and(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: and.w #1, r12
|
||||
%1 = and i16 %a, 1
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @bis(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.w #1, r15
|
||||
; CHECK: bis.w #1, r12
|
||||
%1 = or i16 %a, 1
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @xor(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.w #1, r15
|
||||
; CHECK: xor.w #1, r12
|
||||
%1 = xor i16 %a, 1
|
||||
ret i16 %1
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define i16 @add(i16 %a) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.w &foo, r15
|
||||
; CHECK: add.w &foo, r12
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = add i16 %a, %1
|
||||
ret i16 %2
|
||||
@ -13,7 +13,7 @@ define i16 @add(i16 %a) nounwind {
|
||||
|
||||
define i16 @and(i16 %a) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.w &foo, r15
|
||||
; CHECK: and.w &foo, r12
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = and i16 %a, %1
|
||||
ret i16 %2
|
||||
@ -21,7 +21,7 @@ define i16 @and(i16 %a) nounwind {
|
||||
|
||||
define i16 @bis(i16 %a) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.w &foo, r15
|
||||
; CHECK: bis.w &foo, r12
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = or i16 %a, %1
|
||||
ret i16 %2
|
||||
@ -29,7 +29,7 @@ define i16 @bis(i16 %a) nounwind {
|
||||
|
||||
define i16 @bic(i16 %a) nounwind {
|
||||
; CHECK-LABEL: bic:
|
||||
; CHECK: bic.w &foo, r15
|
||||
; CHECK: bic.w &foo, r12
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = xor i16 %1, -1
|
||||
%3 = and i16 %a, %2
|
||||
@ -38,7 +38,7 @@ define i16 @bic(i16 %a) nounwind {
|
||||
|
||||
define i16 @xor(i16 %a) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.w &foo, r15
|
||||
; CHECK: xor.w &foo, r12
|
||||
%1 = load i16, i16* @foo
|
||||
%2 = xor i16 %a, %1
|
||||
ret i16 %2
|
||||
|
@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define i16 @mov(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: mov:
|
||||
; CHECK: mov.w r14, r15
|
||||
; CHECK: mov.w r13, r12
|
||||
ret i16 %b
|
||||
}
|
||||
|
||||
define i16 @add(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.w r14, r15
|
||||
; CHECK: add.w r13, r12
|
||||
%1 = add i16 %a, %b
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @and(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.w r14, r15
|
||||
; CHECK: and.w r13, r12
|
||||
%1 = and i16 %a, %b
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @bis(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.w r14, r15
|
||||
; CHECK: bis.w r13, r12
|
||||
%1 = or i16 %a, %b
|
||||
ret i16 %1
|
||||
}
|
||||
|
||||
define i16 @bic(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: bic:
|
||||
; CHECK: bic.w r14, r15
|
||||
; CHECK: bic.w r13, r12
|
||||
%1 = xor i16 %b, -1
|
||||
%2 = and i16 %a, %1
|
||||
ret i16 %2
|
||||
@ -39,7 +39,7 @@ define i16 @bic(i16 %a, i16 %b) nounwind {
|
||||
|
||||
define i16 @xor(i16 %a, i16 %b) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.w r14, r15
|
||||
; CHECK: xor.w r13, r12
|
||||
%1 = xor i16 %a, %b
|
||||
ret i16 %1
|
||||
}
|
||||
|
@ -5,14 +5,14 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define void @mov(i8 %a) nounwind {
|
||||
; CHECK-LABEL: mov:
|
||||
; CHECK: mov.b r15, &foo
|
||||
; CHECK: mov.b r12, &foo
|
||||
store i8 %a, i8* @foo
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @and(i8 %a) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.b r15, &foo
|
||||
; CHECK: and.b r12, &foo
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = and i8 %a, %1
|
||||
store i8 %2, i8* @foo
|
||||
@ -21,7 +21,7 @@ define void @and(i8 %a) nounwind {
|
||||
|
||||
define void @add(i8 %a) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.b r15, &foo
|
||||
; CHECK: add.b r12, &foo
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = add i8 %a, %1
|
||||
store i8 %2, i8* @foo
|
||||
@ -30,7 +30,7 @@ define void @add(i8 %a) nounwind {
|
||||
|
||||
define void @bis(i8 %a) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.b r15, &foo
|
||||
; CHECK: bis.b r12, &foo
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = or i8 %a, %1
|
||||
store i8 %2, i8* @foo
|
||||
@ -39,7 +39,7 @@ define void @bis(i8 %a) nounwind {
|
||||
|
||||
define void @bic(i8 zeroext %m) nounwind {
|
||||
; CHECK-LABEL: bic:
|
||||
; CHECK: bic.b r15, &foo
|
||||
; CHECK: bic.b r12, &foo
|
||||
%1 = xor i8 %m, -1
|
||||
%2 = load i8, i8* @foo
|
||||
%3 = and i8 %2, %1
|
||||
@ -49,7 +49,7 @@ define void @bic(i8 zeroext %m) nounwind {
|
||||
|
||||
define void @xor(i8 %a) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.b r15, &foo
|
||||
; CHECK: xor.b r12, &foo
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = xor i8 %a, %1
|
||||
store i8 %2, i8* @foo
|
||||
|
@ -4,34 +4,34 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define i8 @mov() nounwind {
|
||||
; CHECK-LABEL: mov:
|
||||
; CHECK: mov.b #1, r15
|
||||
; CHECK: mov.b #1, r12
|
||||
ret i8 1
|
||||
}
|
||||
|
||||
define i8 @add(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.b #1, r15
|
||||
; CHECK: add.b #1, r12
|
||||
%1 = add i8 %a, 1
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @and(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.b #1, r15
|
||||
; CHECK: and.b #1, r12
|
||||
%1 = and i8 %a, 1
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @bis(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.b #1, r15
|
||||
; CHECK: bis.b #1, r12
|
||||
%1 = or i8 %a, 1
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @xor(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.b #1, r15
|
||||
; CHECK: xor.b #1, r12
|
||||
%1 = xor i8 %a, 1
|
||||
ret i8 %1
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define i8 @add(i8 %a) nounwind {
|
||||
; CHECK-LABEL: add:
|
||||
; CHECK: add.b &foo, r15
|
||||
; CHECK: add.b &foo, r12
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = add i8 %a, %1
|
||||
ret i8 %2
|
||||
@ -13,7 +13,7 @@ define i8 @add(i8 %a) nounwind {
|
||||
|
||||
define i8 @and(i8 %a) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.b &foo, r15
|
||||
; CHECK: and.b &foo, r12
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = and i8 %a, %1
|
||||
ret i8 %2
|
||||
@ -21,7 +21,7 @@ define i8 @and(i8 %a) nounwind {
|
||||
|
||||
define i8 @bis(i8 %a) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.b &foo, r15
|
||||
; CHECK: bis.b &foo, r12
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = or i8 %a, %1
|
||||
ret i8 %2
|
||||
@ -29,7 +29,7 @@ define i8 @bis(i8 %a) nounwind {
|
||||
|
||||
define i8 @bic(i8 %a) nounwind {
|
||||
; CHECK-LABEL: bic:
|
||||
; CHECK: bic.b &foo, r15
|
||||
; CHECK: bic.b &foo, r12
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = xor i8 %1, -1
|
||||
%3 = and i8 %a, %2
|
||||
@ -38,7 +38,7 @@ define i8 @bic(i8 %a) nounwind {
|
||||
|
||||
define i8 @xor(i8 %a) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.b &foo, r15
|
||||
; CHECK: xor.b &foo, r12
|
||||
%1 = load i8, i8* @foo
|
||||
%2 = xor i8 %a, %1
|
||||
ret i8 %2
|
||||
|
@ -4,7 +4,7 @@ target triple = "msp430-generic-generic"
|
||||
|
||||
define i8 @mov(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: mov:
|
||||
; CHECK: mov.{{[bw]}} r14, r15
|
||||
; CHECK: mov.{{[bw]}} r13, r12
|
||||
ret i8 %b
|
||||
}
|
||||
|
||||
@ -17,21 +17,21 @@ define i8 @add(i8 %a, i8 %b) nounwind {
|
||||
|
||||
define i8 @and(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: and:
|
||||
; CHECK: and.w r14, r15
|
||||
; CHECK: and.w r13, r12
|
||||
%1 = and i8 %a, %b
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @bis(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: bis:
|
||||
; CHECK: bis.w r14, r15
|
||||
; CHECK: bis.w r13, r12
|
||||
%1 = or i8 %a, %b
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @bic(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: bic:
|
||||
; CHECK: bic.b r14, r15
|
||||
; CHECK: bic.b r13, r12
|
||||
%1 = xor i8 %b, -1
|
||||
%2 = and i8 %a, %1
|
||||
ret i8 %2
|
||||
@ -39,7 +39,7 @@ define i8 @bic(i8 %a, i8 %b) nounwind {
|
||||
|
||||
define i8 @xor(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: xor:
|
||||
; CHECK: xor.w r14, r15
|
||||
; CHECK: xor.w r13, r12
|
||||
%1 = xor i8 %a, %b
|
||||
ret i8 %1
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ define i8 @bitbrr(i8 %a, i8 %b) nounwind {
|
||||
ret i8 %t3
|
||||
}
|
||||
; CHECK-LABEL: bitbrr:
|
||||
; CHECK: bit.b r14, r15
|
||||
; CHECK: bit.b r13, r12
|
||||
|
||||
define i8 @bitbri(i8 %a) nounwind {
|
||||
%t1 = and i8 %a, 15
|
||||
@ -21,7 +21,7 @@ define i8 @bitbri(i8 %a) nounwind {
|
||||
ret i8 %t3
|
||||
}
|
||||
; CHECK-LABEL: bitbri:
|
||||
; CHECK: bit.b #15, r15
|
||||
; CHECK: bit.b #15, r12
|
||||
|
||||
define i8 @bitbir(i8 %a) nounwind {
|
||||
%t1 = and i8 15, %a
|
||||
@ -30,7 +30,7 @@ define i8 @bitbir(i8 %a) nounwind {
|
||||
ret i8 %t3
|
||||
}
|
||||
; CHECK-LABEL: bitbir:
|
||||
; CHECK: bit.b #15, r15
|
||||
; CHECK: bit.b #15, r12
|
||||
|
||||
define i8 @bitbmi() nounwind {
|
||||
%t1 = load i8, i8* @foo8
|
||||
@ -60,7 +60,7 @@ define i8 @bitbrm(i8 %a) nounwind {
|
||||
ret i8 %t4
|
||||
}
|
||||
; CHECK-LABEL: bitbrm:
|
||||
; CHECK: bit.b &foo8, r15
|
||||
; CHECK: bit.b &foo8, r12
|
||||
|
||||
define i8 @bitbmr(i8 %a) nounwind {
|
||||
%t1 = load i8, i8* @foo8
|
||||
@ -70,7 +70,7 @@ define i8 @bitbmr(i8 %a) nounwind {
|
||||
ret i8 %t4
|
||||
}
|
||||
; CHECK-LABEL: bitbmr:
|
||||
; CHECK: bit.b r15, &foo8
|
||||
; CHECK: bit.b r12, &foo8
|
||||
|
||||
define i8 @bitbmm() nounwind {
|
||||
%t1 = load i8, i8* @foo8
|
||||
@ -93,7 +93,7 @@ define i16 @bitwrr(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t3
|
||||
}
|
||||
; CHECK-LABEL: bitwrr:
|
||||
; CHECK: bit.w r14, r15
|
||||
; CHECK: bit.w r13, r12
|
||||
|
||||
define i16 @bitwri(i16 %a) nounwind {
|
||||
%t1 = and i16 %a, 4080
|
||||
@ -102,7 +102,7 @@ define i16 @bitwri(i16 %a) nounwind {
|
||||
ret i16 %t3
|
||||
}
|
||||
; CHECK-LABEL: bitwri:
|
||||
; CHECK: bit.w #4080, r15
|
||||
; CHECK: bit.w #4080, r12
|
||||
|
||||
define i16 @bitwir(i16 %a) nounwind {
|
||||
%t1 = and i16 4080, %a
|
||||
@ -111,7 +111,7 @@ define i16 @bitwir(i16 %a) nounwind {
|
||||
ret i16 %t3
|
||||
}
|
||||
; CHECK-LABEL: bitwir:
|
||||
; CHECK: bit.w #4080, r15
|
||||
; CHECK: bit.w #4080, r12
|
||||
|
||||
define i16 @bitwmi() nounwind {
|
||||
%t1 = load i16, i16* @foo16
|
||||
@ -141,7 +141,7 @@ define i16 @bitwrm(i16 %a) nounwind {
|
||||
ret i16 %t4
|
||||
}
|
||||
; CHECK-LABEL: bitwrm:
|
||||
; CHECK: bit.w &foo16, r15
|
||||
; CHECK: bit.w &foo16, r12
|
||||
|
||||
define i16 @bitwmr(i16 %a) nounwind {
|
||||
%t1 = load i16, i16* @foo16
|
||||
@ -151,7 +151,7 @@ define i16 @bitwmr(i16 %a) nounwind {
|
||||
ret i16 %t4
|
||||
}
|
||||
; CHECK-LABEL: bitwmr:
|
||||
; CHECK: bit.w r15, &foo16
|
||||
; CHECK: bit.w r12, &foo16
|
||||
|
||||
define i16 @bitwmm() nounwind {
|
||||
%t1 = load i16, i16* @foo16
|
||||
|
@ -9,7 +9,7 @@ target triple = "msp430---elf"
|
||||
define i16 @callee(%struct.Foo* byval %f) nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: callee:
|
||||
; CHECK: mov.w 2(r1), r15
|
||||
; CHECK: mov.w 2(r1), r12
|
||||
%0 = getelementptr inbounds %struct.Foo, %struct.Foo* %f, i32 0, i32 0
|
||||
%1 = load i16, i16* %0, align 2
|
||||
ret i16 %1
|
||||
|
@ -7,12 +7,12 @@ define void @test() #0 {
|
||||
entry:
|
||||
; CHECK: test:
|
||||
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: call #f_i16
|
||||
call void @f_i16(i16 1)
|
||||
|
||||
; CHECK: mov.w #772, r14
|
||||
; CHECK: mov.w #258, r15
|
||||
; CHECK: mov.w #772, r12
|
||||
; CHECK: mov.w #258, r13
|
||||
; CHECK: call #f_i32
|
||||
call void @f_i32(i32 16909060)
|
||||
|
||||
@ -23,26 +23,34 @@ entry:
|
||||
; CHECK: call #f_i64
|
||||
call void @f_i64(i64 72623859790382856)
|
||||
|
||||
; CHECK: mov.w #772, r14
|
||||
; CHECK: mov.w #258, r15
|
||||
; CHECK: mov.w #1800, r12
|
||||
; CHECK: mov.w #1286, r13
|
||||
; CHECK: mov.w #772, r12
|
||||
; CHECK: mov.w #258, r13
|
||||
; CHECK: mov.w #1800, r14
|
||||
; CHECK: mov.w #1286, r15
|
||||
; CHECK: call #f_i32_i32
|
||||
call void @f_i32_i32(i32 16909060, i32 84281096)
|
||||
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: mov.w #772, r13
|
||||
; CHECK: mov.w #258, r14
|
||||
; CHECK: mov.w #2, r12
|
||||
; CHECK: mov.w #2, r15
|
||||
; CHECK: call #f_i16_i32_i16
|
||||
call void @f_i16_i32_i16(i16 1, i32 16909060, i16 2)
|
||||
|
||||
; CHECK: mov.w #2, 8(r1)
|
||||
; CHECK: mov.w #1286, 0(r1)
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: mov.w #772, r13
|
||||
; CHECK: mov.w #258, r14
|
||||
; CHECK: mov.w #1800, r15
|
||||
; CHECK: call #f_i16_i32_i32
|
||||
call void @f_i16_i32_i32(i16 1, i32 16909060, i32 84281096)
|
||||
|
||||
; CHECK: mov.w #258, 6(r1)
|
||||
; CHECK: mov.w #772, 4(r1)
|
||||
; CHECK: mov.w #1286, 2(r1)
|
||||
; CHECK: mov.w #1800, 0(r1)
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: mov.w #2, r13
|
||||
; CHECK: call #f_i16_i64_i16
|
||||
call void @f_i16_i64_i16(i16 1, i64 72623859790382856, i16 2)
|
||||
|
||||
@ -55,15 +63,15 @@ entry:
|
||||
|
||||
define void @f_i16(i16 %a) #0 {
|
||||
; CHECK: f_i16:
|
||||
; CHECK: mov.w r15, &g_i16
|
||||
; CHECK: mov.w r12, &g_i16
|
||||
store volatile i16 %a, i16* @g_i16, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f_i32(i32 %a) #0 {
|
||||
; CHECK: f_i32:
|
||||
; CHECK: mov.w r15, &g_i32+2
|
||||
; CHECK: mov.w r14, &g_i32
|
||||
; CHECK: mov.w r13, &g_i32+2
|
||||
; CHECK: mov.w r12, &g_i32
|
||||
store volatile i32 %a, i32* @g_i32, align 2
|
||||
ret void
|
||||
}
|
||||
@ -80,37 +88,50 @@ define void @f_i64(i64 %a) #0 {
|
||||
|
||||
define void @f_i32_i32(i32 %a, i32 %b) #0 {
|
||||
; CHECK: f_i32_i32:
|
||||
; CHECK: mov.w r15, &g_i32+2
|
||||
; CHECK: mov.w r14, &g_i32
|
||||
store volatile i32 %a, i32* @g_i32, align 2
|
||||
; CHECK: mov.w r13, &g_i32+2
|
||||
; CHECK: mov.w r12, &g_i32
|
||||
store volatile i32 %a, i32* @g_i32, align 2
|
||||
; CHECK: mov.w r15, &g_i32+2
|
||||
; CHECK: mov.w r14, &g_i32
|
||||
store volatile i32 %b, i32* @g_i32, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f_i16_i32_i32(i16 %a, i32 %b, i32 %c) #0 {
|
||||
; CHECK: f_i16_i32_i32:
|
||||
; CHECK: mov.w r12, &g_i16
|
||||
store volatile i16 %a, i16* @g_i16, align 2
|
||||
; CHECK: mov.w r14, &g_i32+2
|
||||
; CHECK: mov.w r13, &g_i32
|
||||
store volatile i32 %b, i32* @g_i32, align 2
|
||||
; CHECK: mov.w r15, &g_i32
|
||||
; CHECK: mov.w 4(r4), &g_i32+2
|
||||
store volatile i32 %c, i32* @g_i32, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f_i16_i32_i16(i16 %a, i32 %b, i16 %c) #0 {
|
||||
; CHECK: f_i16_i32_i16:
|
||||
; CHECK: mov.w r15, &g_i16
|
||||
; CHECK: mov.w r12, &g_i16
|
||||
store volatile i16 %a, i16* @g_i16, align 2
|
||||
; CHECK: mov.w r14, &g_i32+2
|
||||
; CHECK: mov.w r13, &g_i32
|
||||
store volatile i32 %b, i32* @g_i32, align 2
|
||||
; CHECK: mov.w r12, &g_i16
|
||||
; CHECK: mov.w r15, &g_i16
|
||||
store volatile i16 %c, i16* @g_i16, align 2
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @f_i16_i64_i16(i16 %a, i64 %b, i16 %c) #0 {
|
||||
; CHECK: f_i16_i64_i16:
|
||||
; CHECK: mov.w r15, &g_i16
|
||||
; CHECK: mov.w r12, &g_i16
|
||||
store volatile i16 %a, i16* @g_i16, align 2
|
||||
;CHECK: mov.w 10(r4), &g_i64+6
|
||||
;CHECK: mov.w 8(r4), &g_i64+4
|
||||
;CHECK: mov.w 6(r4), &g_i64+2
|
||||
;CHECK: mov.w 4(r4), &g_i64
|
||||
store volatile i64 %b, i64* @g_i64, align 2
|
||||
;CHECK: mov.w 12(r4), &g_i16
|
||||
;CHECK: mov.w r13, &g_i16
|
||||
store volatile i16 %c, i16* @g_i16, align 2
|
||||
ret void
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ entry:
|
||||
; CHECK: test:
|
||||
|
||||
; CHECK: call #f_i16
|
||||
; CHECK: mov.w r15, &g_i16
|
||||
; CHECK: mov.w r12, &g_i16
|
||||
%0 = call i16 @f_i16()
|
||||
store volatile i16 %0, i16* @g_i16
|
||||
|
||||
; CHECK: call #f_i32
|
||||
; CHECK: mov.w r15, &g_i32+2
|
||||
; CHECK: mov.w r14, &g_i32
|
||||
; CHECK: mov.w r13, &g_i32+2
|
||||
; CHECK: mov.w r12, &g_i32
|
||||
%1 = call i32 @f_i32()
|
||||
store volatile i32 %1, i32* @g_i32
|
||||
|
||||
@ -35,15 +35,15 @@ entry:
|
||||
|
||||
define i16 @f_i16() #0 {
|
||||
; CHECK: f_i16:
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: ret
|
||||
ret i16 1
|
||||
}
|
||||
|
||||
define i32 @f_i32() #0 {
|
||||
; CHECK: f_i32:
|
||||
; CHECK: mov.w #772, r14
|
||||
; CHECK: mov.w #258, r15
|
||||
; CHECK: mov.w #772, r12
|
||||
; CHECK: mov.w #258, r13
|
||||
; CHECK: ret
|
||||
ret i32 16909060
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ define internal i16 @foo(i16 %i) nounwind {
|
||||
entry:
|
||||
%tmp1 = getelementptr inbounds [5 x i8*], [5 x i8*]* @C.0.2070, i16 0, i16 %i ; <i8**> [#uses=1]
|
||||
%gotovar.4.0 = load i8*, i8** %tmp1, align 4 ; <i8*> [#uses=1]
|
||||
; CHECK: br .LC.0.2070(r15)
|
||||
; CHECK: br .LC.0.2070(r12)
|
||||
indirectbr i8* %gotovar.4.0, [label %L5, label %L4, label %L3, label %L2, label %L1]
|
||||
|
||||
L5: ; preds = %bb2
|
||||
|
@ -11,9 +11,9 @@ entry:
|
||||
%i.addr = alloca i16, align 2
|
||||
store i16 %i, i16* %i.addr, align 2
|
||||
%0 = load i16, i16* %i.addr, align 2
|
||||
; CHECK: mov.w #2, r14
|
||||
; CHECK: mov.w #2, r13
|
||||
; CHECK: call #__mulhi3hw_noint
|
||||
; CHECK: br .LJTI0_0(r15)
|
||||
; CHECK: br .LJTI0_0(r12)
|
||||
switch i16 %0, label %sw.default [
|
||||
i16 0, label %sw.bb
|
||||
i16 1, label %sw.bb1
|
||||
|
@ -9,9 +9,9 @@ define void @test() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: test:
|
||||
%0 = load i8*, i8** @buf, align 2
|
||||
; CHECK: mov.w &buf, r15
|
||||
; CHECK-NEXT: mov.w #5, r14
|
||||
; CHECK-NEXT: mov.w #128, r13
|
||||
; CHECK: mov.w &buf, r12
|
||||
; CHECK-NEXT: mov.w #5, r13
|
||||
; CHECK-NEXT: mov.w #128, r14
|
||||
; CHECK-NEXT: call #memset
|
||||
call void @llvm.memset.p0i8.i16(i8* %0, i8 5, i16 128, i32 1, i1 false)
|
||||
ret void
|
||||
|
@ -9,10 +9,10 @@ define i16 @sccweqand(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t3
|
||||
}
|
||||
; CHECK-LABEL: sccweqand:
|
||||
; CHECK: bit.w r14, r15
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: rra.w r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: bit.w r13, r12
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: rra.w r12
|
||||
; CHECK: and.w #1, r12
|
||||
|
||||
define i16 @sccwneand(i16 %a, i16 %b) nounwind {
|
||||
%t1 = and i16 %a, %b
|
||||
@ -21,9 +21,9 @@ define i16 @sccwneand(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t3
|
||||
}
|
||||
; CHECK-LABEL: sccwneand:
|
||||
; CHECK: bit.w r14, r15
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: bit.w r13, r12
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: and.w #1, r12
|
||||
|
||||
define i16 @sccwne(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp ne i16 %a, %b
|
||||
@ -31,11 +31,11 @@ define i16 @sccwne(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t2
|
||||
}
|
||||
; CHECK-LABEL:sccwne:
|
||||
; CHECK: cmp.w r14, r15
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: rra.w r12
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: bic.w r12, r15
|
||||
; CHECK: cmp.w r13, r12
|
||||
; CHECK: mov.w r2, r13
|
||||
; CHECK: rra.w r13
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: bic.w r13, r12
|
||||
|
||||
define i16 @sccweq(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp eq i16 %a, %b
|
||||
@ -43,10 +43,10 @@ define i16 @sccweq(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t2
|
||||
}
|
||||
; CHECK-LABEL:sccweq:
|
||||
; CHECK: cmp.w r14, r15
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: rra.w r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: cmp.w r13, r12
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: rra.w r12
|
||||
; CHECK: and.w #1, r12
|
||||
|
||||
define i16 @sccwugt(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp ugt i16 %a, %b
|
||||
@ -54,9 +54,9 @@ define i16 @sccwugt(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t2
|
||||
}
|
||||
; CHECK-LABEL:sccwugt:
|
||||
; CHECK: cmp.w r15, r14
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: bic.w r2, r15
|
||||
; CHECK: cmp.w r12, r13
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: bic.w r2, r12
|
||||
|
||||
define i16 @sccwuge(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp uge i16 %a, %b
|
||||
@ -64,9 +64,9 @@ define i16 @sccwuge(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t2
|
||||
}
|
||||
; CHECK-LABEL:sccwuge:
|
||||
; CHECK: cmp.w r14, r15
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: cmp.w r13, r12
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: and.w #1, r12
|
||||
|
||||
define i16 @sccwult(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp ult i16 %a, %b
|
||||
@ -74,9 +74,9 @@ define i16 @sccwult(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t2
|
||||
}
|
||||
; CHECK-LABEL:sccwult:
|
||||
; CHECK: cmp.w r14, r15
|
||||
; CHECK: mov.w #1, r15
|
||||
; CHECK: bic.w r2, r15
|
||||
; CHECK: cmp.w r13, r12
|
||||
; CHECK: mov.w #1, r12
|
||||
; CHECK: bic.w r2, r12
|
||||
|
||||
define i16 @sccwule(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp ule i16 %a, %b
|
||||
@ -84,9 +84,9 @@ define i16 @sccwule(i16 %a, i16 %b) nounwind {
|
||||
ret i16 %t2
|
||||
}
|
||||
; CHECK-LABEL:sccwule:
|
||||
; CHECK: cmp.w r15, r14
|
||||
; CHECK: mov.w r2, r15
|
||||
; CHECK: and.w #1, r15
|
||||
; CHECK: cmp.w r12, r13
|
||||
; CHECK: mov.w r2, r12
|
||||
; CHECK: and.w #1, r12
|
||||
|
||||
define i16 @sccwsgt(i16 %a, i16 %b) nounwind {
|
||||
%t1 = icmp sgt i16 %a, %b
|
||||
|
23
test/CodeGen/MSP430/struct-return.ll
Normal file
23
test/CodeGen/MSP430/struct-return.ll
Normal file
@ -0,0 +1,23 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
|
||||
target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"
|
||||
target triple = "msp430---elf"
|
||||
|
||||
; Allow simple structures to be returned by value.
|
||||
|
||||
%s = type { i64, i64 }
|
||||
|
||||
define %s @fred() #0 {
|
||||
; CHECK-LABEL: fred:
|
||||
; CHECK: mov.w #2314, 14(r12)
|
||||
; CHECK: mov.w #2828, 12(r12)
|
||||
; CHECK: mov.w #3342, 10(r12)
|
||||
; CHECK: mov.w #3840, 8(r12)
|
||||
; CHECK: mov.w #258, 6(r12)
|
||||
; CHECK: mov.w #772, 4(r12)
|
||||
; CHECK: mov.w #1286, 2(r12)
|
||||
; CHECK: mov.w #1800, 0(r12)
|
||||
ret %s {i64 72623859790382856, i64 651345242494996224}
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind }
|
@ -25,13 +25,13 @@ define i16 @va_arg(i8* %vl) nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: va_arg:
|
||||
%vl.addr = alloca i8*, align 2
|
||||
; CHECK: mov.w r15, 0(r1)
|
||||
; CHECK: mov.w r12, 0(r1)
|
||||
store i8* %vl, i8** %vl.addr, align 2
|
||||
; CHECK: mov.w r15, [[REG:r[0-9]+]]
|
||||
; CHECK: mov.w r12, [[REG:r[0-9]+]]
|
||||
; CHECK-NEXT: add.w #2, [[REG]]
|
||||
; CHECK-NEXT: mov.w [[REG]], 0(r1)
|
||||
%0 = va_arg i8** %vl.addr, i16
|
||||
; CHECK-NEXT: mov.w 0(r15), r15
|
||||
; CHECK-NEXT: mov.w 0(r12), r12
|
||||
ret i16 %0
|
||||
}
|
||||
|
||||
@ -40,11 +40,11 @@ entry:
|
||||
; CHECK-LABEL: va_copy:
|
||||
%vl.addr = alloca i8*, align 2
|
||||
%vl2 = alloca i8*, align 2
|
||||
; CHECK: mov.w r15, 2(r1)
|
||||
; CHECK: mov.w r12, 2(r1)
|
||||
store i8* %vl, i8** %vl.addr, align 2
|
||||
%0 = bitcast i8** %vl2 to i8*
|
||||
%1 = bitcast i8** %vl.addr to i8*
|
||||
; CHECK-NEXT: mov.w r15, 0(r1)
|
||||
; CHECK-NEXT: mov.w r12, 0(r1)
|
||||
call void @llvm.va_copy(i8* %0, i8* %1)
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user