315 lines
7 KiB
C++
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";
|
|
}
|
|
}
|