NeonEmitter.cpp revision 51cc0172a173599b769968696e20638754d1dcd6
151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===- NeonEmitter.cpp - Generate arm_neon.h for use with clang -*- C++ -*-===// 251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// The LLVM Compiler Infrastructure 451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// This file is distributed under the University of Illinois Open Source 651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// License. See LICENSE.TXT for details. 751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// This tablegen backend is responsible for emitting arm_neon.h, which includes 1151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// a declaration and definition of each function specified by the ARM NEON 1251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// compiler interface. See ARM document DUI0348B. 1351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 1451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Each NEON instruction is implemented in terms of 1 or more functions which 1551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// are suffixed with the element type of the input vectors. Functions may be 1651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// implemented in terms of generic vector operations such as +, *, -, etc. or 1751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// by calling a __builtin_-prefixed function which will be handled by clang's 1851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// CodeGen library. 1951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 2051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Additional validation code can be generated by this file when runHeader() is 2151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// called, rather than the normal run() entry point. A complete set of tests 2251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// for Neon intrinsics can be generated by calling the runTests() entry point. 2351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// 2451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne//===----------------------------------------------------------------------===// 2551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 263cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/ADT/DenseMap.h" 2751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/SmallString.h" 2851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/SmallVector.h" 2951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include "llvm/ADT/StringExtras.h" 303cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/ADT/StringMap.h" 317530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie#include "llvm/Support/ErrorHandling.h" 323cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/Error.h" 333cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/Record.h" 343cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen#include "llvm/TableGen/TableGenBackend.h" 3551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne#include <string> 3651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourneusing namespace llvm; 3751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 383cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenenum OpKind { 393cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpNone, 403cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpUnavailable, 413cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAdd, 423cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAddl, 43097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpAddlHi, 443cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAddw, 45097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpAddwHi, 463cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpSub, 473cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpSubl, 48097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpSublHi, 493cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpSubw, 50097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpSubwHi, 513cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMul, 523cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMla, 533cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlal, 54097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMullHi, 55097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMlalHi, 563cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMls, 573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlsl, 58097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMlslHi, 593cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMulN, 603cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlaN, 613cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlsN, 623cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlalN, 633cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlslN, 643cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMulLane, 650aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMulXLane, 663cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMullLane, 670aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMullHiLane, 683cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlaLane, 693cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlsLane, 703cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlalLane, 710aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMlalHiLane, 723cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMlslLane, 730aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMlslHiLane, 743cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpQDMullLane, 750aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpQDMullHiLane, 763cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpQDMlalLane, 770aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpQDMlalHiLane, 783cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpQDMlslLane, 790aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpQDMlslHiLane, 803cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpQDMulhLane, 813cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpQRDMulhLane, 820aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpFMSLane, 830aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpFMSLaneQ, 84bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpTrn1, 85bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpZip1, 86bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpUzp1, 87bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpTrn2, 88bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpZip2, 89bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpUzp2, 903cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpEq, 913cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpGe, 923cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpLe, 933cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpGt, 943cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpLt, 953cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpNeg, 963cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpNot, 973cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAnd, 983cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpOr, 993cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpXor, 1003cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAndNot, 1013cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpOrNot, 1023cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpCast, 1033cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpConcat, 1043cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpDup, 1053cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpDupLane, 1063cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpHi, 1073cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpLo, 1083cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpSelect, 1093cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpRev16, 1103cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpRev32, 1113cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpRev64, 1128137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpXtnHi, 1138137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpSqxtunHi, 1148137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpQxtnHi, 1158137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpFcvtnHi, 1168137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpFcvtlHi, 1178137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpFcvtxnHi, 1183cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpReinterpret, 119097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpAddhnHi, 120097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpRAddhnHi, 121097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpSubhnHi, 122097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpRSubhnHi, 1233cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAbdl, 124097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpAbdlHi, 1253cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpAba, 126b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OpAbal, 127097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpAbalHi, 128097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpQDMullHi, 129097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpQDMlalHi, 130097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpQDMlslHi, 131912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu OpDiv, 132912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu OpLongHi, 133912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu OpNarrowHi, 1342102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin OpMovlHi, 13522229d6822324a42913d25f256045dbf348a53e9Kevin Qin OpCopyLane, 13622229d6822324a42913d25f256045dbf348a53e9Kevin Qin OpCopyQLane, 13751cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpCopyLaneQ, 13851cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpScalarMulLane, 13951cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpScalarMulLaneQ, 14051cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpScalarMulXLane, 14151cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpScalarMulXLaneQ, 14251cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpScalarVMulXLane, 14351cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpScalarVMulXLaneQ 1443cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen}; 1453cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1463cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenenum ClassKind { 1473cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassNone, 1483cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassI, // generic integer instruction, e.g., "i8" suffix 1493cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassS, // signed/unsigned/poly, e.g., "s8", "u8" or "p8" suffix 1503cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassW, // width-specific instruction, e.g., "8" suffix 15121e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassB, // bitcast arguments with enum argument to specify type 15221e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassL, // Logical instructions which are op instructions 15321e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman // but we need to not emit any suffix for in our 15421e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman // tests. 15521e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassNoTest // Instructions which we do not test since they are 15621e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman // not TRUE instructions. 1573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen}; 1583cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1593cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// NeonTypeFlags - Flags to identify the types for overloaded Neon 1603cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// builtins. These must be kept in sync with the flags in 1613cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen/// include/clang/Basic/TargetBuiltins.h. 1623cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace { 1633cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenclass NeonTypeFlags { 1643cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen enum { 1653cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen EltTypeMask = 0xf, 1663cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen UnsignedFlag = 0x10, 1673cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen QuadFlag = 0x20 1683cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen }; 1693cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen uint32_t Flags; 1703cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1713cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenpublic: 1723cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen enum EltType { 1733cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Int8, 1743cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Int16, 1753cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Int32, 1763cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Int64, 1773cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Poly8, 1783cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Poly16, 179624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin Poly64, 1803cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Float16, 181b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Float32, 182b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Float64 1833cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen }; 1843cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1853cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen NeonTypeFlags(unsigned F) : Flags(F) {} 1863cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) { 1873cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen if (IsUnsigned) 1883cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Flags |= UnsignedFlag; 1893cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen if (IsQuad) 1903cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Flags |= QuadFlag; 1913cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen } 1923cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1933cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen uint32_t getFlags() const { return Flags; } 1943cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen}; 1953cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end anonymous namespace 1963cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 1973cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace { 1983cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenclass NeonEmitter { 1993cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen RecordKeeper &Records; 2003cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen StringMap<OpKind> OpMap; 2013cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen DenseMap<Record*, ClassKind> ClassMap; 2023cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 2033cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenpublic: 2043cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen NeonEmitter(RecordKeeper &R) : Records(R) { 2053cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_NONE"] = OpNone; 2063cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_UNAVAILABLE"] = OpUnavailable; 2073cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ADD"] = OpAdd; 2083cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ADDL"] = OpAddl; 209097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_ADDLHi"] = OpAddlHi; 2103cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ADDW"] = OpAddw; 211097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_ADDWHi"] = OpAddwHi; 2123cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_SUB"] = OpSub; 2133cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_SUBL"] = OpSubl; 214097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_SUBLHi"] = OpSublHi; 2153cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_SUBW"] = OpSubw; 216097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_SUBWHi"] = OpSubwHi; 2173cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MUL"] = OpMul; 2183cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLA"] = OpMla; 2193cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLAL"] = OpMlal; 220097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_MULLHi"] = OpMullHi; 221097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_MLALHi"] = OpMlalHi; 2223cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLS"] = OpMls; 2233cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLSL"] = OpMlsl; 224097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_MLSLHi"] = OpMlslHi; 2253cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MUL_N"] = OpMulN; 2263cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLA_N"] = OpMlaN; 2273cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLS_N"] = OpMlsN; 2283cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLAL_N"] = OpMlalN; 2293cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLSL_N"] = OpMlslN; 2303cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MUL_LN"]= OpMulLane; 2310aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_MULX_LN"]= OpMulXLane; 2323cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MULL_LN"] = OpMullLane; 2330aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_MULLHi_LN"] = OpMullHiLane; 2343cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLA_LN"]= OpMlaLane; 2353cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLS_LN"]= OpMlsLane; 2363cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLAL_LN"] = OpMlalLane; 2370aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_MLALHi_LN"] = OpMlalHiLane; 2383cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_MLSL_LN"] = OpMlslLane; 2390aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_MLSLHi_LN"] = OpMlslHiLane; 2403cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_QDMULL_LN"] = OpQDMullLane; 2410aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_QDMULLHi_LN"] = OpQDMullHiLane; 2423cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_QDMLAL_LN"] = OpQDMlalLane; 2430aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_QDMLALHi_LN"] = OpQDMlalHiLane; 2443cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_QDMLSL_LN"] = OpQDMlslLane; 2450aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_QDMLSLHi_LN"] = OpQDMlslHiLane; 2463cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_QDMULH_LN"] = OpQDMulhLane; 2473cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_QRDMULH_LN"] = OpQRDMulhLane; 2480aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_FMS_LN"] = OpFMSLane; 2490aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OpMap["OP_FMS_LNQ"] = OpFMSLaneQ; 250bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpMap["OP_TRN1"] = OpTrn1; 251bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpMap["OP_ZIP1"] = OpZip1; 252bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpMap["OP_UZP1"] = OpUzp1; 253bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpMap["OP_TRN2"] = OpTrn2; 254bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpMap["OP_ZIP2"] = OpZip2; 255bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu OpMap["OP_UZP2"] = OpUzp2; 2563cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_EQ"] = OpEq; 2573cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_GE"] = OpGe; 2583cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_LE"] = OpLe; 2593cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_GT"] = OpGt; 2603cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_LT"] = OpLt; 2613cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_NEG"] = OpNeg; 2623cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_NOT"] = OpNot; 2633cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_AND"] = OpAnd; 2643cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_OR"] = OpOr; 2653cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_XOR"] = OpXor; 2663cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ANDN"] = OpAndNot; 2673cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ORN"] = OpOrNot; 2683cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_CAST"] = OpCast; 2693cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_CONC"] = OpConcat; 2703cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_HI"] = OpHi; 2713cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_LO"] = OpLo; 2723cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_DUP"] = OpDup; 2733cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_DUP_LN"] = OpDupLane; 2743cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_SEL"] = OpSelect; 2753cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_REV16"] = OpRev16; 2763cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_REV32"] = OpRev32; 2773cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_REV64"] = OpRev64; 2788137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpMap["OP_XTN"] = OpXtnHi; 2798137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpMap["OP_SQXTUN"] = OpSqxtunHi; 2808137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpMap["OP_QXTN"] = OpQxtnHi; 2818137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpMap["OP_VCVT_NA_HI"] = OpFcvtnHi; 2828137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpMap["OP_VCVT_EX_HI"] = OpFcvtlHi; 2838137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin OpMap["OP_VCVTX_HI"] = OpFcvtxnHi; 2843cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_REINT"] = OpReinterpret; 285097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_ADDHNHi"] = OpAddhnHi; 286097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_RADDHNHi"] = OpRAddhnHi; 287097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_SUBHNHi"] = OpSubhnHi; 288097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_RSUBHNHi"] = OpRSubhnHi; 2893cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ABDL"] = OpAbdl; 290097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_ABDLHi"] = OpAbdlHi; 2913cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ABA"] = OpAba; 2923cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen OpMap["OP_ABAL"] = OpAbal; 293097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_ABALHi"] = OpAbalHi; 294097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_QDMULLHi"] = OpQDMullHi; 295097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_QDMLALHi"] = OpQDMlalHi; 296097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu OpMap["OP_QDMLSLHi"] = OpQDMlslHi; 297b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OpMap["OP_DIV"] = OpDiv; 298912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu OpMap["OP_LONG_HI"] = OpLongHi; 299912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu OpMap["OP_NARROW_HI"] = OpNarrowHi; 300912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu OpMap["OP_MOVL_HI"] = OpMovlHi; 30122229d6822324a42913d25f256045dbf348a53e9Kevin Qin OpMap["OP_COPY_LN"] = OpCopyLane; 30222229d6822324a42913d25f256045dbf348a53e9Kevin Qin OpMap["OP_COPYQ_LN"] = OpCopyQLane; 30322229d6822324a42913d25f256045dbf348a53e9Kevin Qin OpMap["OP_COPY_LNQ"] = OpCopyLaneQ; 30451cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpMap["OP_SCALAR_MUL_LN"]= OpScalarMulLane; 30551cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpMap["OP_SCALAR_MUL_LNQ"]= OpScalarMulLaneQ; 30651cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpMap["OP_SCALAR_MULX_LN"]= OpScalarMulXLane; 30751cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpMap["OP_SCALAR_MULX_LNQ"]= OpScalarMulXLaneQ; 30851cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpMap["OP_SCALAR_VMULX_LN"]= OpScalarVMulXLane; 30951cc0172a173599b769968696e20638754d1dcd6Ana Pazos OpMap["OP_SCALAR_VMULX_LNQ"]= OpScalarVMulXLaneQ; 3103cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 3113cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Record *SI = R.getClass("SInst"); 3123cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Record *II = R.getClass("IInst"); 3133cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen Record *WI = R.getClass("WInst"); 31421e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman Record *SOpI = R.getClass("SOpInst"); 31521e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman Record *IOpI = R.getClass("IOpInst"); 31621e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman Record *WOpI = R.getClass("WOpInst"); 31721e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman Record *LOpI = R.getClass("LOpInst"); 31821e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman Record *NoTestOpI = R.getClass("NoTestOpInst"); 31921e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman 3203cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassMap[SI] = ClassS; 3213cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassMap[II] = ClassI; 3223cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen ClassMap[WI] = ClassW; 32321e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassMap[SOpI] = ClassS; 32421e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassMap[IOpI] = ClassI; 32521e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassMap[WOpI] = ClassW; 32621e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassMap[LOpI] = ClassL; 32721e4e940ed3ad172f344a3aa3faf1d8437441313Michael Gottesman ClassMap[NoTestOpI] = ClassNoTest; 3283cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen } 3293cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 3303cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // run - Emit arm_neon.h.inc 3313cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen void run(raw_ostream &o); 3323cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 3333cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // runHeader - Emit all the __builtin prototypes used in arm_neon.h 3343cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen void runHeader(raw_ostream &o); 3353cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 3363cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen // runTests - Emit tests for all the Neon intrinsics. 3373cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen void runTests(raw_ostream &o); 3383cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 3393cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenprivate: 340b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover void emitIntrinsic(raw_ostream &OS, Record *R, 341b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &EmittedMap); 342b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover void genBuiltinsDef(raw_ostream &OS, StringMap<ClassKind> &A64IntrinsicMap, 343b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64GenBuiltinDef); 344b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover void genOverloadTypeCheckCode(raw_ostream &OS, 345b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &A64IntrinsicMap, 346b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64TypeCheck); 347b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover void genIntrinsicRangeCheckCode(raw_ostream &OS, 348b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &A64IntrinsicMap, 349b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64RangeCheck); 350b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover void genTargetTest(raw_ostream &OS, StringMap<OpKind> &EmittedMap, 351b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64TestGen); 3523cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen}; 3533cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // end anonymous namespace 3543cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen 35551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// ParseTypes - break down a string such as "fQf" into a vector of StringRefs, 35651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// which each StringRef representing a single type declared in the string. 35751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// for "fQf" we would end up with 2 StringRefs, "f", and "Qf", representing 35851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// 2xfloat and 4xfloat respectively. 35951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic void ParseTypes(Record *r, std::string &s, 36051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVectorImpl<StringRef> &TV) { 36151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const char *data = s.data(); 36251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne int len = 0; 36351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 36451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = s.size(); i != e; ++i, ++len) { 36512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu if (data[len] == 'P' || data[len] == 'Q' || data[len] == 'U' 366944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin || data[len] == 'H' || data[len] == 'S') 36751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 36851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 36951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (data[len]) { 37051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 37151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 37251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 37351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 37451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 37551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 376b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case 'd': 37751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 37851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 37938859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError(r->getLoc(), 38051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "Unexpected letter: " + std::string(data + len, 1)); 38151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 38251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne TV.push_back(StringRef(data, len + 1)); 38351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne data += len + 1; 38451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne len = -1; 38551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 38651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 38751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 38851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// Widen - Convert a type code into the next wider type. char -> short, 38951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// short -> int, etc. 39051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic char Widen(const char t) { 39151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (t) { 39251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 39351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 's'; 39451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 39551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 'i'; 39651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 39751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 'l'; 39851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 39951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 'f'; 4008137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case 'f': 4018137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin return 'd'; 40238859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger default: 40338859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type in widen!"); 40451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 40551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 40651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 40751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// Narrow - Convert a type code into the next smaller type. short -> char, 40851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// float -> half float, etc. 40951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic char Narrow(const char t) { 41051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (t) { 41151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 41251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 'c'; 41351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 41451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 's'; 41551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 41651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 'i'; 41751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 41851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return 'h'; 4198137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case 'd': 4208137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin return 'f'; 42138859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger default: 42238859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type in narrow!"); 42351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 42451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 42551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 426097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liustatic std::string GetNarrowTypestr(StringRef ty) 427097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu{ 428097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string s; 429097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu for (size_t i = 0, end = ty.size(); i < end; i++) { 430097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu switch (ty[i]) { 431097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case 's': 432097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += 'c'; 433097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 434097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case 'i': 435097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += 's'; 436097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 437097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case 'l': 438097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += 'i'; 439097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 440097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu default: 441097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += ty[i]; 442097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 443097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu } 444097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu } 445097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 446097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return s; 447097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu} 448097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 44951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// For a particular StringRef, return the base type code, and whether it has 45051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// the quad-vector, polynomial, or unsigned modifiers set. 45151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) { 45251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned off = 0; 453944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin // ignore scalar. 454944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if (ty[off] == 'S') { 455944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin ++off; 456944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin } 45751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // remember quad. 45812cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu if (ty[off] == 'Q' || ty[off] == 'H') { 45951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = true; 46051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ++off; 46151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 46251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 46351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // remember poly. 46451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ty[off] == 'P') { 46551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne poly = true; 46651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ++off; 46751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 46851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 46951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // remember unsigned. 47051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ty[off] == 'U') { 47151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = true; 47251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ++off; 47351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 47451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 47551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // base type to get the type string for. 47651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return ty[off]; 47751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 47851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 47951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// ModType - Transform a type code and its modifiers based on a mod code. The 48051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// mod code definitions may be found at the top of arm_neon.td. 48151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic char ModType(const char mod, char type, bool &quad, bool &poly, 48251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool &usgn, bool &scal, bool &cnst, bool &pntr) { 48351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (mod) { 48451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 't': 48551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (poly) { 48651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne poly = false; 48751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = true; 48851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 48951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 490564020954e9eb01293d90802c89a02f87301e095Chad Rosier case 'b': 491564020954e9eb01293d90802c89a02f87301e095Chad Rosier scal = true; 49251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'u': 49351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = true; 49451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne poly = false; 49551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (type == 'f') 49651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 'i'; 497b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (type == 'd') 498b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover type = 'l'; 49951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 5009473c1945f9f1dfa143e172622f16e4264e2628bChad Rosier case '$': 5019473c1945f9f1dfa143e172622f16e4264e2628bChad Rosier scal = true; 50251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'x': 50351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = false; 50451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne poly = false; 50551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (type == 'f') 50651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 'i'; 507912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu if (type == 'd') 508912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu type = 'l'; 50951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 5106d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier case 'o': 5116d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier scal = true; 5126d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier type = 'd'; 5136d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier usgn = false; 5146d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier break; 5156d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier case 'y': 5166d048e1a9768b594513e2ec7a6d3579787eb2505Chad Rosier scal = true; 51751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 51851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (type == 'h') 51951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = true; 52051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 'f'; 52151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = false; 52251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 52351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'g': 52451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = false; 52551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 5262e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu case 'B': 5272e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu case 'C': 5282e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu case 'D': 5290aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case 'j': 5300aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu quad = true; 5310aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 53251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'w': 53351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = Widen(type); 53451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = true; 53551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 53651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'n': 53751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = Widen(type); 53851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 53951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 54051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 'i'; 54151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne scal = true; 54251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 54351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 54451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 'l'; 54551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne scal = true; 54651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = true; 54751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 5484553a858e46299955333babfa052a512682869fdChad Rosier case 'z': 5494553a858e46299955333babfa052a512682869fdChad Rosier type = Narrow(type); 5504553a858e46299955333babfa052a512682869fdChad Rosier scal = true; 5514553a858e46299955333babfa052a512682869fdChad Rosier break; 5520391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu case 'r': 5530391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu type = Widen(type); 5544553a858e46299955333babfa052a512682869fdChad Rosier scal = true; 5554553a858e46299955333babfa052a512682869fdChad Rosier break; 55651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 55751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'a': 55851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne scal = true; 55951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 56051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'k': 56151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = true; 56251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 56351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 56451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne cnst = true; 56551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'p': 56651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne pntr = true; 56751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne scal = true; 56851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 56951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 57051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = Narrow(type); 57151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (type == 'h') 57251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = false; 57351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 574097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case 'q': 575097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu type = Narrow(type); 576097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu quad = true; 577097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 57851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'e': 57951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = Narrow(type); 58051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = true; 58151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 582912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case 'm': 583912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu type = Narrow(type); 584912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu quad = false; 585912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu break; 58651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 58751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 58851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 58951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return type; 59051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 59151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 5922e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liustatic bool IsMultiVecProto(const char p) { 5932e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu return ((p >= '2' && p <= '4') || (p >= 'B' && p <= 'D')); 5942e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu} 5952e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu 59651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// TypeString - for a modifier and type, generate the name of the typedef for 59751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// that type. QUc -> uint8x8_t. 59851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string TypeString(const char mod, StringRef typestr) { 59951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool quad = false; 60051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool poly = false; 60151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool usgn = false; 60251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool scal = false; 60351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool cnst = false; 60451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool pntr = false; 60551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 60651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'v') 60751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return "void"; 60851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'i') 60951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return "int"; 61051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // base type to get the type string for. 61251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char type = ClassifyType(typestr, quad, poly, usgn); 61351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Based on the modifying character, change the type and width if necessary. 61551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); 61651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallString<128> s; 61851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 61951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (usgn) 62051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back('u'); 62151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 62251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (type) { 62351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 62451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += poly ? "poly8" : "int8"; 62551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) 62651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 62751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += quad ? "x16" : "x8"; 62851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 62951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 63051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += poly ? "poly16" : "int16"; 63151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) 63251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 63351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += quad ? "x8" : "x4"; 63451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 63551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 63651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "int32"; 63751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) 63851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 63951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += quad ? "x4" : "x2"; 64051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 64151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 642624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin s += (poly && !usgn)? "poly64" : "int64"; 64351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) 64451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 64551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += quad ? "x2" : "x1"; 64651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 64751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 64851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "float16"; 64951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) 65051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 65151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += quad ? "x8" : "x4"; 65251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 65351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 65451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "float32"; 65551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) 65651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 65751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += quad ? "x4" : "x2"; 65851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 659b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case 'd': 660b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s += "float64"; 661b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (scal) 662b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 663b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s += quad ? "x2" : "x1"; 664b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 665b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 66651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 66738859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type!"); 66851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 66951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 6702e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (mod == '2' || mod == 'B') 67151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "x2"; 6722e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (mod == '3' || mod == 'C') 67351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "x3"; 6742e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (mod == '4' || mod == 'D') 67551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "x4"; 67651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 67751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Append _t, finishing the type string typedef type. 67851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "_t"; 67951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 68051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (cnst) 68151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " const"; 68251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 68351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (pntr) 68451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " *"; 68551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 68651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s.str(); 68751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 68851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 68951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// BuiltinTypeString - for a modifier and type, generate the clang 69051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// BuiltinsARM.def prototype code for the function. See the top of clang's 69151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// Builtins.def for a description of the type strings. 69251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string BuiltinTypeString(const char mod, StringRef typestr, 69351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ClassKind ck, bool ret) { 69451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool quad = false; 69551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool poly = false; 69651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool usgn = false; 69751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool scal = false; 69851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool cnst = false; 69951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool pntr = false; 70051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 70151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'v') 70251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return "v"; // void 70351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'i') 70451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return "i"; // int 70551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 70651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // base type to get the type string for. 70751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char type = ClassifyType(typestr, quad, poly, usgn); 70851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 70951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Based on the modifying character, change the type and width if necessary. 71051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); 71151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 71251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // All pointers are void* pointers. Change type to 'v' now. 71351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (pntr) { 71451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = false; 71551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne poly = false; 71651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 'v'; 71751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 71851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Treat half-float ('h') types as unsigned short ('s') types. 71951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (type == 'h') { 72051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = 's'; 72151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne usgn = true; 72251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 7230aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu usgn = usgn | poly | ((ck == ClassI || ck == ClassW) && 7240aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu scal && type != 'f' && type != 'd'); 72551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 72651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (scal) { 72751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallString<128> s; 72851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 72951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (usgn) 73051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back('U'); 73151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else if (type == 'c') 73251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back('S'); // make chars explicitly signed 73351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 73451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (type == 'l') // 64-bit long 73551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "LLi"; 73651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 73751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back(type); 73851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 73951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (cnst) 74051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back('C'); 74151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (pntr) 74251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back('*'); 74351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s.str(); 74451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 74551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 74651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Since the return value must be one type, return a vector type of the 74751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // appropriate width which we will bitcast. An exception is made for 74851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // returning structs of 2, 3, or 4 vectors which are returned in a sret-like 74951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // fashion, storing them to a pointer arg. 75051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ret) { 7512e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (IsMultiVecProto(mod)) 75251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return "vv*"; // void result with void* first argument 75351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'f' || (ck != ClassB && type == 'f')) 75451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V4f" : "V2f"; 7550aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu if (ck != ClassB && type == 'd') 7560aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu return quad ? "V2d" : "V1d"; 75751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB && type == 's') 75851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V8s" : "V4s"; 75951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB && type == 'i') 76051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V4i" : "V2i"; 76151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB && type == 'l') 76251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V2LLi" : "V1LLi"; 76351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 76451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V16Sc" : "V8Sc"; 76551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 76651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 76751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Non-return array types are passed as individual vectors. 7682e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (mod == '2' || mod == 'B') 76951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V16ScV16Sc" : "V8ScV8Sc"; 7702e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (mod == '3' || mod == 'C') 77151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V16ScV16ScV16Sc" : "V8ScV8ScV8Sc"; 7722e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (mod == '4' || mod == 'D') 77351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V16ScV16ScV16ScV16Sc" : "V8ScV8ScV8ScV8Sc"; 77451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 77551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'f' || (ck != ClassB && type == 'f')) 77651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V4f" : "V2f"; 7770aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu if (ck != ClassB && type == 'd') 7780aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu return quad ? "V2d" : "V1d"; 77951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB && type == 's') 78051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V8s" : "V4s"; 78151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB && type == 'i') 78251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V4i" : "V2i"; 78351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB && type == 'l') 78451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V2LLi" : "V1LLi"; 78551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 78651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return quad ? "V16Sc" : "V8Sc"; 78751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 78851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 789fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman/// InstructionTypeCode - Computes the ARM argument character code and 790fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman/// quad status for a specific type string and ClassKind. 791fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesmanstatic void InstructionTypeCode(const StringRef &typeStr, 792fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman const ClassKind ck, 793fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman bool &quad, 794fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman std::string &typeCode) { 79551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool poly = false; 79651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool usgn = false; 797fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman char type = ClassifyType(typeStr, quad, poly, usgn); 79851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 79951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (type) { 80051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 80151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (ck) { 802fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassS: typeCode = poly ? "p8" : usgn ? "u8" : "s8"; break; 803fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassI: typeCode = "i8"; break; 804fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassW: typeCode = "8"; break; 80551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: break; 80651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 80751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 80851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 80951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (ck) { 810fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassS: typeCode = poly ? "p16" : usgn ? "u16" : "s16"; break; 811fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassI: typeCode = "i16"; break; 812fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassW: typeCode = "16"; break; 81351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: break; 81451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 81551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 81651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 81751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (ck) { 818fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassS: typeCode = usgn ? "u32" : "s32"; break; 819fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassI: typeCode = "i32"; break; 820fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassW: typeCode = "32"; break; 82151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: break; 82251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 82351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 82451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 82551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (ck) { 826624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin case ClassS: typeCode = poly ? "p64" : usgn ? "u64" : "s64"; break; 827fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassI: typeCode = "i64"; break; 828fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassW: typeCode = "64"; break; 82951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: break; 83051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 83151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 83251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 83351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (ck) { 83451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case ClassS: 835fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassI: typeCode = "f16"; break; 836fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassW: typeCode = "16"; break; 83751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: break; 83851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 83951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 84051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 84151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (ck) { 84251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case ClassS: 843fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassI: typeCode = "f32"; break; 844fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman case ClassW: typeCode = "32"; break; 84551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: break; 84651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 84751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 848b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case 'd': 849b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover switch (ck) { 850b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case ClassS: 851b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case ClassI: 852b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover typeCode += "f64"; 853b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 854b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case ClassW: 855b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover PrintFatalError("unhandled type!"); 856b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover default: 857b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 858b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 859b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 86051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 86138859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type!"); 86251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 863fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman} 864fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman 865944f09ff9b33637465906e1aeadcfa405d66331dKevin Qinstatic char Insert_BHSD_Suffix(StringRef typestr){ 866944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin unsigned off = 0; 867944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if(typestr[off++] == 'S'){ 868944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin while(typestr[off] == 'Q' || typestr[off] == 'H'|| 869944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin typestr[off] == 'P' || typestr[off] == 'U') 870944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin ++off; 871944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin switch (typestr[off]){ 872944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin default : break; 873944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin case 'c' : return 'b'; 874944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin case 's' : return 'h'; 875944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin case 'i' : 876944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin case 'f' : return 's'; 877944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin case 'l' : 878944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin case 'd' : return 'd'; 879944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin } 880944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin } 881944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin return 0; 882944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin} 883944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin 884fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman/// MangleName - Append a type or width suffix to a base neon function name, 88512cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu/// and insert a 'q' in the appropriate location if type string starts with 'Q'. 88612cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu/// E.g. turn "vst2_lane" into "vst2q_lane_f32", etc. 887944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin/// Insert proper 'b' 'h' 's' 'd' if prefix 'S' is used. 888fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesmanstatic std::string MangleName(const std::string &name, StringRef typestr, 889fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman ClassKind ck) { 8908137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin if (name == "vcvt_f32_f16" || name == "vcvt_f32_f64") 891fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman return name; 892fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman 893fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman bool quad = false; 894fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman std::string typeCode = ""; 895fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman 896fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman InstructionTypeCode(typestr, ck, quad, typeCode); 897fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman 898fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman std::string s = name; 899fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman 900fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman if (typeCode.size() > 0) { 901fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman s += "_" + typeCode; 902fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman } 903fb599a4cc5665afe8da11d438ae021a5cd8cfdbdMichael Gottesman 90451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck == ClassB) 90551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "_v"; 90651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 90751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Insert a 'q' before the first '_' character so that it ends up before 90851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // _lane or _n on vector-scalar operations. 909944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if (typestr.find("Q") != StringRef::npos) { 91012cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu size_t pos = s.find('_'); 91112cd6a83f280bcab0e80230e8c7b1f989f3b4889Hao Liu s = s.insert(pos, "q"); 91251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 913944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin char ins = Insert_BHSD_Suffix(typestr); 914944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if(ins){ 915944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin size_t pos = s.find('_'); 916944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin s = s.insert(pos, &ins, 1); 917944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin } 918c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 91951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 92051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 92151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 922c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic void PreprocessInstruction(const StringRef &Name, 923c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string &InstName, 924c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string &Prefix, 925c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool &HasNPostfix, 926c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool &HasLanePostfix, 927c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool &HasDupPostfix, 928c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool &IsSpecialVCvt, 929c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman size_t &TBNumber) { 930c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // All of our instruction name fields from arm_neon.td are of the form 931c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // <instructionname>_... 932c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Thus we grab our instruction name via computation of said Prefix. 933c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const size_t PrefixEnd = Name.find_first_of('_'); 934c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If InstName is passed in, we use that instead of our name Prefix. 935c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Prefix = InstName.size() == 0? Name.slice(0, PrefixEnd).str() : InstName; 936c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 937c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const StringRef Postfix = Name.slice(PrefixEnd, Name.size()); 938c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 939c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasNPostfix = Postfix.count("_n"); 940c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasLanePostfix = Postfix.count("_lane"); 941c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasDupPostfix = Postfix.count("_dup"); 942c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman IsSpecialVCvt = Postfix.size() != 0 && Name.count("vcvt"); 943c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 944c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (InstName.compare("vtbl") == 0 || 945c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman InstName.compare("vtbx") == 0) { 946c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have a vtblN/vtbxN instruction, use the instruction's ASCII 947c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // encoding to get its true value. 948c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman TBNumber = Name[Name.size()-1] - 48; 949c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 950c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 951c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 952c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// GenerateRegisterCheckPatternsForLoadStores - Given a bunch of data we have 953c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// extracted, generate a FileCheck pattern for a Load Or Store 954c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic void 955c327f8705ecb8753555822d479f899bd2234386dMichael GottesmanGenerateRegisterCheckPatternForLoadStores(const StringRef &NameRef, 956c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string& OutTypeCode, 957c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &IsQuad, 958c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasDupPostfix, 959c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasLanePostfix, 960c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const size_t Count, 961c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string &RegisterSuffix) { 962c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsLDSTOne = NameRef.count("vld1") || NameRef.count("vst1"); 963c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If N == 3 || N == 4 and we are dealing with a quad instruction, Clang 964c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // will output a series of v{ld,st}1s, so we have to handle it specially. 965c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if ((Count == 3 || Count == 4) && IsQuad) { 966c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "{"; 967c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman for (size_t i = 0; i < Count; i++) { 968c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}"; 969c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasDupPostfix) { 970c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "[]"; 971c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 972c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasLanePostfix) { 973c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "[{{[0-9]+}}]"; 974c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 975c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (i < Count-1) { 976c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += ", "; 977c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 978c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 979c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "}"; 980c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else { 981c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 982c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Handle normal loads and stores. 983c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "{"; 984c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman for (size_t i = 0; i < Count; i++) { 985c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}"; 986c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasDupPostfix) { 987c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "[]"; 988c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 989c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasLanePostfix) { 990c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "[{{[0-9]+}}]"; 991c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 992c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (IsQuad && !HasLanePostfix) { 993c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += ", d{{[0-9]+}}"; 994c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasDupPostfix) { 995c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "[]"; 996c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 997c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 998c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (i < Count-1) { 999c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += ", "; 1000c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1001c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1002c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "}, [r{{[0-9]+}}"; 1003c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1004c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // We only include the alignment hint if we have a vld1.*64 or 1005c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // a dup/lane instruction. 1006c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (IsLDSTOne) { 1007c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if ((HasLanePostfix || HasDupPostfix) && OutTypeCode != "8") { 1008410c3f73cb0c78f72335dc712a9d887d77b8e7ceMichael Gottesman RegisterSuffix += ":" + OutTypeCode; 1009c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1010c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1011c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1012c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "]"; 1013c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1014c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1015c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1016c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic bool HasNPostfixAndScalarArgs(const StringRef &NameRef, 1017c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasNPostfix) { 1018c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return (NameRef.count("vmla") || 1019c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vmlal") || 1020c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vmlsl") || 1021c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vmull") || 1022c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmlal") || 1023c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmlsl") || 1024c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmulh") || 1025c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmull") || 1026c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqrdmulh")) && HasNPostfix; 1027c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1028c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1029c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic bool IsFiveOperandLaneAccumulator(const StringRef &NameRef, 1030c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasLanePostfix) { 1031c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return (NameRef.count("vmla") || 1032c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vmls") || 1033c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vmlal") || 1034c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vmlsl") || 1035c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman (NameRef.count("vmul") && NameRef.size() == 3)|| 1036c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmlal") || 1037c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmlsl") || 1038c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqdmulh") || 1039c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NameRef.count("vqrdmulh")) && HasLanePostfix; 1040c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1041c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1042c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic bool IsSpecialLaneMultiply(const StringRef &NameRef, 1043c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasLanePostfix, 1044c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &IsQuad) { 1045c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsVMulOrMulh = (NameRef.count("vmul") || NameRef.count("mulh")) 1046c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman && IsQuad; 1047c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsVMull = NameRef.count("mull") && !IsQuad; 1048c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return (IsVMulOrMulh || IsVMull) && HasLanePostfix; 1049c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1050c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1051c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic void NormalizeProtoForRegisterPatternCreation(const std::string &Name, 1052c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string &Proto, 1053c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasNPostfix, 1054c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &IsQuad, 1055c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasLanePostfix, 1056c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasDupPostfix, 1057c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string &NormedProto) { 1058c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Handle generic case. 1059c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const StringRef NameRef(Name); 1060c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman for (size_t i = 0, end = Proto.size(); i < end; i++) { 1061c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman switch (Proto[i]) { 1062c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'u': 1063c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'f': 1064c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'd': 1065c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 's': 1066c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'x': 1067c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 't': 1068c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'n': 1069c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += IsQuad? 'q' : 'd'; 1070c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1071c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'w': 1072c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'k': 1073c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += 'q'; 1074c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1075c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'g': 10760aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case 'j': 1077c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'h': 1078c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'e': 1079c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += 'd'; 1080c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1081c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'i': 1082c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += HasLanePostfix? 'a' : 'i'; 1083c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1084c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'a': 1085c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasLanePostfix) { 1086c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += 'a'; 1087c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (HasNPostfixAndScalarArgs(NameRef, HasNPostfix)) { 1088c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += IsQuad? 'q' : 'd'; 1089c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else { 1090c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto += 'i'; 1091c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1092c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1093c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1094c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1095c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1096c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Handle Special Cases. 1097c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsNotVExt = !NameRef.count("vext"); 1098c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsVPADAL = NameRef.count("vpadal"); 1099c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool Is5OpLaneAccum = IsFiveOperandLaneAccumulator(NameRef, 1100c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasLanePostfix); 1101c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsSpecialLaneMul = IsSpecialLaneMultiply(NameRef, HasLanePostfix, 1102c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman IsQuad); 1103c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1104c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (IsSpecialLaneMul) { 1105c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If 1106c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto[2] = NormedProto[3]; 1107c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto.erase(3); 1108c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (NormedProto.size() == 4 && 1109c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto[0] == NormedProto[1] && 1110c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman IsNotVExt) { 1111c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If NormedProto.size() == 4 and the first two proto characters are the 1112c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // same, ignore the first. 1113c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto = NormedProto.substr(1, 3); 1114c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (Is5OpLaneAccum) { 1115c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have a 5 op lane accumulator operation, we take characters 1,2,4 1116c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string tmp = NormedProto.substr(1,2); 1117c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman tmp += NormedProto[4]; 1118c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto = tmp; 1119c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (IsVPADAL) { 1120c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have VPADAL, ignore the first character. 1121c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto = NormedProto.substr(0, 2); 1122c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (NameRef.count("vdup") && NormedProto.size() > 2) { 1123c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If our instruction is a dup instruction, keep only the first and 1124c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // last characters. 1125c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string tmp = ""; 1126c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman tmp += NormedProto[0]; 1127c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman tmp += NormedProto[NormedProto.size()-1]; 1128c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormedProto = tmp; 1129c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1130c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1131c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1132c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// GenerateRegisterCheckPatterns - Given a bunch of data we have 1133c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// extracted, generate a FileCheck pattern to check that an 1134c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// instruction's arguments are correct. 1135c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic void GenerateRegisterCheckPattern(const std::string &Name, 1136c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string &Proto, 1137c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string &OutTypeCode, 1138c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasNPostfix, 1139c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &IsQuad, 1140c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasLanePostfix, 1141c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool &HasDupPostfix, 1142c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const size_t &TBNumber, 1143c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string &RegisterSuffix) { 1144c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1145c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix = ""; 1146c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1147c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const StringRef NameRef(Name); 1148c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const StringRef ProtoRef(Proto); 1149c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1150c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if ((NameRef.count("vdup") || NameRef.count("vmov")) && HasNPostfix) { 1151c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1152c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1153c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1154c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsLoadStore = NameRef.count("vld") || NameRef.count("vst"); 1155c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const bool IsTBXOrTBL = NameRef.count("vtbl") || NameRef.count("vtbx"); 1156c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1157c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (IsLoadStore) { 1158c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Grab N value from v{ld,st}N using its ascii representation. 1159c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const size_t Count = NameRef[3] - 48; 1160c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1161c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman GenerateRegisterCheckPatternForLoadStores(NameRef, OutTypeCode, IsQuad, 1162c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasDupPostfix, HasLanePostfix, 1163c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Count, RegisterSuffix); 1164c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (IsTBXOrTBL) { 1165c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}, {"; 1166c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman for (size_t i = 0; i < TBNumber-1; i++) { 1167c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}, "; 1168c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1169c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}}, d{{[0-9]+}}"; 1170c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else { 1171c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Handle a normal instruction. 1172c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (NameRef.count("vget") || NameRef.count("vset")) 1173c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1174c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1175c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // We first normalize our proto, since we only need to emit 4 1176c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // different types of checks, yet have more than 4 proto types 1177c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // that map onto those 4 patterns. 1178c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string NormalizedProto(""); 1179c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormalizeProtoForRegisterPatternCreation(Name, Proto, HasNPostfix, IsQuad, 1180c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasLanePostfix, HasDupPostfix, 1181c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman NormalizedProto); 1182c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1183c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman for (size_t i = 0, end = NormalizedProto.size(); i < end; i++) { 1184c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const char &c = NormalizedProto[i]; 1185c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman switch (c) { 1186c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'q': 1187c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "q{{[0-9]+}}, "; 1188c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1189c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1190c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'd': 1191c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}, "; 1192c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1193c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1194c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'i': 1195c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "#{{[0-9]+}}, "; 1196c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1197c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1198c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman case 'a': 1199c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix += "d{{[0-9]+}}[{{[0-9]}}], "; 1200c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman break; 1201c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1202c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1203c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1204c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Remove extra ", ". 1205c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix = RegisterSuffix.substr(0, RegisterSuffix.size()-2); 1206c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1207c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1208c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1209c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// GenerateChecksForIntrinsic - Given a specific instruction name + 1210c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// typestr + class kind, generate the proper set of FileCheck 1211c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// Patterns to check for. We could just return a string, but instead 1212c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// use a vector since it provides us with the extra flexibility of 1213c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// emitting multiple checks, which comes in handy for certain cases 1214c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman/// like mla where we want to check for 2 different instructions. 1215c327f8705ecb8753555822d479f899bd2234386dMichael Gottesmanstatic void GenerateChecksForIntrinsic(const std::string &Name, 1216c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string &Proto, 1217c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman StringRef &OutTypeStr, 1218c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman StringRef &InTypeStr, 1219c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman ClassKind Ck, 1220c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string &InstName, 1221c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool IsHiddenLOp, 1222c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::vector<std::string>& Result) { 1223c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1224c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If Ck is a ClassNoTest instruction, just return so no test is 1225c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // emitted. 1226c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if(Ck == ClassNoTest) 1227c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1228c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1229c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Name == "vcvt_f32_f16") { 1230c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("vcvt.f32.f16"); 1231c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1232c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1233c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1234c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1235c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Now we preprocess our instruction given the data we have to get the 1236c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // data that we need. 1237c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Create a StringRef for String Manipulation of our Name. 1238c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const StringRef NameRef(Name); 1239c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Instruction Prefix. 1240c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string Prefix; 1241c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // The type code for our out type string. 1242c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string OutTypeCode; 1243c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // To handle our different cases, we need to check for different postfixes. 1244c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Is our instruction a quad instruction. 1245c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool IsQuad = false; 1246c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Our instruction is of the form <instructionname>_n. 1247c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool HasNPostfix = false; 1248c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Our instruction is of the form <instructionname>_lane. 1249c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool HasLanePostfix = false; 1250c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Our instruction is of the form <instructionname>_dup. 1251c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool HasDupPostfix = false; 1252c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Our instruction is a vcvt instruction which requires special handling. 1253c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool IsSpecialVCvt = false; 1254c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have a vtbxN or vtblN instruction, this is set to N. 1255c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman size_t TBNumber = -1; 1256c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Register Suffix 1257c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::string RegisterSuffix; 1258c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1259c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman PreprocessInstruction(NameRef, InstName, Prefix, 1260c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasNPostfix, HasLanePostfix, HasDupPostfix, 1261c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman IsSpecialVCvt, TBNumber); 1262c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1263c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman InstructionTypeCode(OutTypeStr, Ck, IsQuad, OutTypeCode); 1264c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman GenerateRegisterCheckPattern(Name, Proto, OutTypeCode, HasNPostfix, IsQuad, 1265c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman HasLanePostfix, HasDupPostfix, TBNumber, 1266c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman RegisterSuffix); 1267c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1268c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // In the following section, we handle a bunch of special cases. You can tell 1269c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // a special case by the fact we are returning early. 1270c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1271c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If our instruction is a logical instruction without postfix or a 1272c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // hidden LOp just return the current Prefix. 1273c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Ck == ClassL || IsHiddenLOp) { 1274c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back(Prefix + " " + RegisterSuffix); 1275c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1276c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1277c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1278c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have a vmov, due to the many different cases, some of which 1279c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // vary within the different intrinsics generated for a single 1280c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // instruction type, just output a vmov. (e.g. given an instruction 1281c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // A, A.u32 might be vmov and A.u8 might be vmov.8). 1282c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // 1283c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // FIXME: Maybe something can be done about this. The two cases that we care 1284c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // about are vmov as an LType and vmov as a WType. 1285c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Prefix == "vmov") { 1286c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back(Prefix + " " + RegisterSuffix); 1287c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1288c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1289c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1290c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // In the following section, we handle special cases. 1291c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1292c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (OutTypeCode == "64") { 1293c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have a 64 bit vdup/vext and are handling an uint64x1_t 1294c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // type, the intrinsic will be optimized away, so just return 1295c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // nothing. On the other hand if we are handling an uint64x2_t 1296c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // (i.e. quad instruction), vdup/vmov instructions should be 1297c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // emitted. 1298c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Prefix == "vdup" || Prefix == "vext") { 1299c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (IsQuad) { 1300c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("{{vmov|vdup}}"); 1301c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1302c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1303c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1304c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1305c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // v{st,ld}{2,3,4}_{u,s}64 emit v{st,ld}1.64 instructions with 1306c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // multiple register operands. 1307c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool MultiLoadPrefix = Prefix == "vld2" || Prefix == "vld3" 1308c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman || Prefix == "vld4"; 1309c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman bool MultiStorePrefix = Prefix == "vst2" || Prefix == "vst3" 1310c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman || Prefix == "vst4"; 1311c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (MultiLoadPrefix || MultiStorePrefix) { 1312c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back(NameRef.slice(0, 3).str() + "1.64"); 1313c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1314c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1315c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1316c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // v{st,ld}1_{lane,dup}_{u64,s64} use vldr/vstr/vmov/str instead of 1317c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // emitting said instructions. So return a check for 1318c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // vldr/vstr/vmov/str instead. 1319c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (HasLanePostfix || HasDupPostfix) { 1320c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Prefix == "vst1") { 1321c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("{{str|vstr|vmov}}"); 1322c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1323c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (Prefix == "vld1") { 1324c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("{{ldr|vldr|vmov}}"); 1325c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1326c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1327c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1328c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1329c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1330c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // vzip.32/vuzp.32 are the same instruction as vtrn.32 and are 1331c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // sometimes disassembled as vtrn.32. We use a regex to handle both 1332c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // cases. 1333c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if ((Prefix == "vzip" || Prefix == "vuzp") && OutTypeCode == "32") { 1334c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("{{vtrn|" + Prefix + "}}.32 " + RegisterSuffix); 1335c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1336c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1337c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1338c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Currently on most ARM processors, we do not use vmla/vmls for 1339c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // quad floating point operations. Instead we output vmul + vadd. So 1340c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // check if we have one of those instructions and just output a 1341c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // check for vmul. 1342c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (OutTypeCode == "f32") { 1343c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Prefix == "vmls") { 1344c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix); 1345c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("vsub." + OutTypeCode); 1346c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1347c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } else if (Prefix == "vmla") { 1348c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("vmul." + OutTypeCode + " " + RegisterSuffix); 1349c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back("vadd." + OutTypeCode); 1350c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman return; 1351c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1352c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1353c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1354c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If we have vcvt, get the input type from the instruction name 1355c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // (which should be of the form instname_inputtype) and append it 1356c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // before the output type. 1357c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (Prefix == "vcvt") { 1358c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman const std::string inTypeCode = NameRef.substr(NameRef.find_last_of("_")+1); 1359c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Prefix += "." + inTypeCode; 1360c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 1361c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1362c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // Append output type code to get our final mangled instruction. 1363c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Prefix += "." + OutTypeCode; 1364c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 1365c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman Result.push_back(Prefix + " " + RegisterSuffix); 1366c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman} 1367c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 136851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// UseMacro - Examine the prototype string to determine if the intrinsic 136951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// should be defined as a preprocessor macro instead of an inline function. 137051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic bool UseMacro(const std::string &proto) { 137151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If this builtin takes an immediate argument, we need to #define it rather 137251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // than use a standard declaration, so that SemaChecking can range check 137351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // the immediate passed by the user. 137451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto.find('i') != std::string::npos) 137551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return true; 137651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 137751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Pointer arguments need to use macros to avoid hiding aligned attributes 137851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // from the pointer type. 137951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto.find('p') != std::string::npos || 138051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne proto.find('c') != std::string::npos) 138151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return true; 138251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 138351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return false; 138451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 138551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 138651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// MacroArgUsedDirectly - Return true if argument i for an intrinsic that is 138751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// defined as a macro should be accessed directly instead of being first 138851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// assigned to a local temporary. 138951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic bool MacroArgUsedDirectly(const std::string &proto, unsigned i) { 139051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // True for constant ints (i), pointers (p) and const pointers (c). 139151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return (proto[i] == 'i' || proto[i] == 'p' || proto[i] == 'c'); 139251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 139351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 139451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Generate the string "(argtype a, argtype b, ...)" 13952102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qinstatic std::string GenArgs(const std::string &proto, StringRef typestr, 13962102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin const std::string &name) { 139751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool define = UseMacro(proto); 139851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char arg = 'a'; 139951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 140051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 140151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "("; 140251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 140351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { 140451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (define) { 140551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Some macro arguments are used directly instead of being assigned 140651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // to local temporaries; prepend an underscore prefix to make their 140751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // names consistent with the local temporaries. 140851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (MacroArgUsedDirectly(proto, i)) 140951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__"; 141051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 141151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += TypeString(proto[i], typestr) + " __"; 141251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 141351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back(arg); 14142102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin //To avoid argument being multiple defined, add extra number for renaming. 141522229d6822324a42913d25f256045dbf348a53e9Kevin Qin if (name == "vcopy_lane" || name == "vcopy_laneq") 14162102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin s.push_back('1'); 141751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((i + 1) < e) 141851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", "; 141951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 142051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 142151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ")"; 142251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 142351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 142451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 142551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Macro arguments are not type-checked like inline function arguments, so 142651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// assign them to local temporaries to get the right type checking. 14272102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qinstatic std::string GenMacroLocals(const std::string &proto, StringRef typestr, 14282102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin const std::string &name ) { 142951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char arg = 'a'; 143051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 143151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool generatedLocal = false; 143251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 143351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { 143451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Do not create a temporary for an immediate argument. 143551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // That would defeat the whole point of using a macro! 143651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (MacroArgUsedDirectly(proto, i)) 143751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 143851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne generatedLocal = true; 14392102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin bool extranumber = false; 144022229d6822324a42913d25f256045dbf348a53e9Kevin Qin if (name == "vcopy_lane" || name == "vcopy_laneq") 14412102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin extranumber = true; 144251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 144351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += TypeString(proto[i], typestr) + " __"; 144451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back(arg); 14452102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin if(extranumber) 14462102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin s.push_back('1'); 144751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " = ("; 144851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back(arg); 14492102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin if(extranumber) 14502102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin s.push_back('1'); 145151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "); "; 145251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 145351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 145451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (generatedLocal) 145551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "\\\n "; 145651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 145751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 145851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 145951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Use the vmovl builtin to sign-extend or zero-extend a vector. 1460097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liustatic std::string Extend(StringRef typestr, const std::string &a, bool h=0) { 1461097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string s, high; 1462097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu high = h ? "_high" : ""; 1463097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s = MangleName("vmovl" + high, typestr, ClassS); 1464097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "(" + a + ")"; 1465097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return s; 1466097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu} 1467097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 1468097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu// Get the high 64-bit part of a vector 1469097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liustatic std::string GetHigh(const std::string &a, StringRef typestr) { 147051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 1471097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s = MangleName("vget_high", typestr, ClassS); 147251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + a + ")"; 147351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 147451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 147551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 1476097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu// Gen operation with two operands and get high 64-bit for both of two operands. 1477097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liustatic std::string Gen2OpWith2High(StringRef typestr, 1478097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &op, 1479097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &a, 1480097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &b) { 1481097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string s; 1482097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string Op1 = GetHigh(a, typestr); 1483097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string Op2 = GetHigh(b, typestr); 1484097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s = MangleName(op, typestr, ClassS); 1485097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "(" + Op1 + ", " + Op2 + ");"; 1486097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return s; 1487097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu} 1488097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 1489097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu// Gen operation with three operands and get high 64-bit of the latter 1490097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu// two operands. 1491097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liustatic std::string Gen3OpWith2High(StringRef typestr, 1492097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &op, 1493097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &a, 1494097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &b, 1495097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &c) { 1496097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string s; 1497097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string Op1 = GetHigh(b, typestr); 1498097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string Op2 = GetHigh(c, typestr); 1499097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s = MangleName(op, typestr, ClassS); 1500097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "(" + a + ", " + Op1 + ", " + Op2 + ");"; 1501097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return s; 1502097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu} 1503097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 1504097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu// Gen combine operation by putting a on low 64-bit, and b on high 64-bit. 1505097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liustatic std::string GenCombine(std::string typestr, 1506097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &a, 1507097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu const std::string &b) { 1508097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string s; 1509097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s = MangleName("vcombine", typestr, ClassS); 1510097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "(" + a + ", " + b + ")"; 1511097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu return s; 1512097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu} 1513097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 151451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string Duplicate(unsigned nElts, StringRef typestr, 151551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::string &a) { 151651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 151751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 151851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s = "(" + TypeString('d', typestr) + "){ "; 151951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0; i != nElts; ++i) { 152051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += a; 152151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((i + 1) < nElts) 152251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", "; 152351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 152451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " }"; 152551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 152651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 152751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 152851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 152951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string SplatLane(unsigned nElts, const std::string &vec, 153051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::string &lane) { 153151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s = "__builtin_shufflevector(" + vec + ", " + vec; 153251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0; i < nElts; ++i) 153351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", " + lane; 153451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ")"; 153551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 153651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 153751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 1538912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liustatic std::string RemoveHigh(const std::string &name) { 1539912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu std::string s = name; 1540912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu std::size_t found = s.find("_high_"); 1541912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu if (found == std::string::npos) 1542912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu PrintFatalError("name should contain \"_high_\" for high intrinsics"); 1543912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s.replace(found, 5, ""); 1544912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu return s; 1545912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu} 1546912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu 154751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic unsigned GetNumElements(StringRef typestr, bool &quad) { 154851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne quad = false; 154951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool dummy = false; 155051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char type = ClassifyType(typestr, quad, dummy, dummy); 155151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned nElts = 0; 155251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (type) { 155351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': nElts = 8; break; 155451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': nElts = 4; break; 155551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': nElts = 2; break; 155651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': nElts = 1; break; 155751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': nElts = 4; break; 155851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': nElts = 2; break; 1559b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case 'd': 1560b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover nElts = 1; 1561b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 156251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 156338859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type!"); 156451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 156551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (quad) nElts <<= 1; 156651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return nElts; 156751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 156851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 156951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd. 1570912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liustatic std::string GenOpString(const std::string &name, OpKind op, 1571912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu const std::string &proto, StringRef typestr) { 157251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool quad; 157351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned nElts = GetNumElements(typestr, quad); 157451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool define = UseMacro(proto); 157551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 157651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string ts = TypeString(proto[0], typestr); 157751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 157851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (!define) { 157951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s = "return "; 158051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 158151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 158251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch(op) { 158351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAdd: 158451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + __b;"; 158551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 158651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAddl: 158751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += Extend(typestr, "__a") + " + " + Extend(typestr, "__b") + ";"; 158851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1589097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpAddlHi: 1590097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Extend(typestr, "__a", 1) + " + " + Extend(typestr, "__b", 1) + ";"; 1591097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 159251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAddw: 159351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + " + Extend(typestr, "__b") + ";"; 159451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1595097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpAddwHi: 1596097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "__a + " + Extend(typestr, "__b", 1) + ";"; 1597097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 159851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpSub: 159951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - __b;"; 160051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 160151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpSubl: 160251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += Extend(typestr, "__a") + " - " + Extend(typestr, "__b") + ";"; 160351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1604097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpSublHi: 1605097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Extend(typestr, "__a", 1) + " - " + Extend(typestr, "__b", 1) + ";"; 1606097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 160751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpSubw: 160851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - " + Extend(typestr, "__b") + ";"; 160951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1610097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpSubwHi: 1611097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "__a - " + Extend(typestr, "__b", 1) + ";"; 1612097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 161351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMulN: 161451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a * " + Duplicate(nElts, typestr, "__b") + ";"; 161551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 161651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMulLane: 161751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a * " + SplatLane(nElts, "__b", "__c") + ";"; 161851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 16190aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpMulXLane: 16200aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vmulx", typestr, ClassS) + "(__a, " + 16210aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu SplatLane(nElts, "__b", "__c") + ");"; 16220aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 162351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMul: 162451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a * __b;"; 162551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 162651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMullLane: 162751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName("vmull", typestr, ClassS) + "(__a, " + 162851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__b", "__c") + ");"; 162951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 16300aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpMullHiLane: 16310aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vmull", typestr, ClassS) + "(" + 16320aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");"; 16330aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 163451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlaN: 163551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");"; 163651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 163751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlaLane: 163851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");"; 163951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 164051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMla: 164151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + (__b * __c);"; 164251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 164351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlalN: 164451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + 164551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Duplicate(nElts, typestr, "__c") + ");"; 164651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 164751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlalLane: 164851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, " + 164951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__c", "__d") + ");"; 165051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 16510aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpMlalHiLane: 16520aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += "__a + " + MangleName("vmull", typestr, ClassS) + "(" + 16530aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");"; 16540aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 165551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlal: 165651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; 165751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1658097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpMullHi: 1659097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen2OpWith2High(typestr, "vmull", "__a", "__b"); 1660097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1661097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpMlalHi: 1662097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen3OpWith2High(typestr, "vmlal", "__a", "__b", "__c"); 1663097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 166451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlsN: 166551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");"; 166651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 166751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlsLane: 166851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");"; 166951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 16700aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpFMSLane: 16710aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n "; 16720aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n "; 16730aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n "; 16740aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vfma_lane", typestr, ClassS) + "(__a1, __b1, -__c1, __d);"; 16750aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 16760aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpFMSLaneQ: 16770aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n "; 16780aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n "; 16790aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n "; 16800aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vfma_laneq", typestr, ClassS) + "(__a1, __b1, -__c1, __d);"; 16810aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 168251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMls: 168351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - (__b * __c);"; 168451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 168551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlslN: 168651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + 168751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Duplicate(nElts, typestr, "__c") + ");"; 168851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 168951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlslLane: 169051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, " + 169151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__c", "__d") + ");"; 169251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 16930aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpMlslHiLane: 16940aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += "__a - " + MangleName("vmull", typestr, ClassS) + "(" + 16950aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");"; 16960aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 169751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpMlsl: 169851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a - " + MangleName("vmull", typestr, ClassS) + "(__b, __c);"; 169951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1700097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpMlslHi: 1701097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen3OpWith2High(typestr, "vmlsl", "__a", "__b", "__c"); 1702097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 170351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpQDMullLane: 170451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName("vqdmull", typestr, ClassS) + "(__a, " + 170551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__b", "__c") + ");"; 170651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 17070aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpQDMullHiLane: 17080aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vqdmull", typestr, ClassS) + "(" + 17090aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu GetHigh("__a", typestr) + ", " + SplatLane(nElts, "__b", "__c") + ");"; 17100aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 171151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpQDMlalLane: 171251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName("vqdmlal", typestr, ClassS) + "(__a, __b, " + 171351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__c", "__d") + ");"; 171451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 17150aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpQDMlalHiLane: 17160aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vqdmlal", typestr, ClassS) + "(__a, " + 17170aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");"; 17180aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 171951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpQDMlslLane: 172051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, __b, " + 172151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__c", "__d") + ");"; 172251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 17230aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case OpQDMlslHiLane: 17240aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu s += MangleName("vqdmlsl", typestr, ClassS) + "(__a, " + 17250aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu GetHigh("__b", typestr) + ", " + SplatLane(nElts, "__c", "__d") + ");"; 17260aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu break; 172751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpQDMulhLane: 172851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " + 172951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__b", "__c") + ");"; 173051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 173151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpQRDMulhLane: 173251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " + 173351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SplatLane(nElts, "__b", "__c") + ");"; 173451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 173551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpEq: 173651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")(__a == __b);"; 173751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 173851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpGe: 173951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")(__a >= __b);"; 174051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 174151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpLe: 174251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")(__a <= __b);"; 174351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 174451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpGt: 174551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")(__a > __b);"; 174651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 174751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpLt: 174851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")(__a < __b);"; 174951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 175051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpNeg: 175151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " -__a;"; 175251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 175351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpNot: 175451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " ~__a;"; 175551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 175651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAnd: 175751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a & __b;"; 175851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 175951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpOr: 176051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a | __b;"; 176151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 176251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpXor: 176351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a ^ __b;"; 176451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 176551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAndNot: 176651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a & ~__b;"; 176751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 176851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpOrNot: 176951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a | ~__b;"; 177051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 177151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpCast: 177251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")__a;"; 177351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 177451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpConcat: 177551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")__builtin_shufflevector((int64x1_t)__a"; 177651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", (int64x1_t)__b, 0, 1);"; 177751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 177851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpHi: 1779cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach // nElts is for the result vector, so the source is twice that number. 1780cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach s += "__builtin_shufflevector(__a, __a"; 1781cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach for (unsigned i = nElts; i < nElts * 2; ++i) 1782cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach s += ", " + utostr(i); 1783cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach s+= ");"; 178451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 178551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpLo: 1786cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach s += "__builtin_shufflevector(__a, __a"; 1787cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach for (unsigned i = 0; i < nElts; ++i) 1788cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach s += ", " + utostr(i); 1789cd76539274cdc3907a61de28ba81a9e90f270a41Jim Grosbach s+= ");"; 179051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 179151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpDup: 179251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += Duplicate(nElts, typestr, "__a") + ";"; 179351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 179451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpDupLane: 179551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += SplatLane(nElts, "__a", "__b") + ";"; 179651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 179751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpSelect: 179851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // ((0 & 1) | (~0 & 2)) 179951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")"; 180051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ts = TypeString(proto[1], typestr); 180151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "((__a & (" + ts + ")__b) | "; 180251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(~__a & (" + ts + ")__c));"; 180351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 180451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpRev16: 180551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__builtin_shufflevector(__a, __a"; 180651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 2; i <= nElts; i += 2) 180751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned j = 0; j != 2; ++j) 180851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", " + utostr(i - j - 1); 180951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ");"; 181051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 181151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpRev32: { 181251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned WordElts = nElts >> (1 + (int)quad); 181351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__builtin_shufflevector(__a, __a"; 181451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = WordElts; i <= nElts; i += WordElts) 181551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned j = 0; j != WordElts; ++j) 181651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", " + utostr(i - j - 1); 181751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ");"; 181851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 181951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 182051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpRev64: { 182151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned DblWordElts = nElts >> (int)quad; 182251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__builtin_shufflevector(__a, __a"; 182351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = DblWordElts; i <= nElts; i += DblWordElts) 182451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned j = 0; j != DblWordElts; ++j) 182551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", " + utostr(i - j - 1); 182651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ");"; 182751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 182851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 18298137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case OpXtnHi: { 18308137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s = TypeString(proto[1], typestr) + " __a1 = " + 18318137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin MangleName("vmovn", typestr, ClassS) + "(__b);\n " + 18328137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin "return __builtin_shufflevector(__a, __a1"; 18338137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin for (unsigned i = 0; i < nElts * 4; ++i) 18348137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ", " + utostr(i); 18358137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ");"; 18368137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin break; 18378137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin } 18388137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case OpSqxtunHi: { 18398137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s = TypeString(proto[1], typestr) + " __a1 = " + 18408137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin MangleName("vqmovun", typestr, ClassS) + "(__b);\n " + 18418137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin "return __builtin_shufflevector(__a, __a1"; 18428137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin for (unsigned i = 0; i < nElts * 4; ++i) 18438137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ", " + utostr(i); 18448137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ");"; 18458137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin break; 18468137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin } 18478137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case OpQxtnHi: { 18488137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s = TypeString(proto[1], typestr) + " __a1 = " + 18498137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin MangleName("vqmovn", typestr, ClassS) + "(__b);\n " + 18508137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin "return __builtin_shufflevector(__a, __a1"; 18518137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin for (unsigned i = 0; i < nElts * 4; ++i) 18528137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ", " + utostr(i); 18538137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ");"; 18548137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin break; 18558137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin } 18568137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case OpFcvtnHi: { 18578137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin std::string FName = (nElts == 1) ? "vcvt_f32" : "vcvt_f16"; 18588137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s = TypeString(proto[1], typestr) + " __a1 = " + 18598137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin MangleName(FName, typestr, ClassS) + "(__b);\n " + 18608137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin "return __builtin_shufflevector(__a, __a1"; 18618137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin for (unsigned i = 0; i < nElts * 4; ++i) 18628137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ", " + utostr(i); 18638137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ");"; 18648137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin break; 18658137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin } 18668137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case OpFcvtlHi: { 18678137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin std::string FName = (nElts == 2) ? "vcvt_f64" : "vcvt_f32"; 18688137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s = TypeString('d', typestr) + " __a1 = " + GetHigh("__a", typestr) + 18698137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin ";\n return " + MangleName(FName, typestr, ClassS) + "(__a1);"; 18708137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin break; 18718137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin } 18728137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin case OpFcvtxnHi: { 18738137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s = TypeString(proto[1], typestr) + " __a1 = " + 18748137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin MangleName("vcvtx_f32", typestr, ClassS) + "(__b);\n " + 18758137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin "return __builtin_shufflevector(__a, __a1"; 18768137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin for (unsigned i = 0; i < nElts * 4; ++i) 18778137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ", " + utostr(i); 18788137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin s += ");"; 18798137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin break; 18808137a607eebe799d95fd05226fb91119a5b054b0Kevin Qin } 1881bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu case OpUzp1: 1882bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += "__builtin_shufflevector(__a, __b"; 1883bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu for (unsigned i = 0; i < nElts; i++) 1884bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ", " + utostr(2*i); 1885bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ");"; 1886bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu break; 1887bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu case OpUzp2: 1888bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += "__builtin_shufflevector(__a, __b"; 1889bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu for (unsigned i = 0; i < nElts; i++) 1890bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ", " + utostr(2*i+1); 1891bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ");"; 1892bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu break; 1893bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu case OpZip1: 1894bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += "__builtin_shufflevector(__a, __b"; 1895bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu for (unsigned i = 0; i < (nElts/2); i++) 1896bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ", " + utostr(i) + ", " + utostr(i+nElts); 1897bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ");"; 1898bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu break; 1899bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu case OpZip2: 1900bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += "__builtin_shufflevector(__a, __b"; 1901bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu for (unsigned i = nElts/2; i < nElts; i++) 1902bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ", " + utostr(i) + ", " + utostr(i+nElts); 1903bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ");"; 1904bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu break; 1905bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu case OpTrn1: 1906bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += "__builtin_shufflevector(__a, __b"; 1907bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu for (unsigned i = 0; i < (nElts/2); i++) 1908bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ", " + utostr(2*i) + ", " + utostr(2*i+nElts); 1909bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ");"; 1910bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu break; 1911bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu case OpTrn2: 1912bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += "__builtin_shufflevector(__a, __b"; 1913bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu for (unsigned i = 0; i < (nElts/2); i++) 1914bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ", " + utostr(2*i+1) + ", " + utostr(2*i+1+nElts); 1915bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu s += ");"; 1916bf3bc5d37eff88b578d5990f507a87db33f30a6eJiangning Liu break; 191751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAbdl: { 191851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string abd = MangleName("vabd", typestr, ClassS) + "(__a, __b)"; 191951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (typestr[0] != 'U') { 192051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // vabd results are always unsigned and must be zero-extended. 192151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string utype = "U" + typestr.str(); 192251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + TypeString(proto[0], typestr) + ")"; 192351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne abd = "(" + TypeString('d', utype) + ")" + abd; 192451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += Extend(utype, abd) + ";"; 192551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 192651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += Extend(typestr, abd) + ";"; 192751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 192851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 192951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 1930097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpAbdlHi: 1931097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen2OpWith2High(typestr, "vabdl", "__a", "__b"); 1932097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1933097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpAddhnHi: { 1934097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string addhn = MangleName("vaddhn", typestr, ClassS) + "(__b, __c)"; 1935097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += GenCombine(GetNarrowTypestr(typestr), "__a", addhn); 1936097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += ";"; 1937097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1938097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu } 1939097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpRAddhnHi: { 1940097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string raddhn = MangleName("vraddhn", typestr, ClassS) + "(__b, __c)"; 1941097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += GenCombine(GetNarrowTypestr(typestr), "__a", raddhn); 1942097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += ";"; 1943097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1944097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu } 1945097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpSubhnHi: { 1946097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string subhn = MangleName("vsubhn", typestr, ClassS) + "(__b, __c)"; 1947097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += GenCombine(GetNarrowTypestr(typestr), "__a", subhn); 1948097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += ";"; 1949097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1950097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu } 1951097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpRSubhnHi: { 1952097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu std::string rsubhn = MangleName("vrsubhn", typestr, ClassS) + "(__b, __c)"; 1953097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += GenCombine(GetNarrowTypestr(typestr), "__a", rsubhn); 1954097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += ";"; 1955097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1956097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu } 195751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case OpAba: 195851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__a + " + MangleName("vabd", typestr, ClassS) + "(__b, __c);"; 195951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1960097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpAbal: 1961097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += "__a + " + MangleName("vabdl", typestr, ClassS) + "(__b, __c);"; 1962097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1963097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpAbalHi: 1964097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen3OpWith2High(typestr, "vabal", "__a", "__b", "__c"); 1965097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1966097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpQDMullHi: 1967097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen2OpWith2High(typestr, "vqdmull", "__a", "__b"); 1968097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1969097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpQDMlalHi: 1970097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen3OpWith2High(typestr, "vqdmlal", "__a", "__b", "__c"); 1971097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu break; 1972097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu case OpQDMlslHi: 1973097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu s += Gen3OpWith2High(typestr, "vqdmlsl", "__a", "__b", "__c"); 197451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 1975b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case OpDiv: 1976b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s += "__a / __b;"; 1977b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 1978912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case OpMovlHi: { 1979912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s = TypeString(proto[1], typestr.drop_front()) + " __a1 = " + 1980912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu MangleName("vget_high", typestr, ClassS) + "(__a);\n " + s; 1981912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s += "(" + ts + ")" + MangleName("vshll_n", typestr, ClassS); 1982912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s += "(__a1, 0);"; 1983912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu break; 1984912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 1985912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case OpLongHi: { 1986912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu // Another local variable __a1 is needed for calling a Macro, 1987912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu // or using __a will have naming conflict when Macro expanding. 1988912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s += TypeString(proto[1], typestr.drop_front()) + " __a1 = " + 1989912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu MangleName("vget_high", typestr, ClassS) + "(__a); \\\n"; 1990912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s += " (" + ts + ")" + MangleName(RemoveHigh(name), typestr, ClassS) + 1991912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu "(__a1, __b);"; 1992912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu break; 1993912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 1994912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu case OpNarrowHi: { 1995912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s += "(" + ts + ")" + MangleName("vcombine", typestr, ClassS) + "(__a, " + 1996912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu MangleName(RemoveHigh(name), typestr, ClassS) + "(__b, __c));"; 1997912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu break; 1998912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu } 199922229d6822324a42913d25f256045dbf348a53e9Kevin Qin case OpCopyLane: { 20002102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin s += TypeString('s', typestr) + " __c2 = " + 20012102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin MangleName("vget_lane", typestr, ClassS) + "(__c1, __d1); \\\n " + 20022102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin MangleName("vset_lane", typestr, ClassS) + "(__c2, __a1, __b1);"; 20032102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin break; 20042102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin } 200522229d6822324a42913d25f256045dbf348a53e9Kevin Qin case OpCopyQLane: { 200622229d6822324a42913d25f256045dbf348a53e9Kevin Qin std::string typeCode = ""; 200722229d6822324a42913d25f256045dbf348a53e9Kevin Qin InstructionTypeCode(typestr, ClassS, quad, typeCode); 200822229d6822324a42913d25f256045dbf348a53e9Kevin Qin s += TypeString('s', typestr) + " __c2 = vget_lane_" + typeCode + 200922229d6822324a42913d25f256045dbf348a53e9Kevin Qin "(__c1, __d1); \\\n vsetq_lane_" + typeCode + "(__c2, __a1, __b1);"; 201022229d6822324a42913d25f256045dbf348a53e9Kevin Qin break; 201122229d6822324a42913d25f256045dbf348a53e9Kevin Qin } 201222229d6822324a42913d25f256045dbf348a53e9Kevin Qin case OpCopyLaneQ: { 201322229d6822324a42913d25f256045dbf348a53e9Kevin Qin std::string typeCode = ""; 201422229d6822324a42913d25f256045dbf348a53e9Kevin Qin InstructionTypeCode(typestr, ClassS, quad, typeCode); 201522229d6822324a42913d25f256045dbf348a53e9Kevin Qin s += TypeString('s', typestr) + " __c2 = vgetq_lane_" + typeCode + 201622229d6822324a42913d25f256045dbf348a53e9Kevin Qin "(__c1, __d1); \\\n vset_lane_" + typeCode + "(__c2, __a1, __b1);"; 201722229d6822324a42913d25f256045dbf348a53e9Kevin Qin break; 201822229d6822324a42913d25f256045dbf348a53e9Kevin Qin } 201951cc0172a173599b769968696e20638754d1dcd6Ana Pazos case OpScalarMulLane: { 202051cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string typeCode = ""; 202151cc0172a173599b769968696e20638754d1dcd6Ana Pazos InstructionTypeCode(typestr, ClassS, quad, typeCode); 202251cc0172a173599b769968696e20638754d1dcd6Ana Pazos s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode + 202351cc0172a173599b769968696e20638754d1dcd6Ana Pazos "(__b, __c);\\\n __a * __d1;"; 202451cc0172a173599b769968696e20638754d1dcd6Ana Pazos break; 202551cc0172a173599b769968696e20638754d1dcd6Ana Pazos } 202651cc0172a173599b769968696e20638754d1dcd6Ana Pazos case OpScalarMulLaneQ: { 202751cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string typeCode = ""; 202851cc0172a173599b769968696e20638754d1dcd6Ana Pazos InstructionTypeCode(typestr, ClassS, quad, typeCode); 202951cc0172a173599b769968696e20638754d1dcd6Ana Pazos s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + typeCode + 203051cc0172a173599b769968696e20638754d1dcd6Ana Pazos "(__b, __c);\\\n __a * __d1;"; 203151cc0172a173599b769968696e20638754d1dcd6Ana Pazos break; 203251cc0172a173599b769968696e20638754d1dcd6Ana Pazos } 203351cc0172a173599b769968696e20638754d1dcd6Ana Pazos case OpScalarMulXLane: { 203451cc0172a173599b769968696e20638754d1dcd6Ana Pazos bool dummy = false; 203551cc0172a173599b769968696e20638754d1dcd6Ana Pazos char type = ClassifyType(typestr, dummy, dummy, dummy); 203651cc0172a173599b769968696e20638754d1dcd6Ana Pazos if (type == 'f') type = 's'; 203751cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string typeCode = ""; 203851cc0172a173599b769968696e20638754d1dcd6Ana Pazos InstructionTypeCode(typestr, ClassS, quad, typeCode); 203951cc0172a173599b769968696e20638754d1dcd6Ana Pazos s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode + 204051cc0172a173599b769968696e20638754d1dcd6Ana Pazos "(__b, __c);\\\n vmulx" + type + "_" + 204151cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__a, __d1);"; 204251cc0172a173599b769968696e20638754d1dcd6Ana Pazos break; 204351cc0172a173599b769968696e20638754d1dcd6Ana Pazos } 204451cc0172a173599b769968696e20638754d1dcd6Ana Pazos case OpScalarMulXLaneQ: { 204551cc0172a173599b769968696e20638754d1dcd6Ana Pazos bool dummy = false; 204651cc0172a173599b769968696e20638754d1dcd6Ana Pazos char type = ClassifyType(typestr, dummy, dummy, dummy); 204751cc0172a173599b769968696e20638754d1dcd6Ana Pazos if (type == 'f') type = 's'; 204851cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string typeCode = ""; 204951cc0172a173599b769968696e20638754d1dcd6Ana Pazos InstructionTypeCode(typestr, ClassS, quad, typeCode); 205051cc0172a173599b769968696e20638754d1dcd6Ana Pazos s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + 205151cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__b, __c);\\\n vmulx" + type + 205251cc0172a173599b769968696e20638754d1dcd6Ana Pazos "_" + typeCode + "(__a, __d1);"; 205351cc0172a173599b769968696e20638754d1dcd6Ana Pazos break; 205451cc0172a173599b769968696e20638754d1dcd6Ana Pazos } 205551cc0172a173599b769968696e20638754d1dcd6Ana Pazos 205651cc0172a173599b769968696e20638754d1dcd6Ana Pazos case OpScalarVMulXLane: { 205751cc0172a173599b769968696e20638754d1dcd6Ana Pazos bool dummy = false; 205851cc0172a173599b769968696e20638754d1dcd6Ana Pazos char type = ClassifyType(typestr, dummy, dummy, dummy); 205951cc0172a173599b769968696e20638754d1dcd6Ana Pazos if (type == 'f') type = 's'; 206051cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string typeCode = ""; 206151cc0172a173599b769968696e20638754d1dcd6Ana Pazos InstructionTypeCode(typestr, ClassS, quad, typeCode); 206251cc0172a173599b769968696e20638754d1dcd6Ana Pazos s += TypeString('s', typestr) + " __d1 = vget_lane_" + 206351cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__a, 0);\\\n" + 206451cc0172a173599b769968696e20638754d1dcd6Ana Pazos " " + TypeString('s', typestr) + " __e1 = vget_lane_" + 206551cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__b, __c);\\\n" + 206651cc0172a173599b769968696e20638754d1dcd6Ana Pazos " " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" + 206751cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__d1, __e1);\\\n" + 206851cc0172a173599b769968696e20638754d1dcd6Ana Pazos " " + TypeString('d', typestr) + " __g1;\\\n" + 206951cc0172a173599b769968696e20638754d1dcd6Ana Pazos " vset_lane_" + typeCode + "(__f1, __g1, __c);"; 207051cc0172a173599b769968696e20638754d1dcd6Ana Pazos break; 207151cc0172a173599b769968696e20638754d1dcd6Ana Pazos } 207251cc0172a173599b769968696e20638754d1dcd6Ana Pazos 207351cc0172a173599b769968696e20638754d1dcd6Ana Pazos case OpScalarVMulXLaneQ: { 207451cc0172a173599b769968696e20638754d1dcd6Ana Pazos bool dummy = false; 207551cc0172a173599b769968696e20638754d1dcd6Ana Pazos char type = ClassifyType(typestr, dummy, dummy, dummy); 207651cc0172a173599b769968696e20638754d1dcd6Ana Pazos if (type == 'f') type = 's'; 207751cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string typeCode = ""; 207851cc0172a173599b769968696e20638754d1dcd6Ana Pazos InstructionTypeCode(typestr, ClassS, quad, typeCode); 207951cc0172a173599b769968696e20638754d1dcd6Ana Pazos s += TypeString('s', typestr) + " __d1 = vget_lane_" + 208051cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__a, 0);\\\n" + 208151cc0172a173599b769968696e20638754d1dcd6Ana Pazos " " + TypeString('s', typestr) + " __e1 = vgetq_lane_" + 208251cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__b, __c);\\\n" + 208351cc0172a173599b769968696e20638754d1dcd6Ana Pazos " " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" + 208451cc0172a173599b769968696e20638754d1dcd6Ana Pazos typeCode + "(__d1, __e1);\\\n" + 208551cc0172a173599b769968696e20638754d1dcd6Ana Pazos " " + TypeString('d', typestr) + " __g1;\\\n" + 208651cc0172a173599b769968696e20638754d1dcd6Ana Pazos " vset_lane_" + typeCode + "(__f1, __g1, 0);"; 208751cc0172a173599b769968696e20638754d1dcd6Ana Pazos break; 208851cc0172a173599b769968696e20638754d1dcd6Ana Pazos } 208951cc0172a173599b769968696e20638754d1dcd6Ana Pazos 209051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 209138859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unknown OpKind!"); 209251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 209351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 209451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 209551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 209651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic unsigned GetNeonEnum(const std::string &proto, StringRef typestr) { 209751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned mod = proto[0]; 209851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 209951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (mod == 'v' || mod == 'f') 210051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne mod = proto[1]; 210151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 210251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool quad = false; 210351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool poly = false; 210451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool usgn = false; 210551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool scal = false; 210651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool cnst = false; 210751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool pntr = false; 210851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 210951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Base type to get the type string for. 211051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char type = ClassifyType(typestr, quad, poly, usgn); 211151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 211251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Based on the modifying character, change the type and width if necessary. 211351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = ModType(mod, type, quad, poly, usgn, scal, cnst, pntr); 211451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2115da95f73b59f9af964e33725c515139d34c90c863Bob Wilson NeonTypeFlags::EltType ET; 211651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (type) { 211751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 2118da95f73b59f9af964e33725c515139d34c90c863Bob Wilson ET = poly ? NeonTypeFlags::Poly8 : NeonTypeFlags::Int8; 211951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 212051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 2121da95f73b59f9af964e33725c515139d34c90c863Bob Wilson ET = poly ? NeonTypeFlags::Poly16 : NeonTypeFlags::Int16; 212251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 212351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 2124da95f73b59f9af964e33725c515139d34c90c863Bob Wilson ET = NeonTypeFlags::Int32; 212551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 212651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 2127624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin ET = poly ? NeonTypeFlags::Poly64 : NeonTypeFlags::Int64; 212851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 212951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 2130da95f73b59f9af964e33725c515139d34c90c863Bob Wilson ET = NeonTypeFlags::Float16; 213151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 213251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 2133da95f73b59f9af964e33725c515139d34c90c863Bob Wilson ET = NeonTypeFlags::Float32; 213451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne break; 2135b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case 'd': 2136b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ET = NeonTypeFlags::Float64; 2137b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 213851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 213938859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type!"); 214051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 2141da95f73b59f9af964e33725c515139d34c90c863Bob Wilson NeonTypeFlags Flags(ET, usgn, quad && proto[1] != 'g'); 2142da95f73b59f9af964e33725c515139d34c90c863Bob Wilson return Flags.getFlags(); 214351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 214451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 21450391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liustatic bool ProtoHasScalar(const std::string proto) 21460391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu{ 21470391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu return (proto.find('s') != std::string::npos 21480391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu || proto.find('r') != std::string::npos); 21490391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu} 21500391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu 215151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a) 215251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string GenBuiltin(const std::string &name, const std::string &proto, 215351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef typestr, ClassKind ck) { 215451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 215551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 215651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If this builtin returns a struct 2, 3, or 4 vectors, pass it as an implicit 215751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // sret-like argument. 21582e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu bool sret = IsMultiVecProto(proto[0]); 215951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 216051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool define = UseMacro(proto); 216151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 216251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Check if the prototype has a scalar operand with the type of the vector 216351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // elements. If not, bitcasting the args will take care of arg checking. 216451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // The actual signedness etc. will be taken care of with special enums. 21650391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu if (!ProtoHasScalar(proto)) 216651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ck = ClassB; 216751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 216851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto[0] != 'v') { 216951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string ts = TypeString(proto[0], typestr); 217051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 217151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (define) { 217251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (sret) 217351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ts + " r; "; 217451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 217551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "(" + ts + ")"; 217651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else if (sret) { 217751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ts + " r; "; 217851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 217951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "return (" + ts + ")"; 218051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 218151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 218251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 218351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool splat = proto.find('a') != std::string::npos; 218451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 218551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__builtin_neon_"; 218651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (splat) { 218751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Call the non-splat builtin: chop off the "_n" suffix from the name. 218851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string vname(name, 0, name.size()-2); 218951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName(vname, typestr, ck); 219051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 219151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName(name, typestr, ck); 219251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 219351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "("; 219451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 219551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Pass the address of the return variable as the first argument to sret-like 219651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // builtins. 219751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (sret) 219851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "&r, "; 219951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 220051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char arg = 'a'; 220151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { 220251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string args = std::string(&arg, 1); 220351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 220451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Use the local temporaries instead of the macro arguments. 220551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne args = "__" + args; 220651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 220751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool argQuad = false; 220851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool argPoly = false; 220951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool argUsgn = false; 221051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool argScalar = false; 221151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool dummy = false; 221251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char argType = ClassifyType(typestr, argQuad, argPoly, argUsgn); 221351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne argType = ModType(proto[i], argType, argQuad, argPoly, argUsgn, argScalar, 221451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne dummy, dummy); 221551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 221651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Handle multiple-vector values specially, emitting each subvector as an 221751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // argument to the __builtin. 22182e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu unsigned NumOfVec = 0; 221951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto[i] >= '2' && proto[i] <= '4') { 22202e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu NumOfVec = proto[i] - '0'; 22212e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu } else if (proto[i] >= 'B' && proto[i] <= 'D') { 22222e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu NumOfVec = proto[i] - 'A' + 1; 22232e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu } 22242e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu 22252e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (NumOfVec > 0) { 222651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Check if an explicit cast is needed. 222751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (argType != 'c' || argPoly || argUsgn) 222851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne args = (argQuad ? "(int8x16_t)" : "(int8x8_t)") + args; 222951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 22302e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu for (unsigned vi = 0, ve = NumOfVec; vi != ve; ++vi) { 223151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += args + ".val[" + utostr(vi) + "]"; 223251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((vi + 1) < ve) 223351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", "; 223451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 223551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((i + 1) < e) 223651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", "; 223751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 223851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 223951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 224051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 224151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (splat && (i + 1) == e) 224251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne args = Duplicate(GetNumElements(typestr, argQuad), typestr, args); 224351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 224451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Check if an explicit cast is needed. 224551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((splat || !argScalar) && 224651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ((ck == ClassB && argType != 'c') || argPoly || argUsgn)) { 224751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string argTypeStr = "c"; 224851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck != ClassB) 224951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne argTypeStr = argType; 225051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (argQuad) 225151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne argTypeStr = "Q" + argTypeStr; 225251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne args = "(" + TypeString('d', argTypeStr) + ")" + args; 225351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 225451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 225551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += args; 225651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((i + 1) < e) 225751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", "; 225851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 225951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 226051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Extra constant integer to hold type class enum for this function, e.g. s8 226151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck == ClassB) 226251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", " + utostr(GetNeonEnum(proto, typestr)); 226351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 226451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ");"; 226551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 226651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto[0] != 'v' && sret) { 226751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (define) 226851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " r;"; 226951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 227051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " return r;"; 227151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 227251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 227351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 227451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 227551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string GenBuiltinDef(const std::string &name, 227651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::string &proto, 227751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef typestr, ClassKind ck) { 227851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s("BUILTIN(__builtin_neon_"); 227951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 228051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If all types are the same size, bitcasting the args will take care 228151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // of arg checking. The actual signedness etc. will be taken care of with 228251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // special enums. 22830391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu if (!ProtoHasScalar(proto)) 228451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ck = ClassB; 228551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 228651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += MangleName(name, typestr, ck); 228751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", \""; 228851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 228951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = proto.size(); i != e; ++i) 229051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += BuiltinTypeString(proto[i], typestr, ck, i == 0); 229151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 229251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Extra constant integer to hold type class enum for this function, e.g. s8 229351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (ck == ClassB) 229451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "i"; 229551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 229651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "\", \"n\")"; 229751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 229851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 229951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 230051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string GenIntrinsic(const std::string &name, 230151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::string &proto, 230251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef outTypeStr, StringRef inTypeStr, 230351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OpKind kind, ClassKind classKind) { 230451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(!proto.empty() && ""); 2305667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach bool define = UseMacro(proto) && kind != OpUnavailable; 230651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 230751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 230851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // static always inline + return type 230951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (define) 231051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "#define "; 231151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 231251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "__ai " + TypeString(proto[0], outTypeStr) + " "; 231351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 231451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Function name with type suffix 231551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string mangledName = MangleName(name, outTypeStr, ClassS); 231651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (outTypeStr != inTypeStr) { 231751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If the input type is different (e.g., for vreinterpret), append a suffix 231851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // for the input type. String off a "Q" (quad) prefix so that MangleName 231951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // does not insert another "q" in the name. 232051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0); 232151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff); 232251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne mangledName = MangleName(mangledName, inTypeNoQuad, ClassS); 232351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 232451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += mangledName; 232551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 232651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Function arguments 23272102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin s += GenArgs(proto, inTypeStr, name); 232851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 232951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Definition. 233051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (define) { 233151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " __extension__ ({ \\\n "; 23322102a1dba460c99f97a0fdf1e5aee8c685e29ff8Kevin Qin s += GenMacroLocals(proto, inTypeStr, name); 2333667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach } else if (kind == OpUnavailable) { 2334667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach s += " __attribute__((unavailable));\n"; 2335667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach return s; 2336667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach } else 233766981c7ca1fcef529d7d5e5c53b07020ff23d8e3Jim Grosbach s += " {\n "; 233851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 233951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (kind != OpNone) 2340912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu s += GenOpString(name, kind, proto, outTypeStr); 234151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 234251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += GenBuiltin(name, proto, outTypeStr, classKind); 234351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (define) 234451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " })"; 234551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 234651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += " }"; 234751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "\n"; 234851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 234951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 235051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 235151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// run - Read the records in arm_neon.td and output arm_neon.h. arm_neon.h 235251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// is comprised of type definitions and function declarations. 235351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournevoid NeonEmitter::run(raw_ostream &OS) { 235451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << 235551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "/*===---- arm_neon.h - ARM Neon intrinsics ------------------------------" 235651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "---===\n" 235751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " *\n" 235851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * Permission is hereby granted, free of charge, to any person obtaining " 235951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "a copy\n" 236051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * of this software and associated documentation files (the \"Software\")," 236151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " to deal\n" 236251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * in the Software without restriction, including without limitation the " 236351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "rights\n" 236451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * to use, copy, modify, merge, publish, distribute, sublicense, " 236551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "and/or sell\n" 236651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * copies of the Software, and to permit persons to whom the Software is\n" 236751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * furnished to do so, subject to the following conditions:\n" 236851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " *\n" 236951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * The above copyright notice and this permission notice shall be " 237051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "included in\n" 237151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * all copies or substantial portions of the Software.\n" 237251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " *\n" 237351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, " 237451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "EXPRESS OR\n" 237551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF " 237651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "MERCHANTABILITY,\n" 237751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT " 237851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "SHALL THE\n" 237951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR " 238051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "OTHER\n" 238151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, " 238251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "ARISING FROM,\n" 238351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER " 238451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "DEALINGS IN\n" 238551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " * THE SOFTWARE.\n" 238651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " *\n" 238751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " *===--------------------------------------------------------------------" 238851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne "---===\n" 238951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne " */\n\n"; 239051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 239151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#ifndef __ARM_NEON_H\n"; 239251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#define __ARM_NEON_H\n\n"; 239351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2394b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#if !defined(__ARM_NEON__) && !defined(__AARCH_FEATURE_ADVSIMD)\n"; 239551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#error \"NEON support not enabled\"\n"; 239651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 239751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 239851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#include <stdint.h>\n\n"; 239951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 240051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit NEON-specific scalar typedefs. 240151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "typedef float float32_t;\n"; 2402b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "typedef __fp16 float16_t;\n"; 2403b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2404b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef __aarch64__\n"; 2405b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "typedef double float64_t;\n"; 2406b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#endif\n\n"; 2407b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2408b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // For now, signedness of polynomial types depends on target 2409b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef __aarch64__\n"; 2410b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "typedef uint8_t poly8_t;\n"; 2411b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "typedef uint16_t poly16_t;\n"; 2412624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin OS << "typedef uint64_t poly64_t;\n"; 2413b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#else\n"; 241451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "typedef int8_t poly8_t;\n"; 241551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "typedef int16_t poly16_t;\n"; 2416b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#endif\n"; 241751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 241851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit Neon vector typedefs. 2419b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string TypedefTypes( 2420624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin "cQcsQsiQilQlUcQUcUsQUsUiQUiUlQUlhQhfQfdQdPcQPcPsQPsPlQPl"); 242151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVector<StringRef, 24> TDTypeVec; 242251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ParseTypes(0, TypedefTypes, TDTypeVec); 242351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 242451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit vector typedefs. 24250aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu bool isA64 = false; 2426624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin bool preinsert; 2427624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin bool postinsert; 242851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { 242951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool dummy, quad = false, poly = false; 2430b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover char type = ClassifyType(TDTypeVec[i], quad, poly, dummy); 2431624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin preinsert = false; 2432624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin postinsert = false; 2433b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2434624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin if (type == 'd' || (type == 'l' && poly)) { 24350aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu preinsert = isA64? false: true; 2436b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover isA64 = true; 24370aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu } else { 24380aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu postinsert = isA64? true: false; 24390aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu isA64 = false; 24400aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu } 24410aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu if (postinsert) 24420aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OS << "#endif\n"; 24430aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu if (preinsert) 2444b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef __aarch64__\n"; 2445b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 244651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (poly) 244751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "typedef __attribute__((neon_polyvector_type("; 244851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 244951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "typedef __attribute__((neon_vector_type("; 245051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 245151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned nElts = GetNumElements(TDTypeVec[i], quad); 245251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << utostr(nElts) << "))) "; 245351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (nElts < 10) 245451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " "; 245551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 245651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << TypeString('s', TDTypeVec[i]); 245751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << TypeString('d', TDTypeVec[i]) << ";\n"; 2458b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 245951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 2460624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin postinsert = isA64? true: false; 2461624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin if (postinsert) 2462624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin OS << "#endif\n"; 246351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n"; 246451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 246551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit struct typedefs. 24660aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu isA64 = false; 246751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned vi = 2; vi != 5; ++vi) { 246851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = TDTypeVec.size(); i != e; ++i) { 2469b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool dummy, quad = false, poly = false; 2470b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover char type = ClassifyType(TDTypeVec[i], quad, poly, dummy); 2471624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin preinsert = false; 2472624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin postinsert = false; 2473b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2474624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin if (type == 'd' || (type == 'l' && poly)) { 24750aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu preinsert = isA64? false: true; 2476b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover isA64 = true; 24770aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu } else { 24780aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu postinsert = isA64? true: false; 24790aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu isA64 = false; 24800aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu } 24810aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu if (postinsert) 24820aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu OS << "#endif\n"; 24830aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu if (preinsert) 2484b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef __aarch64__\n"; 2485b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 248651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string ts = TypeString('d', TDTypeVec[i]); 248751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string vs = TypeString('0' + vi, TDTypeVec[i]); 248851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "typedef struct " << vs << " {\n"; 248951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << " " << ts << " val"; 249051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "[" << utostr(vi) << "]"; 249151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << ";\n} "; 2492b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << vs << ";\n"; 2493b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "\n"; 249451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 249551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 2496624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin postinsert = isA64? true: false; 2497624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin if (postinsert) 2498624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin OS << "#endif\n"; 2499624bb5e59dbcc24efeee7dff12c9b48d2b5077e9Kevin Qin OS << "\n"; 250051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 25011e8058f8d90fab1b9011adf62caa52e19e61382cBob Wilson OS<<"#define __ai static inline __attribute__((__always_inline__, __nodebug__))\n\n"; 250251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 250351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::vector<Record*> RV = Records.getAllDerivedDefinitions("Inst"); 250451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2505b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> EmittedMap; 2506b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 250751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit vmovl, vmull and vabd intrinsics first so they can be used by other 250851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // intrinsics. (Some of the saturating multiply instructions are also 250951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // used to implement the corresponding "_lane" variants, but tablegen 251051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // sorts the records into alphabetical order so that the "_lane" variants 251151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // come after the intrinsics they use.) 2512b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover emitIntrinsic(OS, Records.getDef("VMOVL"), EmittedMap); 2513b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover emitIntrinsic(OS, Records.getDef("VMULL"), EmittedMap); 2514b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover emitIntrinsic(OS, Records.getDef("VABD"), EmittedMap); 2515097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu emitIntrinsic(OS, Records.getDef("VABDL"), EmittedMap); 2516b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2517b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // ARM intrinsics must be emitted before AArch64 intrinsics to ensure 2518b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // common intrinsics appear only once in the output stream. 2519b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // The check for uniquiness is done in emitIntrinsic. 2520b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Emit ARM intrinsics. 252151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = RV.size(); i != e; ++i) { 252251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = RV[i]; 2523b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2524b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Skip AArch64 intrinsics; they will be emitted at the end. 2525b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 2526b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64) 2527b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2528b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2529b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (R->getName() != "VMOVL" && R->getName() != "VMULL" && 253051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne R->getName() != "VABD") 2531b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover emitIntrinsic(OS, R, EmittedMap); 253251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 253351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2534b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Emit AArch64-specific intrinsics. 2535b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef __aarch64__\n"; 2536b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2537097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu emitIntrinsic(OS, Records.getDef("VMOVL_HIGH"), EmittedMap); 2538097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu emitIntrinsic(OS, Records.getDef("VMULL_HIGH"), EmittedMap); 2539097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu emitIntrinsic(OS, Records.getDef("VABDL_HIGH"), EmittedMap); 2540097a4b487897ca29f0f371c81b6a8b6c1ca599e4Jiangning Liu 2541b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover for (unsigned i = 0, e = RV.size(); i != e; ++i) { 2542b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Record *R = RV[i]; 2543b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2544b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Skip ARM intrinsics already included above. 2545b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 2546b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64) 2547b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2548b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2549b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover emitIntrinsic(OS, R, EmittedMap); 2550b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2551b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2552b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#endif\n\n"; 2553b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 255451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#undef __ai\n\n"; 255551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif /* __ARM_NEON_H */\n"; 255651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 255751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 255851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// emitIntrinsic - Write out the arm_neon.h header file definitions for the 2559b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// intrinsics specified by record R checking for intrinsic uniqueness. 2560b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid NeonEmitter::emitIntrinsic(raw_ostream &OS, Record *R, 2561b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &EmittedMap) { 256251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name = R->getValueAsString("Name"); 256351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Proto = R->getValueAsString("Prototype"); 256451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Types = R->getValueAsString("Types"); 256551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 256651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVector<StringRef, 16> TypeVec; 256751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ParseTypes(R, Types, TypeVec); 256851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 256951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; 257051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 257151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ClassKind classKind = ClassNone; 257251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R->getSuperClasses().size() >= 2) 257351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne classKind = ClassMap[R->getSuperClasses()[1]]; 257451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (classKind == ClassNone && kind == OpNone) 257538859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError(R->getLoc(), "Builtin has no class kind"); 257651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 257751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { 257851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (kind == OpReinterpret) { 257951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool outQuad = false; 258051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool dummy = false; 258151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy); 258251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned srcti = 0, srcte = TypeVec.size(); 258351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne srcti != srcte; ++srcti) { 258451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool inQuad = false; 258551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy); 258651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (srcti == ti || inQuad != outQuad) 258751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 2588b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string s = GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti], 2589b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OpCast, ClassS); 2590b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (EmittedMap.count(s)) 2591b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2592b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover EmittedMap[s] = ClassS; 2593b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << s; 259451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 259551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 2596b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string s = 2597b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti], kind, classKind); 2598b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (EmittedMap.count(s)) 2599b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2600b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover EmittedMap[s] = classKind; 2601b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << s; 260251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 260351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 260451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "\n"; 260551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 260651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 260751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic unsigned RangeFromType(const char mod, StringRef typestr) { 260851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // base type to get the type string for. 260951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool quad = false, dummy = false; 261051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char type = ClassifyType(typestr, quad, dummy, dummy); 261151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne type = ModType(mod, type, quad, dummy, dummy, dummy, dummy, dummy); 261251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 261351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne switch (type) { 261451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'c': 261551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return (8 << (int)quad) - 1; 261651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'h': 261751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 's': 261851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return (4 << (int)quad) - 1; 261951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'f': 262051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'i': 262151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return (2 << (int)quad) - 1; 26220aa1a88e19235574481e46e9e6e9ce66a9e6624fJiangning Liu case 'd': 262351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne case 'l': 262451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return (1 << (int)quad) - 1; 262551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne default: 262638859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError("unhandled type!"); 262751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 262851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 262951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2630f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosierstatic unsigned RangeScalarShiftImm(const char mod, StringRef typestr) { 2631f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier // base type to get the type string for. 2632f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier bool dummy = false; 2633f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier char type = ClassifyType(typestr, dummy, dummy, dummy); 2634f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier type = ModType(mod, type, dummy, dummy, dummy, dummy, dummy, dummy); 2635f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier 2636f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier switch (type) { 2637f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 'c': 2638f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier return 7; 2639f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 'h': 2640f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 's': 2641f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier return 15; 2642f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 'f': 2643f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 'i': 2644f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier return 31; 2645f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 'd': 2646f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier case 'l': 2647f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier return 63; 2648f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier default: 2649f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier PrintFatalError("unhandled type!"); 2650f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier } 2651f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier} 2652f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier 2653b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// Generate the ARM and AArch64 intrinsic range checking code for 2654b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// shift/lane immediates, checking for unique declarations. 2655b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid 2656b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim NorthoverNeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS, 2657b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &A64IntrinsicMap, 2658b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64RangeCheck) { 2659b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 266051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringMap<OpKind> EmittedMap; 266151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2662b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate the intrinsic range checking code for shift/lane immediates. 2663b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64RangeCheck) 2664b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef GET_NEON_AARCH64_IMMEDIATE_CHECK\n"; 2665b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 2666b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef GET_NEON_IMMEDIATE_CHECK\n"; 2667b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 266851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = RV.size(); i != e; ++i) { 266951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = RV[i]; 2670b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 267151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; 267251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (k != OpNone) 267351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 267451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2675b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string name = R->getValueAsString("Name"); 267651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Proto = R->getValueAsString("Prototype"); 2677b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string Types = R->getValueAsString("Types"); 2678944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin std::string Rename = name + "@" + Proto; 267951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 268051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Functions with 'a' (the splat code) in the type prototype should not get 268151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // their own builtin as they use the non-splat variant. 268251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Proto.find('a') != std::string::npos) 268351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 268451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2685b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Functions which do not have an immediate do not need to have range 2686b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // checking code emitted. 2687b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover size_t immPos = Proto.find('i'); 2688b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (immPos == std::string::npos) 2689b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2690b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 269151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVector<StringRef, 16> TypeVec; 269251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ParseTypes(R, Types, TypeVec); 269351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 269451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R->getSuperClasses().size() < 2) 269538859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError(R->getLoc(), "Builtin has no class kind"); 269651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 269751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ClassKind ck = ClassMap[R->getSuperClasses()[1]]; 269851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2699b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Do not include AArch64 range checks if not generating code for AArch64. 2700b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 2701b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64RangeCheck && isA64) 2702b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2703b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2704b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Include ARM range checks in AArch64 but only if ARM intrinsics are not 2705b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // redefined by AArch64 to handle new types. 2706944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if (isA64RangeCheck && !isA64 && A64IntrinsicMap.count(Rename)) { 2707944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin ClassKind &A64CK = A64IntrinsicMap[Rename]; 2708b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (A64CK == ck && ck != ClassNone) 2709b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2710b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2711b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 271251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { 2713b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string namestr, shiftstr, rangestr; 2714b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2715b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (R->getValueAsBit("isVCVT_N")) { 2716b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // VCVT between floating- and fixed-point values takes an immediate 2717912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu // in the range [1, 32] for f32, or [1, 64] for f64. 2718b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ck = ClassB; 2719912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu if (name.find("32") != std::string::npos) 2720912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu rangestr = "l = 1; u = 31"; // upper bound = l + u 2721912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu else if (name.find("64") != std::string::npos) 2722912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu rangestr = "l = 1; u = 63"; 2723912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu else 2724912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu PrintFatalError(R->getLoc(), 2725912502b4996b14db31b498cb1eef2b17d7d66d57Hao Liu "Fixed point convert name should contains \"32\" or \"64\""); 2726f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier 2727f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier } else if (R->getValueAsBit("isScalarShift")) { 27289473c1945f9f1dfa143e172622f16e4264e2628bChad Rosier // Right shifts have an 'r' in the name, left shifts do not. Convert 27299473c1945f9f1dfa143e172622f16e4264e2628bChad Rosier // instructions have the same bounds and right shifts. 27309473c1945f9f1dfa143e172622f16e4264e2628bChad Rosier if (name.find('r') != std::string::npos || 27319473c1945f9f1dfa143e172622f16e4264e2628bChad Rosier name.find("cvt") != std::string::npos) 2732f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier rangestr = "l = 1; "; 2733f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier 2734f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier rangestr += "u = " + 2735f42727215f9fa38175d2e84a938c84122cd1e811Chad Rosier utostr(RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti])); 27360391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu } else if (!ProtoHasScalar(Proto)) { 2737b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Builtins which are overloaded by type will need to have their upper 2738b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // bound computed at Sema time based on the type constant. 2739b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ck = ClassB; 2740b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (R->getValueAsBit("isShift")) { 2741b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover shiftstr = ", true"; 2742b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2743b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Right shifts have an 'r' in the name, left shifts do not. 2744b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (name.find('r') != std::string::npos) 2745b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover rangestr = "l = 1; "; 2746b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2747b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover rangestr += "u = RFT(TV" + shiftstr + ")"; 2748b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } else { 2749b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // The immediate generally refers to a lane in the preceding argument. 2750b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover assert(immPos > 0 && "unexpected immediate operand"); 2751b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover rangestr = 2752b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "u = " + utostr(RangeFromType(Proto[immPos - 1], TypeVec[ti])); 2753b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2754b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Make sure cases appear only once by uniquing them in a string map. 2755b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover namestr = MangleName(name, TypeVec[ti], ck); 2756b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (EmittedMap.count(namestr)) 275751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 2758b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover EmittedMap[namestr] = OpNone; 275951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2760b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Calculate the index of the immediate that should be range checked. 2761b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover unsigned immidx = 0; 2762b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2763b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Builtins that return a struct of multiple vectors have an extra 2764b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // leading arg for the struct return. 27652e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (IsMultiVecProto(Proto[0])) 2766b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ++immidx; 2767b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2768b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Add one to the index for each argument until we reach the immediate 2769b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // to be checked. Structs of vectors are passed as multiple arguments. 2770b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover for (unsigned ii = 1, ie = Proto.size(); ii != ie; ++ii) { 2771b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover switch (Proto[ii]) { 2772b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover default: 2773b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover immidx += 1; 2774b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 2775b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case '2': 27762e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu case 'B': 2777b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover immidx += 2; 2778b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 2779b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case '3': 27802e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu case 'C': 2781b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover immidx += 3; 2782b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 2783b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case '4': 27842e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu case 'D': 2785b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover immidx += 4; 2786b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 2787b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover case 'i': 2788b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ie = ii + 1; 2789b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover break; 2790b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2791b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2792b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64RangeCheck) 2793b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "case AArch64::BI__builtin_neon_"; 2794b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 2795b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "case ARM::BI__builtin_neon_"; 2796b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << MangleName(name, TypeVec[ti], ck) << ": i = " << immidx << "; " 2797b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover << rangestr << "; break;\n"; 279851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 279951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 280051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 2801b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover} 2802b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2803b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// Generate the ARM and AArch64 overloaded type checking code for 2804b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// SemaChecking.cpp, checking for unique builtin declarations. 2805b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid 2806b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim NorthoverNeonEmitter::genOverloadTypeCheckCode(raw_ostream &OS, 2807b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &A64IntrinsicMap, 2808b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64TypeCheck) { 2809b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 2810b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<OpKind> EmittedMap; 281151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 281251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Generate the overloaded type checking code for SemaChecking.cpp 2813b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64TypeCheck) 2814b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef GET_NEON_AARCH64_OVERLOAD_CHECK\n"; 2815b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 2816b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef GET_NEON_OVERLOAD_CHECK\n"; 2817b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 281851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = RV.size(); i != e; ++i) { 281951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = RV[i]; 282051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; 282151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (k != OpNone) 282251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 282351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 282451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Proto = R->getValueAsString("Prototype"); 282551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Types = R->getValueAsString("Types"); 282651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name = R->getValueAsString("Name"); 2827944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin std::string Rename = name + "@" + Proto; 2828944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin 282951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Functions with 'a' (the splat code) in the type prototype should not get 283051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // their own builtin as they use the non-splat variant. 283151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Proto.find('a') != std::string::npos) 283251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 283351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 283451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Functions which have a scalar argument cannot be overloaded, no need to 283551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // check them if we are emitting the type checking code. 28360391691f86fd2a75ef2413d0272bfaf920d0e2b5Jiangning Liu if (ProtoHasScalar(Proto)) 283751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 283851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 283951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVector<StringRef, 16> TypeVec; 284051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ParseTypes(R, Types, TypeVec); 284151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 284251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R->getSuperClasses().size() < 2) 284338859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError(R->getLoc(), "Builtin has no class kind"); 284451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2845b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Do not include AArch64 type checks if not generating code for AArch64. 2846b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 2847b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64TypeCheck && isA64) 2848b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2849b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2850b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Include ARM type check in AArch64 but only if ARM intrinsics 2851b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr 2852b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // redefined in AArch64 to handle an additional 2 x f64 type. 2853b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ClassKind ck = ClassMap[R->getSuperClasses()[1]]; 2854944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if (isA64TypeCheck && !isA64 && A64IntrinsicMap.count(Rename)) { 2855944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin ClassKind &A64CK = A64IntrinsicMap[Rename]; 2856b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (A64CK == ck && ck != ClassNone) 2857b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 2858b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 2859b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 286051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne int si = -1, qi = -1; 2861f8ee6bc1ef0eec8e22b413dfc2baa3cfa4f19f91Richard Smith uint64_t mask = 0, qmask = 0; 286251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { 286351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Generate the switch case(s) for this builtin for the type validation. 286451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool quad = false, poly = false, usgn = false; 286551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (void) ClassifyType(TypeVec[ti], quad, poly, usgn); 286651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 286751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (quad) { 286851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne qi = ti; 2869f8ee6bc1ef0eec8e22b413dfc2baa3cfa4f19f91Richard Smith qmask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]); 287051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 287151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne si = ti; 2872f8ee6bc1ef0eec8e22b413dfc2baa3cfa4f19f91Richard Smith mask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]); 287351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 287451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 28754648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson 28764648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson // Check if the builtin function has a pointer or const pointer argument. 28774648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson int PtrArgNum = -1; 28784648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson bool HasConstPtr = false; 28794648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson for (unsigned arg = 1, arge = Proto.size(); arg != arge; ++arg) { 28804648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson char ArgType = Proto[arg]; 28814648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson if (ArgType == 'c') { 28824648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson HasConstPtr = true; 28834648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson PtrArgNum = arg - 1; 28844648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson break; 28854648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson } 28864648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson if (ArgType == 'p') { 28874648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson PtrArgNum = arg - 1; 28884648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson break; 28894648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson } 28904648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson } 28914648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson // For sret builtins, adjust the pointer argument index. 28922e22f29b92768ea65ac5c26d354226ecc7509311Jiangning Liu if (PtrArgNum >= 0 && IsMultiVecProto(Proto[0])) 28934648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson PtrArgNum += 1; 28944648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson 28959082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson // Omit type checking for the pointer arguments of vld1_lane, vld1_dup, 28969082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson // and vst1_lane intrinsics. Using a pointer to the vector element 28979082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson // type with one of those operations causes codegen to select an aligned 28989082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson // load/store instruction. If you want an unaligned operation, 28999082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson // the pointer argument needs to have less alignment than element type, 29009082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson // so just accept any pointer type. 29019082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson if (name == "vld1_lane" || name == "vld1_dup" || name == "vst1_lane") { 29029082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson PtrArgNum = -1; 29039082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson HasConstPtr = false; 29049082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson } 29059082cddf28e03c2f718e92457e2d9c7390056b2dBob Wilson 29066f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson if (mask) { 2907b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64TypeCheck) 2908b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "case AArch64::BI__builtin_neon_"; 2909b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 2910b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "case ARM::BI__builtin_neon_"; 2911b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << MangleName(name, TypeVec[si], ClassB) << ": mask = " 2912b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover << "0x" << utohexstr(mask) << "ULL"; 29134648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson if (PtrArgNum >= 0) 29144648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson OS << "; PtrArgNum = " << PtrArgNum; 29156f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson if (HasConstPtr) 29166f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson OS << "; HasConstPtr = true"; 29176f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson OS << "; break;\n"; 29186f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson } 29196f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson if (qmask) { 2920b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64TypeCheck) 2921b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "case AArch64::BI__builtin_neon_"; 2922b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 2923b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "case ARM::BI__builtin_neon_"; 2924b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << MangleName(name, TypeVec[qi], ClassB) << ": mask = " 2925b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover << "0x" << utohexstr(qmask) << "ULL"; 29264648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson if (PtrArgNum >= 0) 29274648255cebd2fc7c18293c1f93afd6e9add9ccccBob Wilson OS << "; PtrArgNum = " << PtrArgNum; 29286f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson if (HasConstPtr) 29296f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson OS << "; HasConstPtr = true"; 29306f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson OS << "; break;\n"; 29316f9f03ef370ad48ece0c5d10edda28f39ccadb5dBob Wilson } 293251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 293351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 2934b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover} 2935b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2936b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// genBuiltinsDef: Generate the BuiltinsARM.def and BuiltinsAArch64.def 2937b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// declaration of builtins, checking for unique builtin declarations. 2938b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid NeonEmitter::genBuiltinsDef(raw_ostream &OS, 2939b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> &A64IntrinsicMap, 2940b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64GenBuiltinDef) { 2941b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 2942b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<OpKind> EmittedMap; 2943b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 2944b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate BuiltinsARM.def and BuiltinsAArch64.def 2945b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64GenBuiltinDef) 2946b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef GET_NEON_AARCH64_BUILTINS\n"; 2947b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover else 2948b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef GET_NEON_BUILTINS\n"; 294951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 295051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = RV.size(); i != e; ++i) { 295151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = RV[i]; 295251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OpKind k = OpMap[R->getValueAsDef("Operand")->getName()]; 295351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (k != OpNone) 295451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 295551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 295651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Proto = R->getValueAsString("Prototype"); 2957b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string name = R->getValueAsString("Name"); 2958944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin std::string Rename = name + "@" + Proto; 295951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 296051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Functions with 'a' (the splat code) in the type prototype should not get 296151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // their own builtin as they use the non-splat variant. 296251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (Proto.find('a') != std::string::npos) 296351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 296451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2965b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string Types = R->getValueAsString("Types"); 296651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVector<StringRef, 16> TypeVec; 296751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ParseTypes(R, Types, TypeVec); 296851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 296951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (R->getSuperClasses().size() < 2) 297038859ee4a3c1253d5a45ed3f6b52e77702bfd913Joerg Sonnenberger PrintFatalError(R->getLoc(), "Builtin has no class kind"); 297151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 297251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ClassKind ck = ClassMap[R->getSuperClasses()[1]]; 297351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2974b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Do not include AArch64 BUILTIN() macros if not generating 2975b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // code for AArch64 2976b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 2977b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64GenBuiltinDef && isA64) 2978b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 297951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2980b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Include ARM BUILTIN() macros in AArch64 but only if ARM intrinsics 2981b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // are not redefined in AArch64 to handle new types, e.g. "vabd" is a SIntr 2982b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // redefined in AArch64 to handle an additional 2 x f64 type. 2983944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if (isA64GenBuiltinDef && !isA64 && A64IntrinsicMap.count(Rename)) { 2984944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin ClassKind &A64CK = A64IntrinsicMap[Rename]; 2985b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (A64CK == ck && ck != ClassNone) 298651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 2987b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 298851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2989b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { 2990b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate the declaration for this builtin, ensuring 2991b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // that each unique BUILTIN() macro appears only once in the output 2992b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // stream. 2993b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string bd = GenBuiltinDef(name, Proto, TypeVec[ti], ck); 2994b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (EmittedMap.count(bd)) 2995b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 299651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 2997b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover EmittedMap[bd] = OpNone; 2998b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << bd << "\n"; 299951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 300051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 300151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OS << "#endif\n\n"; 300251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 300351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3004b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// runHeader - Emit a file with sections defining: 3005b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// 1. the NEON section of BuiltinsARM.def and BuiltinsAArch64.def. 3006b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// 2. the SemaChecking code for the type overload checking. 3007b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// 3. the SemaChecking code for validation of intrinsic immediate arguments. 3008b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid NeonEmitter::runHeader(raw_ostream &OS) { 3009b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 3010b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3011b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // build a map of AArch64 intriniscs to be used in uniqueness checks. 3012b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<ClassKind> A64IntrinsicMap; 3013b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover for (unsigned i = 0, e = RV.size(); i != e; ++i) { 3014b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover Record *R = RV[i]; 3015b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3016b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 3017b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64) 3018b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 3019b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3020b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ClassKind CK = ClassNone; 3021b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (R->getSuperClasses().size() >= 2) 3022b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover CK = ClassMap[R->getSuperClasses()[1]]; 3023b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3024b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string Name = R->getValueAsString("Name"); 3025944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin std::string Proto = R->getValueAsString("Prototype"); 3026944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin std::string Rename = Name + "@" + Proto; 3027944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin if (A64IntrinsicMap.count(Rename)) 3028b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 3029944f09ff9b33637465906e1aeadcfa405d66331dKevin Qin A64IntrinsicMap[Rename] = CK; 3030b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 3031b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3032b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate BuiltinsARM.def for ARM 3033b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genBuiltinsDef(OS, A64IntrinsicMap, false); 3034b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3035b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate BuiltinsAArch64.def for AArch64 3036b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genBuiltinsDef(OS, A64IntrinsicMap, true); 3037b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3038b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate ARM overloaded type checking code for SemaChecking.cpp 3039b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genOverloadTypeCheckCode(OS, A64IntrinsicMap, false); 3040b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3041b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate AArch64 overloaded type checking code for SemaChecking.cpp 3042b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genOverloadTypeCheckCode(OS, A64IntrinsicMap, true); 3043b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3044b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate ARM range checking code for shift/lane immediates. 3045b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genIntrinsicRangeCheckCode(OS, A64IntrinsicMap, false); 3046b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3047b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // Generate the AArch64 range checking code for shift/lane immediates. 3048b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genIntrinsicRangeCheckCode(OS, A64IntrinsicMap, true); 3049b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover} 3050b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 305151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// GenTest - Write out a test for the intrinsic specified by the name and 305251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne/// type strings, including the embedded patterns for FileCheck to match. 305351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbournestatic std::string GenTest(const std::string &name, 305451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne const std::string &proto, 305551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef outTypeStr, StringRef inTypeStr, 30567200bd673af6b58d7d2f0c5d048050abe5b8858cMichael Gottesman bool isShift, bool isHiddenLOp, 3057b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover ClassKind ck, const std::string &InstName, 305851cc0172a173599b769968696e20638754d1dcd6Ana Pazos bool isA64, 305951cc0172a173599b769968696e20638754d1dcd6Ana Pazos std::string & testFuncProto) { 306051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne assert(!proto.empty() && ""); 306151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string s; 306251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 306351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Function name with type suffix 306451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string mangledName = MangleName(name, outTypeStr, ClassS); 306551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (outTypeStr != inTypeStr) { 306651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // If the input type is different (e.g., for vreinterpret), append a suffix 306751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // for the input type. String off a "Q" (quad) prefix so that MangleName 306851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // does not insert another "q" in the name. 306951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0); 307051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff); 307151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne mangledName = MangleName(mangledName, inTypeNoQuad, ClassS); 307251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 307351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3074b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // todo: GenerateChecksForIntrinsic does not generate CHECK 3075b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // for aarch64 instructions yet 3076c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman std::vector<std::string> FileCheckPatterns; 3077b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64) { 3078b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover GenerateChecksForIntrinsic(name, proto, outTypeStr, inTypeStr, ck, InstName, 3079b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover isHiddenLOp, FileCheckPatterns); 3080b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s+= "// CHECK_ARM: test_" + mangledName + "\n"; 3081b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover } 3082b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s += "// CHECK_AARCH64: test_" + mangledName + "\n"; 3083c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman 308451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit the FileCheck patterns. 3085c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // If for any reason we do not want to emit a check, mangledInst 3086c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman // will be the empty string. 3087c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman if (FileCheckPatterns.size()) { 3088c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman for (std::vector<std::string>::const_iterator i = FileCheckPatterns.begin(), 3089c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman e = FileCheckPatterns.end(); 3090c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman i != e; 3091c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman ++i) { 3092b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s += "// CHECK_ARM: " + *i + "\n"; 3093c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 3094c327f8705ecb8753555822d479f899bd2234386dMichael Gottesman } 309551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 309651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Emit the start of the test function. 3097b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3098b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover testFuncProto = TypeString(proto[0], outTypeStr) + " test_" + mangledName + "("; 309951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne char arg = 'a'; 310051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string comma; 310151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { 310251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // Do not create arguments for values that must be immediate constants. 310351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto[i] == 'i') 310451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 3105b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover testFuncProto += comma + TypeString(proto[i], inTypeStr) + " "; 3106b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover testFuncProto.push_back(arg); 310751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne comma = ", "; 310851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 3109b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover testFuncProto += ")"; 3110b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3111b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s+= testFuncProto; 3112b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover s+= " {\n "; 311351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 311451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto[0] != 'v') 311551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "return "; 311651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += mangledName + "("; 311751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne arg = 'a'; 311851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) { 311951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (proto[i] == 'i') { 312051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // For immediate operands, test the maximum value. 312151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (isShift) 312251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += "1"; // FIXME 312351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne else 312451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne // The immediate generally refers to a lane in the preceding argument. 312551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += utostr(RangeFromType(proto[i-1], inTypeStr)); 312651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 312751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s.push_back(arg); 312851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 312951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if ((i + 1) < e) 313051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ", "; 313151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 313251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne s += ");\n}\n\n"; 313351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne return s; 313451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 313551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3136b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// Write out all intrinsic tests for the specified target, checking 3137b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// for intrinsic test uniqueness. 3138b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid NeonEmitter::genTargetTest(raw_ostream &OS, StringMap<OpKind> &EmittedMap, 3139b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64GenTest) { 3140b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64GenTest) 3141b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#ifdef __aarch64__\n"; 314251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 3143b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::vector<Record *> RV = Records.getAllDerivedDefinitions("Inst"); 314451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned i = 0, e = RV.size(); i != e; ++i) { 314551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne Record *R = RV[i]; 314651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string name = R->getValueAsString("Name"); 314751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Proto = R->getValueAsString("Prototype"); 314851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne std::string Types = R->getValueAsString("Types"); 314951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool isShift = R->getValueAsBit("isShift"); 31507200bd673af6b58d7d2f0c5d048050abe5b8858cMichael Gottesman std::string InstName = R->getValueAsString("InstName"); 31517200bd673af6b58d7d2f0c5d048050abe5b8858cMichael Gottesman bool isHiddenLOp = R->getValueAsBit("isHiddenLInst"); 3152b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover bool isA64 = R->getValueAsBit("isA64"); 3153b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3154b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // do not include AArch64 intrinsic test if not generating 3155b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // code for AArch64 3156b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (!isA64GenTest && isA64) 3157b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 315851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 315951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne SmallVector<StringRef, 16> TypeVec; 316051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne ParseTypes(R, Types, TypeVec); 316151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 31627200bd673af6b58d7d2f0c5d048050abe5b8858cMichael Gottesman ClassKind ck = ClassMap[R->getSuperClasses()[1]]; 316351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()]; 3164667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach if (kind == OpUnavailable) 3165667381b21f75d6964bbdf6af143308a02b9198a8Jim Grosbach continue; 316651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) { 316751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (kind == OpReinterpret) { 316851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool outQuad = false; 316951d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool dummy = false; 317051d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy); 317151d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne for (unsigned srcti = 0, srcte = TypeVec.size(); 317251d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne srcti != srcte; ++srcti) { 317351d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne bool inQuad = false; 317451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy); 317551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne if (srcti == ti || inQuad != outQuad) 317651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne continue; 3177b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string testFuncProto; 3178b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[srcti], 3179b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover isShift, isHiddenLOp, ck, InstName, isA64, 3180b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover testFuncProto); 3181b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (EmittedMap.count(testFuncProto)) 3182b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 3183b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover EmittedMap[testFuncProto] = kind; 3184b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << s << "\n"; 318551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 318651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } else { 3187b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string testFuncProto; 3188b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover std::string s = GenTest(name, Proto, TypeVec[ti], TypeVec[ti], isShift, 3189b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover isHiddenLOp, ck, InstName, isA64, testFuncProto); 3190b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (EmittedMap.count(testFuncProto)) 3191b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover continue; 3192b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover EmittedMap[testFuncProto] = kind; 3193b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << s << "\n"; 319451d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 319551d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 319651d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne } 3197b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3198b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover if (isA64GenTest) 3199b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "#endif\n"; 3200b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover} 3201b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// runTests - Write out a complete set of tests for all of the Neon 3202b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover/// intrinsics. 3203b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northovervoid NeonEmitter::runTests(raw_ostream &OS) { 3204b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover OS << "// RUN: %clang_cc1 -triple thumbv7s-apple-darwin -target-abi " 3205b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "apcs-gnu\\\n" 3206b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "// RUN: -target-cpu swift -ffreestanding -Os -S -o - %s\\\n" 3207b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "// RUN: | FileCheck %s -check-prefix=CHECK_ARM\n" 3208b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "\n" 3209b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "// RUN: %clang_cc1 -triple aarch64-none-linux-gnu \\\n" 3210b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "// RUN -target-feature +neon -ffreestanding -S -o - %s \\\n" 3211b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "// RUN: | FileCheck %s -check-prefix=CHECK_AARCH64\n" 3212b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "\n" 3213b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "// REQUIRES: long_tests\n" 3214b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "\n" 3215b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "#include <arm_neon.h>\n" 3216b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover "\n"; 3217b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3218b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // ARM tests must be emitted before AArch64 tests to ensure 3219b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // tests for intrinsics that are common to ARM and AArch64 3220b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // appear only once in the output stream. 3221b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover // The check for uniqueness is done in genTargetTest. 3222b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover StringMap<OpKind> EmittedMap; 3223b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3224b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genTargetTest(OS, EmittedMap, false); 3225b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover 3226b793f0d3448a15277cd6b6cc4ba558ded39a8084Tim Northover genTargetTest(OS, EmittedMap, true); 322751d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne} 322851d7777a21b9706d503496c650af06f80d278c1aPeter Collingbourne 32293cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesennamespace clang { 32303cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitNeon(RecordKeeper &Records, raw_ostream &OS) { 32313cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen NeonEmitter(Records).run(OS); 32323cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} 32333cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitNeonSema(RecordKeeper &Records, raw_ostream &OS) { 32343cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen NeonEmitter(Records).runHeader(OS); 32353cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} 32363cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesenvoid EmitNeonTest(RecordKeeper &Records, raw_ostream &OS) { 32373cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen NeonEmitter(Records).runTests(OS); 32383cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} 32393cc509b5ac0e99ef44c1bf8b57cd403b546abc3dJakob Stoklund Olesen} // End namespace clang 3240