bolt/deps/llvm-18.1.8/llvm/unittests/Target/VE/MachineInstrTest.cpp
2025-02-14 19:21:04 +01:00

315 lines
7 KiB
C++

//===- MachineInstrTest.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "VEInstrInfo.h"
#include "VESubtarget.h"
#include "VETargetMachine.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "gtest/gtest.h"
using namespace llvm;
TEST(VETest, VLIndex) {
using namespace VE;
// Return expected VL register index in each MI's operands. Aurora VE has
// multiple instruction formats for each instruction. So, we define
// instructions hierarchically and tests parts of the whole instructions.
// This function returns -1 to N as expected index, or -2 as default.
// We skip a test on an instruction that this function returns -2.
auto VLIndex = [](unsigned Opcode) {
switch (Opcode) {
default:
break;
case VLDNCrz:
return -1;
case VLDUNCrzl:
case VLDLSXrzl_v:
case VLDLZXNCirL:
case VLD2DNCrrL_v:
case VLDU2DNCrzL_v:
case VLDL2DSXizL_v:
case VLDL2DZXNCirl:
return 3;
case VSTOTrrv:
return -1;
case VSTUNCrzvl:
case VSTLNCOTizvL:
case VST2Dirvl:
return 3;
case VSTU2DNCrzvml:
case VSTL2DNCOTrzvml:
return 4;
case VGTNCsrzm_v:
return -1;
case VGTUNCvrzl:
case VGTLSXvrzl_v:
case VGTLZXNCsirL:
return 4;
case VGTNCsrrmL_v:
case VGTUNCvrzmL:
case VGTLSXsizml_v:
return 5;
case VSCNCsrzvm:
return -1;
case VSCUNCvrzvl:
case VSCLNCsirvL:
return 4;
case VSCOTsrrvmL:
case VSCUNCOTvrzvmL:
case VSCLsizvml:
return 5;
case PFCHVrr:
return -1;
case PFCHVrrl:
case PFCHVNCrzL:
return 2;
case VBRDrm:
return -1;
case VBRDrl:
return 2;
case VBRDimL_v:
return 3;
case VMVrvm_v:
return -1;
case VMVivl:
return 3;
case VMVrvmL_v:
return 4;
case VADDULvv_v:
case PVADDULOrvm:
return -1;
case VADDUWvvl_v:
case PVADDUUPrvL:
return 3;
case PVADDUvvmL_v:
case VADDSWSXivml:
case VADDSLivml:
return 4;
case VDIVULvv_v:
case VDIVSWSXrvm:
return -1;
case VDIVUWvrl_v:
case VDIVSWZXviL:
return 3;
case VDIVSLivmL_v:
case VDIVSWSXivml:
return 4;
// We test casually if instructions are defined using a multiclass already
// tested.
case VSUBSLivml:
case VMULSLivml:
case VCMPSLivml:
case VMAXSLivml:
return 4;
case VANDvv_v:
case PVANDLOrvm:
return -1;
case PVANDvvl_v:
case PVANDUPrvL:
return 3;
case VORvvmL_v:
case PVORLOmvml:
case VXORmvml:
case VEQVmvml:
return 4;
case VLDZv:
return -1;
case VPCNTvL:
return 2;
case VBRVvml:
return 3;
case VSEQ:
return -1;
case VSEQL:
return 1;
case VSEQml:
return 2;
case VSLLvv_v:
case PVSLLLOvrm:
return -1;
case PVSLLvvl_v:
case PVSRLUPvrL:
return 3;
case VSLLvimL_v:
case PVSRLLOvrml:
case VSLALvimL_v:
case VSRALvimL_v:
return 4;
case VSLDvvr_v:
case VSLDvvim:
return -1;
case VSLDvvrl_v:
case VSRDvviL:
return 4;
case VSLDvvimL_v:
case VSRDvvrml:
return 5;
case VSFAvrr_v:
case VSFAvrmm_v:
return -1;
case VSFAvirl_v:
case VSFAvirL:
return 4;
case VSFAvimml:
case VSFAvimmL_v:
return 5;
case VFADDDivml:
case VFSUBDivml:
case VFMULDivml:
case VFDIVDivml:
case VFCMPDivml:
case VFMAXDivml:
return 4;
case VFSQRTDv_v:
case VFSQRTSvm:
return -1;
case VFSQRTDvl_v:
case VFSQRTDvL:
return 2;
case VFSQRTDvmL_v:
case VFSQRTDvml:
case VFSQRTDvmL:
return 3;
case VFMADDvvv_v:
case PVFMADLOvrvm:
return -1;
case PVFMADvivl_v:
case PVFMADUPvrvL:
return 4;
case VFMADSivvmL_v:
case PVFMADLOvrvml:
case VFMSBDivvmL_v:
case VFNMADDivvmL_v:
case VFNMSBDivvmL_v:
return 5;
case VRCPDvmL:
case VRSQRTDvmL:
case VRSQRTDNEXvmL:
return 3;
case VCVTWDSXv:
case VCVTWDZXvm_v:
return -1;
case VCVTWSSXvl_v:
case VCVTWSZXvL:
return 3;
case PVCVTWSLOvmL_v:
case PVCVTWSUPvml:
case PVCVTWSvmL:
case VCVTLDvml:
return 4;
case VCVTDWvml:
case VCVTDLvml:
case VCVTSDvml:
case VCVTDSvml:
case VSUMWSXvml:
case VSUMLvml:
case VFSUMDvml:
case VRMAXSWFSTSXvml:
case VRMAXSLFSTvml:
case VFRMAXDFSTvml:
case VRANDvml:
case VRORvml:
case VRXORvml:
return 3;
case VFIADvr_v:
case VFIASvi_v:
return -1;
case VFIADvrl_v:
case VFIASviL_v:
case VFISDviL_v:
case VFIMDviL_v:
return 3;
case VFIAMDvvr_v:
case VFIAMSvvi_v:
return -1;
case VFISMDvvrl_v:
case VFISMSvviL_v:
case VFIMADvviL_v:
case VFIMSDvviL_v:
return 4;
case VMRGivml:
return 4;
case VCPvml:
case VEXvml:
return 3;
case VSHFvvr:
case VSHFvvr_v:
return -1;
case VSHFvvrl:
case VSHFvvrL_v:
return 4;
case VFMKLv:
case VFMKLvm:
return -1;
case VFMKLvl:
case VFMKLvL:
return 3;
case VFMKLvml:
case VFMKLvmL:
return 4;
case VFMKLal:
case VFMKLnaL:
return 1;
case VFMKLaml:
case VFMKLnamL:
case VFMKWnamL:
case VFMKDnamL:
return 2;
case TOVMm:
case PCVMm:
case LZVMm:
return -1;
case TOVMml:
case PCVMmL:
case LZVMml:
return 2;
}
return -2;
};
LLVMInitializeVETargetInfo();
LLVMInitializeVETarget();
LLVMInitializeVETargetMC();
auto TT(Triple::normalize("ve-unknown-linux-gnu"));
std::string Error;
const Target *T = TargetRegistry::lookupTarget(TT, Error);
if (!T) {
dbgs() << Error;
return;
}
TargetOptions Options;
auto TM = std::unique_ptr<LLVMTargetMachine>(
static_cast<LLVMTargetMachine*>(
T->createTargetMachine(TT, "", "", Options, std::nullopt, std::nullopt,
CodeGenOptLevel::Default)));
VESubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()),
std::string(TM->getTargetFeatureString()),
*static_cast<const VETargetMachine *>(TM.get()));
const VEInstrInfo *TII = ST.getInstrInfo();
auto MII = TM->getMCInstrInfo();
for (unsigned i = 0; i < VE::INSTRUCTION_LIST_END; ++i) {
// Skip -2 (default value)
if (VLIndex(i) == -2)
continue;
const MCInstrDesc &Desc = TII->get(i);
uint64_t Flags = Desc.TSFlags;
ASSERT_EQ(VLIndex(i), GET_VLINDEX(Flags))
<< MII->getName(i)
<< ": mismatched expected VL register index in its argument\n";
}
}