[Xtensa] Implement THREADPTR and DFPAccel Xtensa Options. (#145543)
Implment base support of the TLS functionality using Xtensa THREADPTR Option. Implement basic functionality of the DFPAccel Option(registers support).
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "MCTargetDesc/XtensaMCExpr.h"
|
||||||
#include "MCTargetDesc/XtensaMCTargetDesc.h"
|
#include "MCTargetDesc/XtensaMCTargetDesc.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/BinaryFormat/ELF.h"
|
#include "llvm/BinaryFormat/ELF.h"
|
||||||
@@ -45,10 +46,12 @@ XtensaObjectWriter::~XtensaObjectWriter() {}
|
|||||||
unsigned XtensaObjectWriter::getRelocType(const MCFixup &Fixup,
|
unsigned XtensaObjectWriter::getRelocType(const MCFixup &Fixup,
|
||||||
const MCValue &Target,
|
const MCValue &Target,
|
||||||
bool IsPCRel) const {
|
bool IsPCRel) const {
|
||||||
|
uint8_t Specifier = Target.getSpecifier();
|
||||||
|
|
||||||
switch ((unsigned)Fixup.getKind()) {
|
switch ((unsigned)Fixup.getKind()) {
|
||||||
case FK_Data_4:
|
case FK_Data_4:
|
||||||
return ELF::R_XTENSA_32;
|
return Specifier == Xtensa::S_TPOFF ? ELF::R_XTENSA_TLS_TPOFF
|
||||||
|
: ELF::R_XTENSA_32;
|
||||||
default:
|
default:
|
||||||
return ELF::R_XTENSA_SLOT0_OP;
|
return ELF::R_XTENSA_SLOT0_OP;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,11 +186,17 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
|
|||||||
return FeatureBits[Xtensa::FeatureMiscSR];
|
return FeatureBits[Xtensa::FeatureMiscSR];
|
||||||
case Xtensa::PRID:
|
case Xtensa::PRID:
|
||||||
return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeaturePRID];
|
return RAType == Xtensa::REGISTER_READ && FeatureBits[Xtensa::FeaturePRID];
|
||||||
|
case Xtensa::THREADPTR:
|
||||||
|
return FeatureBits[FeatureTHREADPTR];
|
||||||
case Xtensa::VECBASE:
|
case Xtensa::VECBASE:
|
||||||
return FeatureBits[Xtensa::FeatureRelocatableVector];
|
return FeatureBits[Xtensa::FeatureRelocatableVector];
|
||||||
case Xtensa::FCR:
|
case Xtensa::FCR:
|
||||||
case Xtensa::FSR:
|
case Xtensa::FSR:
|
||||||
return FeatureBits[FeatureSingleFloat];
|
return FeatureBits[FeatureSingleFloat];
|
||||||
|
case Xtensa::F64R_LO:
|
||||||
|
case Xtensa::F64R_HI:
|
||||||
|
case Xtensa::F64S:
|
||||||
|
return FeatureBits[FeatureDFPAccel];
|
||||||
case Xtensa::WINDOWBASE:
|
case Xtensa::WINDOWBASE:
|
||||||
case Xtensa::WINDOWSTART:
|
case Xtensa::WINDOWSTART:
|
||||||
return FeatureBits[Xtensa::FeatureWindowed];
|
return FeatureBits[Xtensa::FeatureWindowed];
|
||||||
@@ -203,12 +209,23 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
|
|||||||
|
|
||||||
// Get Xtensa User Register by encoding value.
|
// Get Xtensa User Register by encoding value.
|
||||||
MCRegister Xtensa::getUserRegister(unsigned Code, const MCRegisterInfo &MRI) {
|
MCRegister Xtensa::getUserRegister(unsigned Code, const MCRegisterInfo &MRI) {
|
||||||
|
MCRegister UserReg = Xtensa::NoRegister;
|
||||||
|
|
||||||
if (MRI.getEncodingValue(Xtensa::FCR) == Code) {
|
if (MRI.getEncodingValue(Xtensa::FCR) == Code) {
|
||||||
return Xtensa::FCR;
|
UserReg = Xtensa::FCR;
|
||||||
} else if (MRI.getEncodingValue(Xtensa::FSR) == Code) {
|
} else if (MRI.getEncodingValue(Xtensa::FSR) == Code) {
|
||||||
return Xtensa::FSR;
|
UserReg = Xtensa::FSR;
|
||||||
|
} else if (MRI.getEncodingValue(Xtensa::F64R_LO) == Code) {
|
||||||
|
UserReg = Xtensa::F64R_LO;
|
||||||
|
} else if (MRI.getEncodingValue(Xtensa::F64R_HI) == Code) {
|
||||||
|
UserReg = Xtensa::F64R_HI;
|
||||||
|
} else if (MRI.getEncodingValue(Xtensa::F64S) == Code) {
|
||||||
|
UserReg = Xtensa::F64S;
|
||||||
|
} else if (MRI.getEncodingValue(Xtensa::THREADPTR) == Code) {
|
||||||
|
UserReg = Xtensa::THREADPTR;
|
||||||
}
|
}
|
||||||
return Xtensa::NoRegister;
|
|
||||||
|
return UserReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
|
static MCAsmInfo *createXtensaMCAsmInfo(const MCRegisterInfo &MRI,
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ def FeatureDataCache : SubtargetFeature<"dcache", "HasDataCache", "true",
|
|||||||
def HasDataCache : Predicate<"Subtarget->hasDataCache()">,
|
def HasDataCache : Predicate<"Subtarget->hasDataCache()">,
|
||||||
AssemblerPredicate<(all_of FeatureDataCache)>;
|
AssemblerPredicate<(all_of FeatureDataCache)>;
|
||||||
|
|
||||||
|
def FeatureTHREADPTR : SubtargetFeature<"threadptr", "HasTHREADPTR", "true",
|
||||||
|
"Enable Xtensa THREADPTR option">;
|
||||||
|
def HasTHREADPTR : Predicate<"Subtarget->hasTHREADPTR()">,
|
||||||
|
AssemblerPredicate<(all_of FeatureTHREADPTR)>;
|
||||||
|
|
||||||
// Xtensa Interrupts Options.
|
// Xtensa Interrupts Options.
|
||||||
def FeatureHighPriInterrupts : SubtargetFeature<"highpriinterrupts",
|
def FeatureHighPriInterrupts : SubtargetFeature<"highpriinterrupts",
|
||||||
"HasHighPriInterrupts", "true",
|
"HasHighPriInterrupts", "true",
|
||||||
@@ -137,3 +142,8 @@ def FeatureCoprocessor : SubtargetFeature<"coprocessor", "HasCoprocessor", "true
|
|||||||
"Enable Xtensa Coprocessor option">;
|
"Enable Xtensa Coprocessor option">;
|
||||||
def HasCoprocessor : Predicate<"Subtarget->hasCoprocessor()">,
|
def HasCoprocessor : Predicate<"Subtarget->hasCoprocessor()">,
|
||||||
AssemblerPredicate<(all_of FeatureCoprocessor)>;
|
AssemblerPredicate<(all_of FeatureCoprocessor)>;
|
||||||
|
|
||||||
|
def FeatureDFPAccel : SubtargetFeature<"dfpaccel", "HasDFPAccel", "true",
|
||||||
|
"Enable Xtensa Double Precision FP acceleration">;
|
||||||
|
def HasDFPAccel : Predicate<"Subtarget->hasDFPAccel()">,
|
||||||
|
AssemblerPredicate<(all_of FeatureDFPAccel)>;
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &TM,
|
|||||||
|
|
||||||
setOperationAction(ISD::ConstantPool, PtrVT, Custom);
|
setOperationAction(ISD::ConstantPool, PtrVT, Custom);
|
||||||
setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
|
setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
|
||||||
|
setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);
|
||||||
setOperationAction(ISD::BlockAddress, PtrVT, Custom);
|
setOperationAction(ISD::BlockAddress, PtrVT, Custom);
|
||||||
setOperationAction(ISD::JumpTable, PtrVT, Custom);
|
setOperationAction(ISD::JumpTable, PtrVT, Custom);
|
||||||
|
|
||||||
@@ -972,6 +973,58 @@ SDValue XtensaTargetLowering::LowerGlobalAddress(SDValue Op,
|
|||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue XtensaTargetLowering::LowerGlobalTLSAddress(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
const GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(Op);
|
||||||
|
SDLoc DL(Op);
|
||||||
|
EVT PtrVT = Op.getValueType();
|
||||||
|
const GlobalValue *GV = G->getGlobal();
|
||||||
|
|
||||||
|
if (DAG.getTarget().useEmulatedTLS())
|
||||||
|
return LowerToTLSEmulatedModel(G, DAG);
|
||||||
|
|
||||||
|
TLSModel::Model model = getTargetMachine().getTLSModel(GV);
|
||||||
|
|
||||||
|
if (!Subtarget.hasTHREADPTR()) {
|
||||||
|
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
|
||||||
|
DAG.getMachineFunction().getFunction(), "only emulated TLS supported",
|
||||||
|
DL.getDebugLoc()));
|
||||||
|
return DAG.getPOISON(Op->getValueType(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (model == TLSModel::LocalExec || model == TLSModel::InitialExec) {
|
||||||
|
bool Priv = GV->isPrivateLinkage(GV->getLinkage());
|
||||||
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
|
XtensaMachineFunctionInfo *XtensaFI =
|
||||||
|
MF.getInfo<XtensaMachineFunctionInfo>();
|
||||||
|
unsigned LabelId = XtensaFI->createCPLabelId();
|
||||||
|
|
||||||
|
// Create a constant pool entry for the callee address
|
||||||
|
XtensaConstantPoolValue *CPV = XtensaConstantPoolSymbol::Create(
|
||||||
|
*DAG.getContext(), GV->getName().str().c_str(), LabelId, Priv,
|
||||||
|
XtensaCP::TPOFF);
|
||||||
|
|
||||||
|
// Get the address of the callee into a register
|
||||||
|
SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, Align(4));
|
||||||
|
SDValue CPWrap = getAddrPCRel(CPAddr, DAG);
|
||||||
|
SDValue Addr = DAG.getLoad(
|
||||||
|
PtrVT, DL, DAG.getEntryNode(), CPWrap,
|
||||||
|
MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
|
||||||
|
|
||||||
|
SDValue TPRegister = DAG.getRegister(Xtensa::THREADPTR, MVT::i32);
|
||||||
|
SDValue ThreadPointer =
|
||||||
|
DAG.getNode(XtensaISD::RUR, DL, MVT::i32, TPRegister);
|
||||||
|
|
||||||
|
return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DAG.getContext()->diagnose(DiagnosticInfoUnsupported(
|
||||||
|
DAG.getMachineFunction().getFunction(),
|
||||||
|
"only local-exec and initial-exec TLS mode supported", DL.getDebugLoc()));
|
||||||
|
|
||||||
|
return DAG.getPOISON(Op->getValueType(0));
|
||||||
|
}
|
||||||
|
|
||||||
SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
|
SDValue XtensaTargetLowering::LowerBlockAddress(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
|
BlockAddressSDNode *Node = cast<BlockAddressSDNode>(Op);
|
||||||
@@ -1406,6 +1459,8 @@ SDValue XtensaTargetLowering::LowerOperation(SDValue Op,
|
|||||||
return LowerRETURNADDR(Op, DAG);
|
return LowerRETURNADDR(Op, DAG);
|
||||||
case ISD::GlobalAddress:
|
case ISD::GlobalAddress:
|
||||||
return LowerGlobalAddress(Op, DAG);
|
return LowerGlobalAddress(Op, DAG);
|
||||||
|
case ISD::GlobalTLSAddress:
|
||||||
|
return LowerGlobalTLSAddress(Op, DAG);
|
||||||
case ISD::BlockAddress:
|
case ISD::BlockAddress:
|
||||||
return LowerBlockAddress(Op, DAG);
|
return LowerBlockAddress(Op, DAG);
|
||||||
case ISD::JumpTable:
|
case ISD::JumpTable:
|
||||||
@@ -1459,6 +1514,8 @@ const char *XtensaTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
return "XtensaISD::RET";
|
return "XtensaISD::RET";
|
||||||
case XtensaISD::RETW:
|
case XtensaISD::RETW:
|
||||||
return "XtensaISD::RETW";
|
return "XtensaISD::RETW";
|
||||||
|
case XtensaISD::RUR:
|
||||||
|
return "XtensaISD::RUR";
|
||||||
case XtensaISD::SELECT_CC:
|
case XtensaISD::SELECT_CC:
|
||||||
return "XtensaISD::SELECT_CC";
|
return "XtensaISD::SELECT_CC";
|
||||||
case XtensaISD::SELECT_CC_FP:
|
case XtensaISD::SELECT_CC_FP:
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ enum {
|
|||||||
RET,
|
RET,
|
||||||
RETW,
|
RETW,
|
||||||
|
|
||||||
|
RUR,
|
||||||
|
|
||||||
// Select with condition operator - This selects between a true value and
|
// Select with condition operator - This selects between a true value and
|
||||||
// a false value (ops #2 and #3) based on the boolean result of comparing
|
// a false value (ops #2 and #3) based on the boolean result of comparing
|
||||||
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
|
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
|
||||||
@@ -161,6 +163,8 @@ private:
|
|||||||
|
|
||||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
|
||||||
|
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
|
||||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
|
||||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
|||||||
@@ -575,7 +575,7 @@ def WUR : RRR_Inst<0x00, 0x03, 0x0F, (outs UR:$ur), (ins AR:$t),
|
|||||||
}
|
}
|
||||||
|
|
||||||
def RUR : RRR_Inst<0x00, 0x03, 0x0E, (outs AR:$r), (ins UR:$ur),
|
def RUR : RRR_Inst<0x00, 0x03, 0x0E, (outs AR:$r), (ins UR:$ur),
|
||||||
"rur\t$r, $ur", []> {
|
"rur\t$r, $ur", [(set AR:$r, (Xtensa_rur UR:$ur))]> {
|
||||||
bits<8> ur;
|
bits<8> ur;
|
||||||
|
|
||||||
let s = ur{7-4};
|
let s = ur{7-4};
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ def SDT_XtensaEXTUI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCi
|
|||||||
|
|
||||||
def SDT_XtensaMOVSP : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
|
def SDT_XtensaMOVSP : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
|
||||||
|
|
||||||
|
def SDT_XtensaRUR : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Node definitions
|
// Node definitions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@@ -77,6 +79,9 @@ def Xtensa_extui: SDNode<"XtensaISD::EXTUI", SDT_XtensaEXTUI>;
|
|||||||
def Xtensa_movsp: SDNode<"XtensaISD::MOVSP", SDT_XtensaMOVSP,
|
def Xtensa_movsp: SDNode<"XtensaISD::MOVSP", SDT_XtensaMOVSP,
|
||||||
[SDNPHasChain, SDNPSideEffect, SDNPInGlue]>;
|
[SDNPHasChain, SDNPSideEffect, SDNPInGlue]>;
|
||||||
|
|
||||||
|
def Xtensa_rur: SDNode<"XtensaISD::RUR", SDT_XtensaRUR,
|
||||||
|
[SDNPInGlue]>;
|
||||||
|
|
||||||
def Xtensa_cmpoeq : SDNode<"XtensaISD::CMPOEQ", SDT_XtensaCmp, [SDNPOutGlue]>;
|
def Xtensa_cmpoeq : SDNode<"XtensaISD::CMPOEQ", SDT_XtensaCmp, [SDNPOutGlue]>;
|
||||||
def Xtensa_cmpolt : SDNode<"XtensaISD::CMPOLT", SDT_XtensaCmp, [SDNPOutGlue]>;
|
def Xtensa_cmpolt : SDNode<"XtensaISD::CMPOLT", SDT_XtensaCmp, [SDNPOutGlue]>;
|
||||||
def Xtensa_cmpole : SDNode<"XtensaISD::CMPOLE", SDT_XtensaCmp, [SDNPOutGlue]>;
|
def Xtensa_cmpole : SDNode<"XtensaISD::CMPOLE", SDT_XtensaCmp, [SDNPOutGlue]>;
|
||||||
|
|||||||
@@ -53,7 +53,10 @@ BitVector XtensaRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|||||||
// Reserve frame pointer.
|
// Reserve frame pointer.
|
||||||
Reserved.set(getFrameRegister(MF));
|
Reserved.set(getFrameRegister(MF));
|
||||||
}
|
}
|
||||||
|
if (Subtarget.hasTHREADPTR()) {
|
||||||
|
// Reserve frame pointer.
|
||||||
|
Reserved.set(Xtensa::THREADPTR);
|
||||||
|
}
|
||||||
// Reserve stack pointer.
|
// Reserve stack pointer.
|
||||||
Reserved.set(Xtensa::SP);
|
Reserved.set(Xtensa::SP);
|
||||||
return Reserved;
|
return Reserved;
|
||||||
|
|||||||
@@ -234,10 +234,19 @@ class URReg<bits<8> num, string n, list<string> alt = []> : XtensaReg<n> {
|
|||||||
let AltNames = alt;
|
let AltNames = alt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Thread Pointer register
|
||||||
|
def THREADPTR : URReg<231, "threadptr", ["THREADPTR"]>;
|
||||||
|
|
||||||
def FCR : URReg<232, "fcr", ["FCR"]>;
|
def FCR : URReg<232, "fcr", ["FCR"]>;
|
||||||
def FSR : URReg<233, "fsr", ["FSR"]>;
|
def FSR : URReg<233, "fsr", ["FSR"]>;
|
||||||
|
|
||||||
def UR : RegisterClass<"Xtensa", [i32], 32, (add FCR, FSR)>;
|
// DFPAccel registers
|
||||||
|
def F64R_LO : URReg<234, "f64r_lo", ["F64R_LO"]>;
|
||||||
|
def F64R_HI : URReg<235, "f64r_hi", ["F64R_HI"]>;
|
||||||
|
def F64S : URReg<236, "f64s", ["F64S"]>;
|
||||||
|
|
||||||
|
def UR : RegisterClass<"Xtensa", [i32], 32, (add
|
||||||
|
THREADPTR, FCR, FSR, F64R_LO, F64R_HI, F64S)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Floating-Point registers
|
// Floating-Point registers
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public:
|
|||||||
bool hasHighPriInterruptsLevel7() const { return HasHighPriInterruptsLevel7; }
|
bool hasHighPriInterruptsLevel7() const { return HasHighPriInterruptsLevel7; }
|
||||||
bool hasInterrupt() const { return HasInterrupt; }
|
bool hasInterrupt() const { return HasInterrupt; }
|
||||||
bool hasException() const { return HasException; }
|
bool hasException() const { return HasException; }
|
||||||
|
bool hasTHREADPTR() const { return HasTHREADPTR; }
|
||||||
bool isWindowedABI() const { return hasWindowed(); }
|
bool isWindowedABI() const { return hasWindowed(); }
|
||||||
|
|
||||||
// Automatically generated by tblgen.
|
// Automatically generated by tblgen.
|
||||||
|
|||||||
17
llvm/test/CodeGen/Xtensa/invalid-tls.ll
Normal file
17
llvm/test/CodeGen/Xtensa/invalid-tls.ll
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
; RUN: not llc -mtriple=xtensa -mattr=+threadptr -relocation-model=pic -filetype=null < %s 2>&1 \
|
||||||
|
; RUN: | FileCheck -check-prefix=XTENSA-PIC %s
|
||||||
|
; RUN: not llc -mtriple=xtensa -filetype=null < %s 2>&1 \
|
||||||
|
; RUN: | FileCheck -check-prefix=XTENSA-NO-THREADPTR %s
|
||||||
|
|
||||||
|
; XTENSA-PIC: error: <unknown>:0:0: in function f i32 (): only local-exec and initial-exec TLS mode supported
|
||||||
|
; XTENSA-PIC: error: <unknown>:0:0: in function f i32 (): PIC relocations are not supported
|
||||||
|
|
||||||
|
; XTENSA-NO-THREADPTR: error: <unknown>:0:0: in function f i32 (): only emulated TLS supported
|
||||||
|
|
||||||
|
@i = external thread_local global i32
|
||||||
|
|
||||||
|
define i32 @f() {
|
||||||
|
entry:
|
||||||
|
%tmp1 = load i32, ptr @i
|
||||||
|
ret i32 %tmp1
|
||||||
|
}
|
||||||
18
llvm/test/CodeGen/Xtensa/threadptr.ll
Normal file
18
llvm/test/CodeGen/Xtensa/threadptr.ll
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
||||||
|
; RUN: llc -mtriple=xtensa -mattr=+threadptr < %s | FileCheck %s
|
||||||
|
|
||||||
|
@i = external thread_local global i32
|
||||||
|
|
||||||
|
define i32 @f() {
|
||||||
|
; CHECK-LABEL: f:
|
||||||
|
; CHECK: .cfi_startproc
|
||||||
|
; CHECK-NEXT: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: l32r a8, .LCPI0_0
|
||||||
|
; CHECK-NEXT: rur a9, threadptr
|
||||||
|
; CHECK-NEXT: add a8, a9, a8
|
||||||
|
; CHECK-NEXT: l32i a2, a8, 0
|
||||||
|
; CHECK-NEXT: ret
|
||||||
|
entry:
|
||||||
|
%tmp1 = load i32, ptr @i
|
||||||
|
ret i32 %tmp1
|
||||||
|
}
|
||||||
19
llvm/test/MC/Disassembler/Xtensa/dfpaccel.txt
Normal file
19
llvm/test/MC/Disassembler/Xtensa/dfpaccel.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
|
||||||
|
# RUN: llvm-mc -triple=xtensa -mattr=+dfpaccel -disassemble %s | FileCheck -check-prefixes=CHECK-DFPACCEL %s
|
||||||
|
# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
|
||||||
|
|
||||||
|
## Verify that binary code is correctly disassembled with
|
||||||
|
## DFPACCEL option enabled. Also verify that dissasembling without
|
||||||
|
## DFPACCEL option generates warnings.
|
||||||
|
|
||||||
|
[0xa0,0x3e,0xe3]
|
||||||
|
# CHECK-DFPACCEL: rur a3, f64r_lo
|
||||||
|
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
|
||||||
|
|
||||||
|
[0xb0,0x3e,0xe3]
|
||||||
|
# CHECK-DFPACCEL: rur a3, f64r_hi
|
||||||
|
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
|
||||||
|
|
||||||
|
[0xc0,0x3e,0xe3]
|
||||||
|
# CHECK-DFPACCEL: rur a3, f64s
|
||||||
|
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
|
||||||
11
llvm/test/MC/Disassembler/Xtensa/threadptr.txt
Normal file
11
llvm/test/MC/Disassembler/Xtensa/threadptr.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mc_test_checks.py UTC_ARGS: --version 5
|
||||||
|
# RUN: llvm-mc -triple=xtensa -mattr=+threadptr -disassemble %s | FileCheck -check-prefixes=CHECK-THREADPTR %s
|
||||||
|
# RUN: not llvm-mc -triple=xtensa -disassemble %s 2>&1 | FileCheck --implicit-check-not=warning: -check-prefixes=CHECK-CORE %s
|
||||||
|
|
||||||
|
## Verify that binary code is correctly disassembled with
|
||||||
|
## THREADPTR option enabled. Also verify that dissasembling without
|
||||||
|
## THREADPTR option generates warnings.
|
||||||
|
|
||||||
|
[0x70,0x3e,0xe3]
|
||||||
|
# CHECK-THREADPTR: rur a3, threadptr
|
||||||
|
# CHECK-CORE: :[[@LINE-2]]:2: warning: invalid instruction encoding
|
||||||
53
llvm/test/MC/Xtensa/dfpaccel.s
Normal file
53
llvm/test/MC/Xtensa/dfpaccel.s
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+dfpaccel \
|
||||||
|
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
LBL0:
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64r_lo
|
||||||
|
# CHECK: encoding: [0xa0,0x3e,0xe3]
|
||||||
|
rur a3, f64r_lo
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64r_lo
|
||||||
|
# CHECK: encoding: [0xa0,0x3e,0xe3]
|
||||||
|
rur a3, 234
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64r_lo
|
||||||
|
# CHECK: encoding: [0xa0,0x3e,0xe3]
|
||||||
|
rur.f64r_lo a3
|
||||||
|
|
||||||
|
# CHECK-INST: wur a3, f64r_lo
|
||||||
|
# CHECK: encoding: [0x30,0xea,0xf3]
|
||||||
|
wur a3, f64r_lo
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64r_hi
|
||||||
|
# CHECK: encoding: [0xb0,0x3e,0xe3]
|
||||||
|
rur a3, f64r_hi
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64r_hi
|
||||||
|
# CHECK: encoding: [0xb0,0x3e,0xe3]
|
||||||
|
rur a3, 235
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64r_hi
|
||||||
|
# CHECK: encoding: [0xb0,0x3e,0xe3]
|
||||||
|
rur.f64r_hi a3
|
||||||
|
|
||||||
|
# CHECK-INST: wur a3, f64r_hi
|
||||||
|
# CHECK: encoding: [0x30,0xeb,0xf3]
|
||||||
|
wur a3, f64r_hi
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64s
|
||||||
|
# CHECK: encoding: [0xc0,0x3e,0xe3]
|
||||||
|
rur a3, f64s
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64s
|
||||||
|
# CHECK: encoding: [0xc0,0x3e,0xe3]
|
||||||
|
rur a3, 236
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, f64s
|
||||||
|
# CHECK: encoding: [0xc0,0x3e,0xe3]
|
||||||
|
rur.f64s a3
|
||||||
|
|
||||||
|
# CHECK-INST: wur a3, f64s
|
||||||
|
# CHECK: encoding: [0x30,0xec,0xf3]
|
||||||
|
wur a3, f64s
|
||||||
21
llvm/test/MC/Xtensa/threadptr.s
Normal file
21
llvm/test/MC/Xtensa/threadptr.s
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+threadptr \
|
||||||
|
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
LBL0:
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, threadptr
|
||||||
|
# CHECK: encoding: [0x70,0x3e,0xe3]
|
||||||
|
rur a3, threadptr
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, threadptr
|
||||||
|
# CHECK: encoding: [0x70,0x3e,0xe3]
|
||||||
|
rur a3, 231
|
||||||
|
|
||||||
|
# CHECK-INST: rur a3, threadptr
|
||||||
|
# CHECK: encoding: [0x70,0x3e,0xe3]
|
||||||
|
rur.threadptr a3
|
||||||
|
|
||||||
|
# CHECK-INST: wur a3, threadptr
|
||||||
|
# CHECK: encoding: [0x30,0xe7,0xf3]
|
||||||
|
wur a3, threadptr
|
||||||
Reference in New Issue
Block a user