[llvm] 7ed515d - [AIX][XCOFF] emit vector info of traceback table.
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 14 08:15:44 PDT 2021
Author: zhijian
Date: 2021-06-14T11:15:22-04:00
New Revision: 7ed515d16803f12fc06258ebf8a405931dc8a637
URL: https://github.com/llvm/llvm-project/commit/7ed515d16803f12fc06258ebf8a405931dc8a637
DIFF: https://github.com/llvm/llvm-project/commit/7ed515d16803f12fc06258ebf8a405931dc8a637.diff
LOG: [AIX][XCOFF] emit vector info of traceback table.
Summary:
emit vector info of traceback table.
Reviewers: Jason Liu,Hubert Tong
Differential Revision: https://reviews.llvm.org/D93659
Added:
llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll
Modified:
llvm/include/llvm/BinaryFormat/XCOFF.h
llvm/include/llvm/CodeGen/MachineRegisterInfo.h
llvm/include/llvm/Object/XCOFFObjectFile.h
llvm/lib/BinaryFormat/XCOFF.cpp
llvm/lib/CodeGen/MachineRegisterInfo.cpp
llvm/lib/Object/XCOFFObjectFile.cpp
llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
llvm/test/CodeGen/PowerPC/aix-exception.ll
llvm/test/DebugInfo/XCOFF/explicit-section.ll
llvm/unittests/Object/XCOFFObjectFileTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/BinaryFormat/XCOFF.h b/llvm/include/llvm/BinaryFormat/XCOFF.h
index bd2f0ee11d4e3..cf56adffef107 100644
--- a/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -19,6 +19,7 @@
namespace llvm {
class StringRef;
template <unsigned> class SmallString;
+template <typename T> class Expected;
namespace XCOFF {
@@ -286,7 +287,14 @@ enum SymbolAuxType : uint8_t {
StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
StringRef getRelocationTypeString(XCOFF::RelocationType Type);
-SmallString<32> parseParmsType(uint32_t Value, unsigned ParmsNum);
+Expected<SmallString<32>> parseParmsType(uint32_t Value, unsigned FixedParmsNum,
+ unsigned FloatingParmsNum);
+Expected<SmallString<32>> parseParmsTypeWithVecInfo(uint32_t Value,
+ unsigned FixedParmsNum,
+ unsigned FloatingParmsNum,
+ unsigned VectorParmsNum);
+Expected<SmallString<32>> parseVectorParmsType(uint32_t Value,
+ unsigned ParmsNum);
struct TracebackTable {
enum LanguageID : uint8_t {
@@ -381,6 +389,8 @@ struct TracebackTable {
static constexpr uint32_t ParmTypeIsVectorShortBit = 0x4000'0000;
static constexpr uint32_t ParmTypeIsVectorIntBit = 0x8000'0000;
static constexpr uint32_t ParmTypeIsVectorFloatBit = 0xC000'0000;
+
+ static constexpr uint8_t WidthOfParamType = 2;
};
// Extended Traceback table flags.
diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index c0cb095be3ef2..ca3dd992bbd50 100644
--- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -857,9 +857,9 @@ class MachineRegisterInfo {
/// Return true if the specified register is modified or read in this
/// function. This checks that no machine operands exist for the register or
- /// any of its aliases. The register is also considered used when it is set
- /// in the UsedPhysRegMask.
- bool isPhysRegUsed(MCRegister PhysReg) const;
+ /// any of its aliases. If SkipRegMaskTest is false, the register is
+ /// considered used when it is set in the UsedPhysRegMask.
+ bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest = false) const;
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
/// This corresponds to the bit mask attached to register mask operands.
diff --git a/llvm/include/llvm/Object/XCOFFObjectFile.h b/llvm/include/llvm/Object/XCOFFObjectFile.h
index 12d550f69d597..fce555bffd9b0 100644
--- a/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -538,20 +538,19 @@ class XCOFFSymbolRef {
};
class TBVectorExt {
- friend class XCOFFTracebackTable;
-
uint16_t Data;
- uint32_t VecParmsInfo;
+ SmallString<32> VecParmsInfo;
- TBVectorExt(StringRef TBvectorStrRef);
+ TBVectorExt(StringRef TBvectorStrRef, Error &Err);
public:
+ static Expected<TBVectorExt> create(StringRef TBvectorStrRef);
uint8_t getNumberOfVRSaved() const;
bool isVRSavedOnStack() const;
bool hasVarArgs() const;
uint8_t getNumberOfVectorParms() const;
bool hasVMXInstruction() const;
- SmallString<32> getVectorParmsInfoString() const;
+ SmallString<32> getVectorParmsInfo() const { return VecParmsInfo; };
};
/// This class provides methods to extract traceback table data from a buffer.
diff --git a/llvm/lib/BinaryFormat/XCOFF.cpp b/llvm/lib/BinaryFormat/XCOFF.cpp
index 0f270a5cea1b9..fd5d8568b62ff 100644
--- a/llvm/lib/BinaryFormat/XCOFF.cpp
+++ b/llvm/lib/BinaryFormat/XCOFF.cpp
@@ -9,6 +9,8 @@
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
using namespace llvm;
@@ -76,6 +78,7 @@ StringRef XCOFF::getRelocationTypeString(XCOFF::RelocationType Type) {
}
return "Unknown";
}
+#undef RELOC_CASE
#define LANG_CASE(A) \
case XCOFF::TracebackTable::A: \
@@ -104,15 +107,25 @@ StringRef XCOFF::getNameForTracebackTableLanguageId(
}
#undef LANG_CASE
-SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
+Expected<SmallString<32>> XCOFF::parseParmsType(uint32_t Value,
+ unsigned FixedParmsNum,
+ unsigned FloatingParmsNum) {
SmallString<32> ParmsType;
- for (unsigned I = 0; I < ParmsNum; ++I) {
- if (I != 0)
+ int Bits = 0;
+ unsigned ParsedFixedNum = 0;
+ unsigned ParsedFloatingNum = 0;
+ unsigned ParsedNum = 0;
+ unsigned ParmsNum = FixedParmsNum + FloatingParmsNum;
+
+ while (Bits < 32 && ParsedNum < ParmsNum) {
+ if (++ParsedNum > 1)
ParmsType += ", ";
if ((Value & TracebackTable::ParmTypeIsFloatingBit) == 0) {
// Fixed parameter type.
ParmsType += "i";
+ ++ParsedFixedNum;
Value <<= 1;
+ ++Bits;
} else {
if ((Value & TracebackTable::ParmTypeFloatingIsDoubleBit) == 0)
// Float parameter type.
@@ -120,11 +133,21 @@ SmallString<32> XCOFF::parseParmsType(uint32_t Value, unsigned ParmsNum) {
else
// Double parameter type.
ParmsType += "d";
-
+ ++ParsedFloatingNum;
Value <<= 2;
+ Bits += 2;
}
}
- assert(Value == 0u && "ParmsType encodes more than ParmsNum parameters.");
+
+ // We have more parameters than the 32 Bits could encode.
+ if (ParsedNum < ParmsNum)
+ ParmsType += ", ...";
+
+ if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
+ ParsedFloatingNum > FloatingParmsNum)
+ return createStringError(errc::invalid_argument,
+ "ParmsType encodes can not map to ParmsNum "
+ "parameters in parseParmsType.");
return ParmsType;
}
@@ -153,4 +176,94 @@ SmallString<32> XCOFF::getExtendedTBTableFlagString(uint8_t Flag) {
return Res;
}
-#undef RELOC_CASE
+Expected<SmallString<32>>
+XCOFF::parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum,
+ unsigned FloatingParmsNum,
+ unsigned VectorParmsNum) {
+ SmallString<32> ParmsType;
+
+ unsigned ParsedFixedNum = 0;
+ unsigned ParsedFloatingNum = 0;
+ unsigned ParsedVectorNum = 0;
+ unsigned ParsedNum = 0;
+ unsigned ParmsNum = FixedParmsNum + FloatingParmsNum + VectorParmsNum;
+
+ for (int Bits = 0; Bits < 32 && ParsedNum < ParmsNum; Bits += 2) {
+ if (++ParsedNum > 1)
+ ParmsType += ", ";
+
+ switch (Value & TracebackTable::ParmTypeMask) {
+ case TracebackTable::ParmTypeIsFixedBits:
+ ParmsType += "i";
+ ++ParsedFixedNum;
+ break;
+ case TracebackTable::ParmTypeIsVectorBits:
+ ParmsType += "v";
+ ++ParsedVectorNum;
+ break;
+ case TracebackTable::ParmTypeIsFloatingBits:
+ ParmsType += "f";
+ ++ParsedFloatingNum;
+ break;
+ case TracebackTable::ParmTypeIsDoubleBits:
+ ParmsType += "d";
+ ++ParsedFloatingNum;
+ break;
+ default:
+ assert(false && "Unrecognized bits in ParmsType.");
+ }
+ Value <<= 2;
+ }
+
+ // We have more parameters than the 32 Bits could encode.
+ if (ParsedNum < ParmsNum)
+ ParmsType += ", ...";
+
+ if (Value != 0u || ParsedFixedNum > FixedParmsNum ||
+ ParsedFloatingNum > FloatingParmsNum || ParsedVectorNum > VectorParmsNum)
+ return createStringError(
+ errc::invalid_argument,
+ "ParmsType encodes can not map to ParmsNum parameters "
+ "in parseParmsTypeWithVecInfo.");
+
+ return ParmsType;
+}
+
+Expected<SmallString<32>> XCOFF::parseVectorParmsType(uint32_t Value,
+ unsigned ParmsNum) {
+ SmallString<32> ParmsType;
+ unsigned ParsedNum = 0;
+ for (int Bits = 0; ParsedNum < ParmsNum && Bits < 32; Bits += 2) {
+ if (++ParsedNum > 1)
+ ParmsType += ", ";
+ switch (Value & TracebackTable::ParmTypeMask) {
+ case TracebackTable::ParmTypeIsVectorCharBit:
+ ParmsType += "vc";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorShortBit:
+ ParmsType += "vs";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorIntBit:
+ ParmsType += "vi";
+ break;
+
+ case TracebackTable::ParmTypeIsVectorFloatBit:
+ ParmsType += "vf";
+ break;
+ }
+
+ Value <<= 2;
+ }
+
+ // We have more parameters than the 32 Bits could encode.
+ if (ParsedNum < ParmsNum)
+ ParmsType += ", ...";
+
+ if (Value != 0u)
+ return createStringError(errc::invalid_argument,
+ "ParmsType encodes more than ParmsNum parameters "
+ "in parseVectorParmsType.");
+ return ParmsType;
+}
diff --git a/llvm/lib/CodeGen/MachineRegisterInfo.cpp b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
index 58bb86688d31c..3f6b11e072b48 100644
--- a/llvm/lib/CodeGen/MachineRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/MachineRegisterInfo.cpp
@@ -582,8 +582,9 @@ bool MachineRegisterInfo::isPhysRegModified(MCRegister PhysReg,
return false;
}
-bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg) const {
- if (UsedPhysRegMask.test(PhysReg))
+bool MachineRegisterInfo::isPhysRegUsed(MCRegister PhysReg,
+ bool SkipRegMaskTest) const {
+ if (!SkipRegMaskTest && UsedPhysRegMask.test(PhysReg))
return true;
const TargetRegisterInfo *TRI = getTargetRegisterInfo();
for (MCRegAliasIterator AliasReg(PhysReg, TRI, true); AliasReg.isValid();
diff --git a/llvm/lib/Object/XCOFFObjectFile.cpp b/llvm/lib/Object/XCOFFObjectFile.cpp
index 8c2a0ead45c82..a03627f2097e9 100644
--- a/llvm/lib/Object/XCOFFObjectFile.cpp
+++ b/llvm/lib/Object/XCOFFObjectFile.cpp
@@ -900,15 +900,34 @@ bool doesXCOFFTracebackTableBegin(ArrayRef<uint8_t> Bytes) {
return support::endian::read32be(Bytes.data()) == 0;
}
-TBVectorExt::TBVectorExt(StringRef TBvectorStrRef) {
+#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
+#define GETVALUEWITHMASKSHIFT(X, S) \
+ ((Data & (TracebackTable::X)) >> (TracebackTable::S))
+
+Expected<TBVectorExt> TBVectorExt::create(StringRef TBvectorStrRef) {
+ Error Err = Error::success();
+ TBVectorExt TBTVecExt(TBvectorStrRef, Err);
+ if (Err)
+ return std::move(Err);
+ return TBTVecExt;
+}
+
+TBVectorExt::TBVectorExt(StringRef TBvectorStrRef, Error &Err) {
const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(TBvectorStrRef.data());
Data = support::endian::read16be(Ptr);
- VecParmsInfo = support::endian::read32be(Ptr + 2);
+ uint32_t VecParmsTypeValue = support::endian::read32be(Ptr + 2);
+ unsigned ParmsNum =
+ GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask, NumberOfVectorParmsShift);
+
+ ErrorAsOutParameter EAO(&Err);
+ Expected<SmallString<32>> VecParmsTypeOrError =
+ parseVectorParmsType(VecParmsTypeValue, ParmsNum);
+ if (!VecParmsTypeOrError)
+ Err = VecParmsTypeOrError.takeError();
+ else
+ VecParmsInfo = VecParmsTypeOrError.get();
}
-#define GETVALUEWITHMASK(X) (Data & (TracebackTable::X))
-#define GETVALUEWITHMASKSHIFT(X, S) \
- ((Data & (TracebackTable::X)) >> (TracebackTable::S))
uint8_t TBVectorExt::getNumberOfVRSaved() const {
return GETVALUEWITHMASKSHIFT(NumberOfVRSavedMask, NumberOfVRSavedShift);
}
@@ -920,6 +939,7 @@ bool TBVectorExt::isVRSavedOnStack() const {
bool TBVectorExt::hasVarArgs() const {
return GETVALUEWITHMASK(HasVarArgsMask);
}
+
uint8_t TBVectorExt::getNumberOfVectorParms() const {
return GETVALUEWITHMASKSHIFT(NumberOfVectorParmsMask,
NumberOfVectorParmsShift);
@@ -931,72 +951,6 @@ bool TBVectorExt::hasVMXInstruction() const {
#undef GETVALUEWITHMASK
#undef GETVALUEWITHMASKSHIFT
-SmallString<32> TBVectorExt::getVectorParmsInfoString() const {
- SmallString<32> ParmsType;
- uint32_t Value = VecParmsInfo;
- for (uint8_t I = 0; I < getNumberOfVectorParms(); ++I) {
- if (I != 0)
- ParmsType += ", ";
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsVectorCharBit:
- ParmsType += "vc";
- break;
-
- case TracebackTable::ParmTypeIsVectorShortBit:
- ParmsType += "vs";
- break;
-
- case TracebackTable::ParmTypeIsVectorIntBit:
- ParmsType += "vi";
- break;
-
- case TracebackTable::ParmTypeIsVectorFloatBit:
- ParmsType += "vf";
- break;
- }
- Value <<= 2;
- }
- return ParmsType;
-}
-
-static SmallString<32> parseParmsTypeWithVecInfo(uint32_t Value,
- unsigned int ParmsNum) {
- SmallString<32> ParmsType;
- unsigned I = 0;
- bool Begin = false;
- while (I < ParmsNum || Value) {
- if (Begin)
- ParmsType += ", ";
- else
- Begin = true;
-
- switch (Value & TracebackTable::ParmTypeMask) {
- case TracebackTable::ParmTypeIsFixedBits:
- ParmsType += "i";
- ++I;
- break;
- case TracebackTable::ParmTypeIsVectorBits:
- ParmsType += "v";
- break;
- case TracebackTable::ParmTypeIsFloatingBits:
- ParmsType += "f";
- ++I;
- break;
- case TracebackTable::ParmTypeIsDoubleBits:
- ParmsType += "d";
- ++I;
- break;
- default:
- assert(false && "Unrecognized bits in ParmsType.");
- }
- Value <<= 2;
- }
- assert(I == ParmsNum &&
- "The total parameters number of fixed-point or floating-point "
- "parameters not equal to the number in the parameter type!");
- return ParmsType;
-}
-
Expected<XCOFFTracebackTable> XCOFFTracebackTable::create(const uint8_t *Ptr,
uint64_t &Size) {
Error Err = Error::success();
@@ -1017,21 +971,13 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
// Skip 8 bytes of mandatory fields.
DE.getU64(Cur);
+ unsigned FixedParmsNum = getNumberOfFixedParms();
+ unsigned FloatingParmsNum = getNumberOfFPParms();
+ uint32_t ParamsTypeValue = 0;
+
// Begin to parse optional fields.
- if (Cur) {
- unsigned ParmNum = getNumberOfFixedParms() + getNumberOfFPParms();
-
- // As long as there are no "fixed-point" or floating-point parameters, this
- // field remains not present even when hasVectorInfo gives true and
- // indicates the presence of vector parameters.
- if (ParmNum > 0) {
- uint32_t ParamsTypeValue = DE.getU32(Cur);
- if (Cur)
- ParmsType = hasVectorInfo()
- ? parseParmsTypeWithVecInfo(ParamsTypeValue, ParmNum)
- : parseParmsType(ParamsTypeValue, ParmNum);
- }
- }
+ if (Cur && (FixedParmsNum + FloatingParmsNum) > 0)
+ ParamsTypeValue = DE.getU32(Cur);
if (Cur && hasTraceBackTableOffset())
TraceBackTableOffset = DE.getU32(Cur);
@@ -1060,10 +1006,35 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (Cur && isAllocaUsed())
AllocaRegister = DE.getU8(Cur);
+ unsigned VectorParmsNum = 0;
if (Cur && hasVectorInfo()) {
StringRef VectorExtRef = DE.getBytes(Cur, 6);
- if (Cur)
- VecExt = TBVectorExt(VectorExtRef);
+ if (Cur) {
+ Expected<TBVectorExt> TBVecExtOrErr = TBVectorExt::create(VectorExtRef);
+ if (!TBVecExtOrErr) {
+ Err = TBVecExtOrErr.takeError();
+ return;
+ }
+ VecExt = TBVecExtOrErr.get();
+ VectorParmsNum = VecExt.getValue().getNumberOfVectorParms();
+ }
+ }
+
+ // As long as there is no fixed-point or floating-point parameter, this
+ // field remains not present even when hasVectorInfo gives true and
+ // indicates the presence of vector parameters.
+ if (Cur && (FixedParmsNum + FloatingParmsNum) > 0) {
+ Expected<SmallString<32>> ParmsTypeOrError =
+ hasVectorInfo()
+ ? parseParmsTypeWithVecInfo(ParamsTypeValue, FixedParmsNum,
+ FloatingParmsNum, VectorParmsNum)
+ : parseParmsType(ParamsTypeValue, FixedParmsNum, FloatingParmsNum);
+
+ if (!ParmsTypeOrError) {
+ Err = ParmsTypeOrError.takeError();
+ return;
+ }
+ ParmsType = ParmsTypeOrError.get();
}
if (Cur && hasExtensionTable())
@@ -1071,6 +1042,7 @@ XCOFFTracebackTable::XCOFFTracebackTable(const uint8_t *Ptr, uint64_t &Size,
if (!Cur)
Err = Cur.takeError();
+
Size = Cur.tell();
}
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
index 813faf3e3d37e..fa65f54b4eabf 100644
--- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -61,6 +61,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/TargetRegistry.h"
@@ -1940,7 +1941,7 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
// Check the function uses floating-point processor instructions or not
for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
- if (MRI.isPhysRegUsed(Reg)) {
+ if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
break;
}
@@ -1980,7 +1981,8 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
static_assert(XCOFF::AllocRegNo == 31, "Unexpected register usage!");
- if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
+ if (MRI.isPhysRegUsed(Subtarget->isPPC64() ? PPC::X31 : PPC::R31,
+ /* SkipRegMaskTest */ true))
FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
@@ -2025,6 +2027,20 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
(SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
// Set the 6th byte of mandatory field.
+
+ // Check whether has Vector Instruction,We only treat instructions uses vector
+ // register as vector instructions.
+ bool HasVectorInst = false;
+ for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)
+ if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
+ // Has VMX instruction.
+ HasVectorInst = true;
+ break;
+ }
+
+ if (FI->hasVectorParms() || HasVectorInst)
+ SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;
+
bool ShouldEmitEHBlock = TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF);
if (ShouldEmitEHBlock)
SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
@@ -2053,9 +2069,9 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
(SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
// Set the 7th byte of mandatory field.
- uint32_t NumberOfFixedPara = FI->getFixedParamNum();
+ uint32_t NumberOfFixedParms = FI->getFixedParmsNum();
SecondHalfOfMandatoryField |=
- (NumberOfFixedPara << TracebackTable::NumberOfFixedParmsShift) &
+ (NumberOfFixedParms << TracebackTable::NumberOfFixedParmsShift) &
TracebackTable::NumberOfFixedParmsMask;
GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
NumberOfFixedParms);
@@ -2068,9 +2084,9 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
// Always set parameter on stack.
SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
- uint32_t NumberOfFPPara = FI->getFloatingPointParamNum();
+ uint32_t NumberOfFPParms = FI->getFloatingPointParmsNum();
SecondHalfOfMandatoryField |=
- (NumberOfFPPara << TracebackTable::NumberOfFloatingPointParmsShift) &
+ (NumberOfFPParms << TracebackTable::NumberOfFloatingPointParmsShift) &
TracebackTable::NumberOfFloatingPointParmsMask;
GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
@@ -2083,18 +2099,25 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
// Generate the optional fields of traceback table.
// Parameter type.
- if (NumberOfFixedPara || NumberOfFPPara) {
- assert((SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) ==
- 0 &&
- "VectorInfo has not been implemented.");
- uint32_t ParaType = FI->getParameterType();
- CommentOS << "Parameter type = "
- << XCOFF::parseParmsType(ParaType,
- NumberOfFixedPara + NumberOfFPPara);
- EmitComment();
- OutStreamer->emitIntValueInHexWithPadding(ParaType, sizeof(ParaType));
+ if (NumberOfFixedParms || NumberOfFPParms) {
+ uint32_t ParmsTypeValue = FI->getParmsType();
+
+ Expected<SmallString<32>> ParmsType =
+ FI->hasVectorParms()
+ ? XCOFF::parseParmsTypeWithVecInfo(
+ ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
+ FI->getVectorParmsNum())
+ : XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,
+ NumberOfFPParms);
+
+ assert(ParmsType && toString(ParmsType.takeError()).c_str());
+ if (ParmsType) {
+ CommentOS << "Parameter type = " << ParmsType.get();
+ EmitComment();
+ }
+ OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
+ sizeof(ParmsTypeValue));
}
-
// Traceback table offset.
OutStreamer->AddComment("Function size");
if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
@@ -2126,6 +2149,69 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
}
+ if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
+ uint16_t VRData = 0;
+ // Calculate the number of VRs be saved.
+ // Vector registers 20 through 31 are marked as reserved and cannot be used
+ // in the default ABI.
+ const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
+ if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
+ TM.getAIXExtendedAltivecABI()) {
+ for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
+ if (MRI.isPhysRegModified(Reg)) {
+ // Number of VRs saved.
+ VRData |=
+ ((PPC::V31 - Reg + 1) << TracebackTable::NumberOfVRSavedShift) &
+ TracebackTable::NumberOfVRSavedMask;
+ // This bit is supposed to set only when the special register
+ // VRSAVE is saved on stack.
+ // However, IBM XL compiler sets the bit when any vector registers
+ // are saved on the stack. We will follow XL's behavior on AIX
+ // so that we don't get surprise behavior change for C code.
+ VRData |= TracebackTable::IsVRSavedOnStackMask;
+ break;
+ }
+ }
+
+ // Set has_varargs.
+ if (FI->getVarArgsFrameIndex())
+ VRData |= TracebackTable::HasVarArgsMask;
+
+ // Vector parameters number.
+ unsigned VectorParmsNum = FI->getVectorParmsNum();
+ VRData |= (VectorParmsNum << TracebackTable::NumberOfVectorParmsShift) &
+ TracebackTable::NumberOfVectorParmsMask;
+
+ if (HasVectorInst)
+ VRData |= TracebackTable::HasVMXInstructionMask;
+
+ GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);
+ GENBOOLCOMMENT(", ", VRData, IsVRSavedOnStack);
+ GENBOOLCOMMENT(", ", VRData, HasVarArgs);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
+
+ GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);
+ GENBOOLCOMMENT(", ", VRData, HasVMXInstruction);
+ EmitComment();
+ OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
+
+ uint32_t VecParmTypeValue = FI->getVecExtParmsType();
+
+ Expected<SmallString<32>> VecParmsType =
+ XCOFF::parseVectorParmsType(VecParmTypeValue, VectorParmsNum);
+ assert(VecParmsType && toString(VecParmsType.takeError()).c_str());
+ if (VecParmsType) {
+ CommentOS << "Vector Parameter type = " << VecParmsType.get();
+ EmitComment();
+ }
+ OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
+ sizeof(VecParmTypeValue));
+ // Padding 2 bytes.
+ CommentOS << "Padding";
+ EmitCommentAndValue(0, 2);
+ }
+
uint8_t ExtensionTableFlag = 0;
if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
if (ShouldEmitEHBlock)
@@ -2156,7 +2242,6 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
OutStreamer->AddComment("EHInfo Table");
OutStreamer->emitValue(Exp, DL.getPointerSize());
}
-
#undef GENBOOLCOMMENT
#undef GENVALUECOMMENT
}
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 2dc948c081cb3..4730a6d3d769a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -6954,10 +6954,38 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
if (VA.isRegLoc()) {
if (VA.getValVT().isScalarInteger())
FuncInfo->appendParameterType(PPCFunctionInfo::FixedType);
- else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector())
- FuncInfo->appendParameterType(VA.getValVT().SimpleTy == MVT::f32
- ? PPCFunctionInfo::ShortFloatPoint
- : PPCFunctionInfo::LongFloatPoint);
+ else if (VA.getValVT().isFloatingPoint() && !VA.getValVT().isVector()) {
+ switch (VA.getValVT().SimpleTy) {
+ default:
+ report_fatal_error("Unhandled value type for argument.");
+ case MVT::f32:
+ FuncInfo->appendParameterType(PPCFunctionInfo::ShortFloatingPoint);
+ break;
+ case MVT::f64:
+ FuncInfo->appendParameterType(PPCFunctionInfo::LongFloatingPoint);
+ break;
+ }
+ } else if (VA.getValVT().isVector()) {
+ switch (VA.getValVT().SimpleTy) {
+ default:
+ report_fatal_error("Unhandled value type for argument.");
+ case MVT::v16i8:
+ FuncInfo->appendParameterType(PPCFunctionInfo::VectorChar);
+ break;
+ case MVT::v8i16:
+ FuncInfo->appendParameterType(PPCFunctionInfo::VectorShort);
+ break;
+ case MVT::v4i32:
+ case MVT::v2i64:
+ case MVT::v1i128:
+ FuncInfo->appendParameterType(PPCFunctionInfo::VectorInt);
+ break;
+ case MVT::v4f32:
+ case MVT::v2f64:
+ FuncInfo->appendParameterType(PPCFunctionInfo::VectorFloat);
+ break;
+ }
+ }
}
if (Flags.isByVal() && VA.isMemLoc()) {
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
index c976a9c62d3bf..782d41f93ae53 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.cpp
@@ -66,34 +66,122 @@ bool PPCFunctionInfo::isLiveInZExt(Register VReg) const {
}
void PPCFunctionInfo::appendParameterType(ParamType Type) {
- uint32_t CopyParamType = ParameterType;
- int Bits = 0;
- // If it is fixed type, we only need to increase the FixedParamNum, for
- // the bit encode of fixed type is bit of zero, we do not need to change the
- // ParamType.
- if (Type == FixedType) {
- ++FixedParamNum;
+ ParamtersType.push_back(Type);
+ switch (Type) {
+ case FixedType:
+ ++FixedParmsNum;
+ return;
+ case ShortFloatingPoint:
+ case LongFloatingPoint:
+ ++FloatingParmsNum;
return;
+ case VectorChar:
+ case VectorShort:
+ case VectorInt:
+ case VectorFloat:
+ ++VectorParmsNum;
+ return;
+ }
+ llvm_unreachable("Error ParamType type.");
+}
+
+uint32_t PPCFunctionInfo::getVecExtParmsType() const {
+
+ uint32_t VectExtParamInfo = 0;
+ unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
+ int Bits = 0;
+
+ if (!hasVectorParms())
+ return 0;
+
+ for (const auto &Elt : ParamtersType) {
+ switch (Elt) {
+ case VectorChar:
+ VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ VectExtParamInfo |=
+ XCOFF::TracebackTable::ParmTypeIsVectorCharBit >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
+ case VectorShort:
+ VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ VectExtParamInfo |=
+ XCOFF::TracebackTable::ParmTypeIsVectorShortBit >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
+ case VectorInt:
+ VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ VectExtParamInfo |=
+ XCOFF::TracebackTable::ParmTypeIsVectorIntBit >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
+ case VectorFloat:
+ VectExtParamInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ VectExtParamInfo |=
+ XCOFF::TracebackTable::ParmTypeIsVectorFloatBit >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
+ default:
+ break;
+ }
+
+ // There are only 32bits in the VectExtParamInfo.
+ if (Bits >= 32)
+ break;
}
+ return Bits < 32 ? VectExtParamInfo << (32 - Bits) : VectExtParamInfo;
+}
+
+uint32_t PPCFunctionInfo::getParmsType() const {
+ uint32_t ParamsTypeInfo = 0;
+ unsigned ShiftBits = 32 - XCOFF::TracebackTable::WidthOfParamType;
+
+ int Bits = 0;
+ for (const auto &Elt : ParamtersType) {
- ++FloatingPointParamNum;
+ if (Bits > 31 || (Bits > 30 && (Elt != FixedType || hasVectorParms())))
+ break;
- for (int I = 0;
- I < static_cast<int>(FloatingPointParamNum + FixedParamNum - 1); ++I) {
- if (CopyParamType & XCOFF::TracebackTable::ParmTypeIsFloatingBit) {
+ switch (Elt) {
+ case FixedType:
+ if (hasVectorParms()) {
+ //'00' ==> fixed parameter if HasVectorParms is true.
+ ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ ParamsTypeInfo |=
+ XCOFF::TracebackTable::ParmTypeIsFixedBits >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ } else {
+ //'0' ==> fixed parameter if HasVectorParms is false.
+ ParamsTypeInfo <<= 1;
+ ++Bits;
+ }
+ break;
+ case ShortFloatingPoint:
// '10'b => floating point short parameter.
+ ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ ParamsTypeInfo |=
+ XCOFF::TracebackTable::ParmTypeIsFloatingBits >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
+ case LongFloatingPoint:
// '11'b => floating point long parameter.
- CopyParamType <<= 2;
- Bits += 2;
- } else {
- // '0'b => fixed parameter.
- CopyParamType <<= 1;
- ++Bits;
+ ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ ParamsTypeInfo |=
+ XCOFF::TracebackTable::ParmTypeIsDoubleBits >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
+ case VectorChar:
+ case VectorShort:
+ case VectorInt:
+ case VectorFloat:
+ // '01' ==> vector parameter
+ ParamsTypeInfo <<= XCOFF::TracebackTable::WidthOfParamType;
+ ParamsTypeInfo |=
+ XCOFF::TracebackTable::ParmTypeIsVectorBits >> ShiftBits;
+ Bits += XCOFF::TracebackTable::WidthOfParamType;
+ break;
}
}
- assert(Type != FixedType && "FixedType should already be handled.");
- if (Bits < 31)
- ParameterType |= Type << (30 - Bits);
+ return Bits < 32 ? ParamsTypeInfo << (32 - Bits) : ParamsTypeInfo;
}
diff --git a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
index 6a2de53814d8f..07c503d47e981 100644
--- a/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
+++ b/llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h
@@ -23,12 +23,14 @@ namespace llvm {
/// PowerPC target-specific information for each MachineFunction.
class PPCFunctionInfo : public MachineFunctionInfo {
public:
- // The value in the ParamType are used to indicate the bitstrings used in the
- // encoding format.
enum ParamType {
- FixedType = 0x0,
- ShortFloatPoint = 0x2,
- LongFloatPoint = 0x3
+ FixedType,
+ ShortFloatingPoint,
+ LongFloatingPoint,
+ VectorChar,
+ VectorShort,
+ VectorInt,
+ VectorFloat
};
private:
@@ -120,19 +122,18 @@ class PPCFunctionInfo : public MachineFunctionInfo {
/// register for parameter passing.
unsigned VarArgsNumFPR = 0;
- /// FixedParamNum - Number of fixed parameter.
- unsigned FixedParamNum = 0;
+ /// FixedParmsNum - The number of fixed parameters.
+ unsigned FixedParmsNum = 0;
- /// FloatingParamNum - Number of floating point parameter.
- unsigned FloatingPointParamNum = 0;
+ /// FloatingParmsNum - The number of floating parameters.
+ unsigned FloatingParmsNum = 0;
- /// ParamType - Encode type for every parameter
- /// in the order of parameters passing in.
- /// Bitstring starts from the most significant (leftmost) bit.
- /// '0'b => fixed parameter.
- /// '10'b => floating point short parameter.
- /// '11'b => floating point long parameter.
- uint32_t ParameterType = 0;
+ /// VectorParmsNum - The number of vector parameters.
+ unsigned VectorParmsNum = 0;
+
+ /// ParamtersType - Store all the parameter's type that are saved on
+ /// registers.
+ SmallVector<ParamType, 32> ParamtersType;
/// CRSpillFrameIndex - FrameIndex for CR spill slot for 32-bit SVR4.
int CRSpillFrameIndex = 0;
@@ -224,11 +225,15 @@ class PPCFunctionInfo : public MachineFunctionInfo {
unsigned getVarArgsNumGPR() const { return VarArgsNumGPR; }
void setVarArgsNumGPR(unsigned Num) { VarArgsNumGPR = Num; }
- unsigned getFixedParamNum() const { return FixedParamNum; }
+ unsigned getFixedParmsNum() const { return FixedParmsNum; }
+ unsigned getFloatingPointParmsNum() const { return FloatingParmsNum; }
+ unsigned getVectorParmsNum() const { return VectorParmsNum; }
+ bool hasVectorParms() const { return VectorParmsNum != 0; }
+
+ uint32_t getParmsType() const;
- unsigned getFloatingPointParamNum() const { return FloatingPointParamNum; }
+ uint32_t getVecExtParmsType() const;
- uint32_t getParameterType() const { return ParameterType; }
void appendParameterType(ParamType Type);
unsigned getVarArgsNumFPR() const { return VarArgsNumFPR; }
diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
index d14f647eca0f7..12a4e014bb19a 100644
--- a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll
@@ -1,9 +1,9 @@
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr4 \
-; RUN: -mattr=-altivec -xcoff-traceback-table=true < %s | \
+; RUN: -mattr=+altivec -vec-extabi -xcoff-traceback-table=true < %s | \
; RUN: FileCheck --check-prefixes=CHECK-ASM,COMMON %s
; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
-; RUN: -mcpu=pwr4 -mattr=-altivec < %s | \
+; RUN: -mcpu=pwr4 -mattr=+altivec -vec-extabi < %s | \
; RUN: FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
define float @bar() #0 {
@@ -26,6 +26,16 @@ entry:
ret float %add
}
+define <4 x i32> @foov() #0 {
+entry:
+ %taken = alloca <4 x i32>, align 16
+ %data = alloca <4 x i32>, align 16
+ store <4 x i32> <i32 123, i32 0, i32 0, i32 0>, <4 x i32>* %data, align 16
+ call void asm sideeffect "", "~{v31},~{v30},~{v29},~{v28}"()
+ %0 = load <4 x i32>, <4 x i32>* %taken, align 16
+ ret <4 x i32> %0
+}
+
; COMMON: .vbyte 4, 0x00000000 # Traceback table begin
; COMMON-NEXT: .byte 0x00 # Version = 0
; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
@@ -46,3 +56,28 @@ entry:
; COMMON-NEXT: .byte "bar" # Function Name
; COMMON-NEXT: .byte 0x1f # AllocaUsed
; COMMON-NEXT: # -- End function
+
+; COMMON: L..foov0:
+; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
+; COMMON-NEXT: .byte 0x00 # Version = 0
+; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
+; COMMON-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
+; COMMON-NEXT: # -HasControlledStorage, -IsTOCless
+; COMMON-NEXT: # -IsFloatingPointPresent
+; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
+; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+; COMMON-NEXT: .byte 0x00 # NumberOfFixedParms = 0
+; COMMON-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
+; CHECK-ASM-NEXT: .vbyte 4, L..foov0-.foov # Function size
+; CHECK-FUNC-NEXT: .vbyte 4, L..foov0-.foov[PR] # Function size
+; COMMON-NEXT: .vbyte 2, 0x0004 # Function name len = 4
+; COMMON-NEXT: .byte "foov" # Function Name
+; COMMON-NEXT: .byte 0x12 # NumOfVRsSaved = 4, +IsVRSavedOnStack, -HasVarArgs
+; COMMON-NEXT: .byte 0x01 # NumOfVectorParams = 0, +HasVMXInstruction
+; COMMON-NEXT: .vbyte 4, 0x00000000 # Vector Parameter type =
+; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
+; COMMON-NEXT: # -- End function
diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
new file mode 100644
index 0000000000000..ab1dd8e3b9ade
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo.ll
@@ -0,0 +1,129 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr7 \
+; RUN: -mattr=+altivec -vec-extabi -xcoff-traceback-table=true < %s | \
+; RUN: FileCheck --check-prefixes=CHECK-ASM,COMMON %s
+
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -function-sections \
+; RUN: -mcpu=pwr7 -mattr=+altivec -vec-extabi < %s | \
+; RUN: FileCheck --check-prefixes=CHECK-FUNC,COMMON %s
+
+;; #include <altivec.h>
+;; vector float f(vector int vi1, int i1, int i2, float f1, vector float vf,double d1, vector char vc1) {
+;; return vec_abs(vf);
+;; }
+;; vector float fin(int x) {
+;; vector float vf ={1.0,1.0,1.0,1.0};
+;; if (x) return vf;
+;; return vec_abs(vf);
+;; }
+
+define dso_local <4 x float> @f(<4 x i32> %vi1, i32 signext %i1, i32 signext %i2, float %f1, <4 x float> %vf, double %d1, <16 x i8> %vc1) #0 {
+entry:
+ %__a.addr.i = alloca <4 x float>, align 16
+ %vi1.addr = alloca <4 x i32>, align 16
+ %i1.addr = alloca i32, align 4
+ %i2.addr = alloca i32, align 4
+ %f1.addr = alloca float, align 4
+ %vf.addr = alloca <4 x float>, align 16
+ %d1.addr = alloca double, align 8
+ %vc1.addr = alloca <16 x i8>, align 16
+ store <4 x i32> %vi1, <4 x i32>* %vi1.addr, align 16
+ store i32 %i1, i32* %i1.addr, align 4
+ store i32 %i2, i32* %i2.addr, align 4
+ store float %f1, float* %f1.addr, align 4
+ store <4 x float> %vf, <4 x float>* %vf.addr, align 16
+ store double %d1, double* %d1.addr, align 8
+ store <16 x i8> %vc1, <16 x i8>* %vc1.addr, align 16
+ %0 = load <4 x float>, <4 x float>* %vf.addr, align 16
+ store <4 x float> %0, <4 x float>* %__a.addr.i, align 16
+ %1 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
+ %2 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
+ %3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %2) #2
+ ret <4 x float> %3
+}
+
+define <4 x float> @fin(i32 %x) #0 {
+entry:
+ %__a.addr.i = alloca <4 x float>, align 16
+ %__res.i = alloca <4 x i32>, align 16
+ %retval = alloca <4 x float>, align 16
+ %x.addr = alloca i32, align 4
+ %vf = alloca <4 x float>, align 16
+ store i32 %x, i32* %x.addr, align 4
+ store <4 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>, <4 x float>* %vf, align 16
+ %0 = load i32, i32* %x.addr, align 4
+ %tobool = icmp ne i32 %0, 0
+ br i1 %tobool, label %if.then, label %if.end
+
+if.then: ; preds = %entry
+ %1 = load <4 x float>, <4 x float>* %vf, align 16
+ store <4 x float> %1, <4 x float>* %retval, align 16
+ br label %return
+
+if.end: ; preds = %entry
+ %2 = load <4 x float>, <4 x float>* %vf, align 16
+ store <4 x float> %2, <4 x float>* %__a.addr.i, align 16
+ %3 = load <4 x float>, <4 x float>* %__a.addr.i, align 16
+ %4 = bitcast <4 x float> %3 to <4 x i32>
+ %and.i = and <4 x i32> %4, <i32 2147483647, i32 2147483647, i32 2147483647, i32 2147483647>
+ store <4 x i32> %and.i, <4 x i32>* %__res.i, align 16
+ %5 = load <4 x i32>, <4 x i32>* %__res.i, align 16
+ %6 = bitcast <4 x i32> %5 to <4 x float>
+ store <4 x float> %6, <4 x float>* %retval, align 16
+ br label %return
+
+return: ; preds = %if.end, %if.then
+ %7 = load <4 x float>, <4 x float>* %retval, align 16
+ ret <4 x float> %7
+}
+
+declare <4 x float> @llvm.fabs.v4f32(<4 x float>) #1
+
+; COMMON: L..f0:
+; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
+; COMMON-NEXT: .byte 0x00 # Version = 0
+; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
+; COMMON-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
+; COMMON-NEXT: # -HasControlledStorage, -IsTOCless
+; COMMON-NEXT: # +IsFloatingPointPresent
+; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
+; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+; COMMON-NEXT: .byte 0x02 # NumberOfFixedParms = 2
+; COMMON-NEXT: .byte 0x05 # NumberOfFPParms = 2, +HasParmsOnStack
+; COMMON-NEXT: .vbyte 4, 0x42740000 # Parameter type = v, i, i, f, v, d, v
+; CHECK-ASM-NEXT: .vbyte 4, L..f0-.f # Function size
+; CHECK-FUNC-NEXT: .vbyte 4, L..f0-.f[PR] # Function size
+; COMMON-NEXT: .vbyte 2, 0x0001 # Function name len = 1
+; COMMON-NEXT: .byte 102 # Function Name
+; COMMON-NEXT: .byte 0x00 # NumOfVRsSaved = 0, -IsVRSavedOnStack, -HasVarArgs
+; COMMON-NEXT: .byte 0x07 # NumOfVectorParams = 3, +HasVMXInstruction
+; COMMON-NEXT: .vbyte 4, 0xb0000000 # Vector Parameter type = vi, vf, vc
+; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
+
+; COMMON: L..fin0:
+; COMMON-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
+; COMMON-NEXT: .byte 0x00 # Version = 0
+; COMMON-NEXT: .byte 0x09 # Language = CPlusPlus
+; COMMON-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; COMMON-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
+; COMMON-NEXT: # -HasControlledStorage, -IsTOCless
+; COMMON-NEXT: # +IsFloatingPointPresent
+; COMMON-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
+; COMMON-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+; COMMON-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+; COMMON-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+; COMMON-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+; COMMON-NEXT: .byte 0x01 # NumberOfFixedParms = 1
+; COMMON-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
+; COMMON-NEXT: .vbyte 4, 0x00000000 # Parameter type = i
+; CHECK-ASM-NEXT: .vbyte 4, L..fin0-.fin # Function size
+; CHECK-FUNC-NEXT: .vbyte 4, L..fin0-.fin[PR] # Function size
+; COMMON-NEXT: .vbyte 2, 0x0003 # Function name len = 3
+; COMMON-NEXT: .byte "fin" # Function Name
+; COMMON-NEXT: .byte 0x00 # NumOfVRsSaved = 0, -IsVRSavedOnStack, -HasVarArgs
+; COMMON-NEXT: .byte 0x01 # NumOfVectorParams = 0, +HasVMXInstruction
+; COMMON-NEXT: .vbyte 4, 0x00000000 # Vector Parameter type =
+; COMMON-NEXT: .vbyte 2, 0x0000 # Padding
diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll
new file mode 100644
index 0000000000000..9a8a4f5f80d2e
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-vectorinfo_hasvarg.ll
@@ -0,0 +1,36 @@
+; RUN: llc -verify-machineinstrs -mtriple powerpc-ibm-aix-xcoff -mcpu=pwr7 \
+; RUN: -mattr=+altivec -vec-extabi -xcoff-traceback-table=true 2>&1 < %s | \
+; RUN: FileCheck --check-prefixes=CHECK-ASM %s
+
+;; void f(vector float vf, ...) {
+;;}
+
+define void @f(<4 x float> %vf, ...) #0 {
+entry:
+ %vf.addr = alloca <4 x float>, align 16
+ store <4 x float> %vf, <4 x float>* %vf.addr, align 16
+ ret void
+}
+
+;CHECK-ASM: .vbyte 4, 0x00000000 # Traceback table begin
+;CHECK-ASM-NEXT: .byte 0x00 # Version = 0
+;CHECK-ASM-NEXT: .byte 0x09 # Language = CPlusPlus
+;CHECK-ASM-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+;CHECK-ASM-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
+;CHECK-ASM-NEXT: # -HasControlledStorage, -IsTOCless
+;CHECK-ASM-NEXT: # -IsFloatingPointPresent
+;CHECK-ASM-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
+;CHECK-ASM-NEXT: .byte 0x40 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
+;CHECK-ASM-NEXT: # OnConditionDirective = 0, -IsCRSaved, -IsLRSaved
+;CHECK-ASM-NEXT: .byte 0x80 # +IsBackChainStored, -IsFixup, NumOfFPRsSaved = 0
+;CHECK-ASM-NEXT: .byte 0x80 # +HasVectorInfo, -HasExtensionTable, NumOfGPRsSaved = 0
+;CHECK-ASM-NEXT: .byte 0x00 # NumberOfFixedParms = 0
+;CHECK-ASM-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack
+;CHECK-ASM-NEXT: .vbyte 4, L..f0-.f # Function size
+;CHECK-ASM-NEXT: .vbyte 2, 0x0001 # Function name len = 1
+;CHECK-ASM-NEXT: .byte 102 # Function Name
+;CHECK-ASM-NEXT: .byte 0x01 # NumOfVRsSaved = 0, -IsVRSavedOnStack, +HasVarArgs
+;CHECK-ASM-NEXT: .byte 0x03 # NumOfVectorParams = 1, +HasVMXInstruction
+;CHECK-ASM-NEXT: .vbyte 4, 0xc0000000 # Vector Parameter type = vf
+;CHECK-ASM-NEXT: .vbyte 2, 0x0000 # Padding
+;CHECK-ASM-NEXT: # -- End function
diff --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll
index f36c40fcad69e..9a6b5e711f682 100644
--- a/llvm/test/CodeGen/PowerPC/aix-exception.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll
@@ -103,10 +103,10 @@ eh.resume: ; preds = %catch.dispatch
; ASM: .vbyte 4, 0x00000000 # Traceback table begin
; ASM: .byte 0x00 # Version = 0
; ASM: .byte 0x09 # Language = CPlusPlus
-; ASM: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; ASM: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
; ASM: # +HasTraceBackTableOffset, -IsInternalProcedure
; ASM: # -HasControlledStorage, -IsTOCless
-; ASM: # +IsFloatingPointPresent
+; ASM: # -IsFloatingPointPresent
; ASM: # -IsFloatingPointOperationLogOrAbortEnabled
; ASM: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; ASM: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
diff --git a/llvm/test/DebugInfo/XCOFF/explicit-section.ll b/llvm/test/DebugInfo/XCOFF/explicit-section.ll
index 321861cee1ff6..86dbb56d53a71 100644
--- a/llvm/test/DebugInfo/XCOFF/explicit-section.ll
+++ b/llvm/test/DebugInfo/XCOFF/explicit-section.ll
@@ -112,10 +112,10 @@ entry:
; CHECK-NEXT: .vbyte 4, 0x00000000 # Traceback table begin
; CHECK-NEXT: .byte 0x00 # Version = 0
; CHECK-NEXT: .byte 0x09 # Language = CPlusPlus
-; CHECK-NEXT: .byte 0x22 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
+; CHECK-NEXT: .byte 0x20 # -IsGlobaLinkage, -IsOutOfLineEpilogOrPrologue
; CHECK-NEXT: # +HasTraceBackTableOffset, -IsInternalProcedure
; CHECK-NEXT: # -HasControlledStorage, -IsTOCless
-; CHECK-NEXT: # +IsFloatingPointPresent
+; CHECK-NEXT: # -IsFloatingPointPresent
; CHECK-NEXT: # -IsFloatingPointOperationLogOrAbortEnabled
; CHECK-NEXT: .byte 0x41 # -IsInterruptHandler, +IsFunctionNamePresent, -IsAllocaUsed
; CHECK-NEXT: # OnConditionDirective = 0, -IsCRSaved, +IsLRSaved
diff --git a/llvm/unittests/Object/XCOFFObjectFileTest.cpp b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
index 71b902c93e3dd..fc7e48100aa68 100644
--- a/llvm/unittests/Object/XCOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/XCOFFObjectFileTest.cpp
@@ -141,6 +141,20 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIParmsType) {
XCOFFTracebackTable TT3 = *TTOrErr3;
ASSERT_TRUE(TT3.getParmsType());
EXPECT_EQ(TT3.getParmsType().getValue(), "d, i, f, f");
+
+ V[6] = 0x04;
+ V[7] = 0x1E;
+ V[8] = 0xAC;
+ V[9] = 0xAA;
+ V[10] = 0xAA;
+ V[11] = 0xAA;
+ Size = sizeof(V);
+ Expected<XCOFFTracebackTable> TTOrErr4 = XCOFFTracebackTable::create(V, Size);
+ ASSERT_THAT_EXPECTED(TTOrErr4, Succeeded());
+ XCOFFTracebackTable TT4 = *TTOrErr4;
+ ASSERT_TRUE(TT4.getParmsType());
+ EXPECT_EQ(TT4.getParmsType().getValue(),
+ "f, f, d, i, i, f, f, f, f, f, f, f, f, f, f, f, f, ...");
}
const uint8_t TBTableData[] = {
@@ -205,7 +219,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 2u);
EXPECT_TRUE(VecExt.hasVMXInstruction());
- EXPECT_EQ(VecExt.getVectorParmsInfoString(), "vf, vf");
+ EXPECT_EQ(VecExt.getVectorParmsInfo(), "vf, vf");
ASSERT_TRUE(TT.getExtensionTable());
EXPECT_EQ(TT.getExtensionTable().getValue(),
@@ -216,7 +230,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo) {
TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
const uint8_t TBTableData[] = {
- 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc5, 0x00, 0x00,
0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
@@ -227,7 +241,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
XCOFFTracebackTable TT = *TTOrErr;
ASSERT_TRUE(TT.getParmsType());
- EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i");
+ EXPECT_EQ(TT.getParmsType().getValue(), "v, i, f, i, d, i, v, v");
ASSERT_TRUE(TT.getVectorExt());
TBVectorExt VecExt = TT.getVectorExt().getValue();
@@ -239,7 +253,7 @@ TEST(XCOFFObjectFileTest, XCOFFTracebackTableAPIHasVectorInfo1) {
EXPECT_EQ(VecExt.getNumberOfVectorParms(), 3u);
EXPECT_TRUE(VecExt.hasVMXInstruction());
- EXPECT_EQ(VecExt.getVectorParmsInfoString(), "vi, vs, vc");
+ EXPECT_EQ(VecExt.getVectorParmsInfo(), "vi, vs, vc");
ASSERT_TRUE(TT.getExtensionTable());
EXPECT_EQ(TT.getExtensionTable().getValue(),
@@ -496,3 +510,49 @@ TEST(XCOFFObjectFileTest, XCOFFGetCsectAuxRef64) {
ExpectErr.takeError(),
FailedWithMessage("csect symbol \".data\" contains no auxiliary entry"));
}
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterType) {
+ const uint8_t TBTableData[] = {0x00, 0x00, 0x22, 0x40, 0x80, 0x00, 0x01,
+ 0x05, 0x58, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x00, 0x07, 0x61, 0x64, 0x64,
+ 0x5f, 0x61, 0x6c, 0x6c, 0x00, 0x00, 0x00};
+ uint64_t Size = 28;
+ Expected<XCOFFTracebackTable> TTOrErr =
+ XCOFFTracebackTable::create(TBTableData, Size);
+
+ EXPECT_THAT_ERROR(
+ TTOrErr.takeError(),
+ FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
+ "in parseParmsType."));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtParameterTypeWithVecInfo) {
+ const uint8_t TBTableData[] = {
+ 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
+ 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
+ 0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00};
+ uint64_t Size = 44;
+ Expected<XCOFFTracebackTable> TTOrErr =
+ XCOFFTracebackTable::create(TBTableData, Size);
+
+ EXPECT_THAT_ERROR(
+ TTOrErr.takeError(),
+ FailedWithMessage("ParmsType encodes can not map to ParmsNum parameters "
+ "in parseParmsTypeWithVecInfo."));
+}
+
+TEST(XCOFFObjectFileTest, XCOFFTracebackTableErrorAtVecParameterType) {
+ const uint8_t TBTableData[] = {
+ 0x00, 0x00, 0x2A, 0x40, 0x80, 0xc0, 0x03, 0x05, 0x48, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x05, 0x05, 0x00, 0x00,
+ 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x61, 0x64, 0x64, 0x5f, 0x61, 0x6c,
+ 0x6c, 0x11, 0x07, 0x90, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00};
+ uint64_t Size = 44;
+ Expected<XCOFFTracebackTable> TTOrErr =
+ XCOFFTracebackTable::create(TBTableData, Size);
+
+ EXPECT_THAT_ERROR(TTOrErr.takeError(),
+ FailedWithMessage("ParmsType encodes more than ParmsNum "
+ "parameters in parseVectorParmsType."));
+}
More information about the llvm-commits
mailing list