1 //===- MachineInstrTest.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "VEInstrInfo.h" 10 #include "VESubtarget.h" 11 #include "VETargetMachine.h" 12 #include "llvm/MC/TargetRegistry.h" 13 #include "llvm/Support/TargetSelect.h" 14 #include "llvm/Target/TargetMachine.h" 15 #include "llvm/Target/TargetOptions.h" 16 17 #include "gtest/gtest.h" 18 19 using namespace llvm; 20 21 TEST(VETest, VLIndex) { 22 using namespace VE; 23 24 // Return expected VL register index in each MI's operands. Aurora VE has 25 // multiple instruction formats for each instruction. So, we define 26 // instructions hierarchically and tests parts of the whole instructions. 27 // This function returns -1 to N as expected index, or -2 as default. 28 // We skip a test on an instruction that this function returns -2. 29 auto VLIndex = [](unsigned Opcode) { 30 switch (Opcode) { 31 default: 32 break; 33 case VLDNCrz: 34 return -1; 35 case VLDUNCrzl: 36 case VLDLSXrzl_v: 37 case VLDLZXNCirL: 38 case VLD2DNCrrL_v: 39 case VLDU2DNCrzL_v: 40 case VLDL2DSXizL_v: 41 case VLDL2DZXNCirl: 42 return 3; 43 case VSTOTrrv: 44 return -1; 45 case VSTUNCrzvl: 46 case VSTLNCOTizvL: 47 case VST2Dirvl: 48 return 3; 49 case VSTU2DNCrzvml: 50 case VSTL2DNCOTrzvml: 51 return 4; 52 case VGTNCsrzm_v: 53 return -1; 54 case VGTUNCvrzl: 55 case VGTLSXvrzl_v: 56 case VGTLZXNCsirL: 57 return 4; 58 case VGTNCsrrmL_v: 59 case VGTUNCvrzmL: 60 case VGTLSXsizml_v: 61 return 5; 62 case VSCNCsrzvm: 63 return -1; 64 case VSCUNCvrzvl: 65 case VSCLNCsirvL: 66 return 4; 67 case VSCOTsrrvmL: 68 case VSCUNCOTvrzvmL: 69 case VSCLsizvml: 70 return 5; 71 case PFCHVrr: 72 return -1; 73 case PFCHVrrl: 74 case PFCHVNCrzL: 75 return 2; 76 case VBRDrm: 77 return -1; 78 case VBRDrl: 79 return 2; 80 case VBRDimL_v: 81 return 3; 82 case VMVrvm_v: 83 return -1; 84 case VMVivl: 85 return 3; 86 case VMVrvmL_v: 87 return 4; 88 case VADDULvv_v: 89 case PVADDULOrvm: 90 return -1; 91 case VADDUWvvl_v: 92 case PVADDUUPrvL: 93 return 3; 94 case PVADDUvvmL_v: 95 case VADDSWSXivml: 96 case VADDSLivml: 97 return 4; 98 case VDIVULvv_v: 99 case VDIVSWSXrvm: 100 return -1; 101 case VDIVUWvrl_v: 102 case VDIVSWZXviL: 103 return 3; 104 case VDIVSLivmL_v: 105 case VDIVSWSXivml: 106 return 4; 107 // We test casually if instructions are defined using a multiclass already 108 // tested. 109 case VSUBSLivml: 110 case VMULSLivml: 111 case VCMPSLivml: 112 case VMAXSLivml: 113 return 4; 114 case VANDvv_v: 115 case PVANDLOrvm: 116 return -1; 117 case PVANDvvl_v: 118 case PVANDUPrvL: 119 return 3; 120 case VORvvmL_v: 121 case PVORLOmvml: 122 case VXORmvml: 123 case VEQVmvml: 124 return 4; 125 case VLDZv: 126 return -1; 127 case VPCNTvL: 128 return 2; 129 case VBRVvml: 130 return 3; 131 case VSEQ: 132 return -1; 133 case VSEQL: 134 return 1; 135 case VSEQml: 136 return 2; 137 case VSLLvv_v: 138 case PVSLLLOvrm: 139 return -1; 140 case PVSLLvvl_v: 141 case PVSRLUPvrL: 142 return 3; 143 case VSLLvimL_v: 144 case PVSRLLOvrml: 145 case VSLALvimL_v: 146 case VSRALvimL_v: 147 return 4; 148 case VSLDvvr_v: 149 case VSLDvvim: 150 return -1; 151 case VSLDvvrl_v: 152 case VSRDvviL: 153 return 4; 154 case VSLDvvimL_v: 155 case VSRDvvrml: 156 return 5; 157 case VSFAvrr_v: 158 case VSFAvrmm_v: 159 return -1; 160 case VSFAvirl_v: 161 case VSFAvirL: 162 return 4; 163 case VSFAvimml: 164 case VSFAvimmL_v: 165 return 5; 166 case VFADDDivml: 167 case VFSUBDivml: 168 case VFMULDivml: 169 case VFDIVDivml: 170 case VFCMPDivml: 171 case VFMAXDivml: 172 return 4; 173 case VFSQRTDv_v: 174 case VFSQRTSvm: 175 return -1; 176 case VFSQRTDvl_v: 177 case VFSQRTDvL: 178 return 2; 179 case VFSQRTDvmL_v: 180 case VFSQRTDvml: 181 case VFSQRTDvmL: 182 return 3; 183 case VFMADDvvv_v: 184 case PVFMADLOvrvm: 185 return -1; 186 case PVFMADvivl_v: 187 case PVFMADUPvrvL: 188 return 4; 189 case VFMADSivvmL_v: 190 case PVFMADLOvrvml: 191 case VFMSBDivvmL_v: 192 case VFNMADDivvmL_v: 193 case VFNMSBDivvmL_v: 194 return 5; 195 case VRCPDvmL: 196 case VRSQRTDvmL: 197 case VRSQRTDNEXvmL: 198 return 3; 199 case VCVTWDSXv: 200 case VCVTWDZXvm_v: 201 return -1; 202 case VCVTWSSXvl_v: 203 case VCVTWSZXvL: 204 return 3; 205 case PVCVTWSLOvmL_v: 206 case PVCVTWSUPvml: 207 case PVCVTWSvmL: 208 case VCVTLDvml: 209 return 4; 210 case VCVTDWvml: 211 case VCVTDLvml: 212 case VCVTSDvml: 213 case VCVTDSvml: 214 case VSUMWSXvml: 215 case VSUMLvml: 216 case VFSUMDvml: 217 case VRMAXSWFSTSXvml: 218 case VRMAXSLFSTvml: 219 case VFRMAXDFSTvml: 220 case VRANDvml: 221 case VRORvml: 222 case VRXORvml: 223 return 3; 224 case VFIADvr_v: 225 case VFIASvi_v: 226 return -1; 227 case VFIADvrl_v: 228 case VFIASviL_v: 229 case VFISDviL_v: 230 case VFIMDviL_v: 231 return 3; 232 case VFIAMDvvr_v: 233 case VFIAMSvvi_v: 234 return -1; 235 case VFISMDvvrl_v: 236 case VFISMSvviL_v: 237 case VFIMADvviL_v: 238 case VFIMSDvviL_v: 239 return 4; 240 case VMRGivml: 241 return 4; 242 case VCPvml: 243 case VEXvml: 244 return 3; 245 case VSHFvvr: 246 case VSHFvvr_v: 247 return -1; 248 case VSHFvvrl: 249 case VSHFvvrL_v: 250 return 4; 251 case VFMKLv: 252 case VFMKLvm: 253 return -1; 254 case VFMKLvl: 255 case VFMKLvL: 256 return 3; 257 case VFMKLvml: 258 case VFMKLvmL: 259 return 4; 260 case VFMKLal: 261 case VFMKLnaL: 262 return 1; 263 case VFMKLaml: 264 case VFMKLnamL: 265 case VFMKWnamL: 266 case VFMKDnamL: 267 return 2; 268 case TOVMm: 269 case PCVMm: 270 case LZVMm: 271 return -1; 272 case TOVMml: 273 case PCVMmL: 274 case LZVMml: 275 return 2; 276 } 277 return -2; 278 }; 279 280 LLVMInitializeVETargetInfo(); 281 LLVMInitializeVETarget(); 282 LLVMInitializeVETargetMC(); 283 284 auto TT(Triple::normalize("ve-unknown-linux-gnu")); 285 std::string Error; 286 const Target *T = TargetRegistry::lookupTarget(TT, Error); 287 if (!T) { 288 dbgs() << Error; 289 return; 290 } 291 292 TargetOptions Options; 293 auto TM = std::unique_ptr<TargetMachine>( 294 T->createTargetMachine(TT, "", "", Options, std::nullopt, std::nullopt, 295 CodeGenOptLevel::Default)); 296 VESubtarget ST(TM->getTargetTriple(), std::string(TM->getTargetCPU()), 297 std::string(TM->getTargetFeatureString()), 298 *static_cast<const VETargetMachine *>(TM.get())); 299 const VEInstrInfo *TII = ST.getInstrInfo(); 300 auto MII = TM->getMCInstrInfo(); 301 302 for (unsigned i = 0; i < VE::INSTRUCTION_LIST_END; ++i) { 303 // Skip -2 (default value) 304 if (VLIndex(i) == -2) 305 continue; 306 307 const MCInstrDesc &Desc = TII->get(i); 308 309 uint64_t Flags = Desc.TSFlags; 310 ASSERT_EQ(VLIndex(i), GET_VLINDEX(Flags)) 311 << MII->getName(i) 312 << ": mismatched expected VL register index in its argument\n"; 313 } 314 } 315