18d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf//===- subzero/src/PNaClTranslator.cpp - ICE from bitcode -----------------===// 28d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// 38d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// The Subzero Code Generator 48d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// 58d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// This file is distributed under the University of Illinois Open Source 68d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// License. See LICENSE.TXT for details. 78d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// 88d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf//===----------------------------------------------------------------------===// 99612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// 109612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// \file 1192a6e5b08ec68e7076d637ebc680da2fcc346a00Jim Stichnoth/// \brief Implements the interface for translation from PNaCl bitcode files to 1292a6e5b08ec68e7076d637ebc680da2fcc346a00Jim Stichnoth/// ICE to machine code. 139612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// 148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf//===----------------------------------------------------------------------===// 158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1667f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "PNaClTranslator.h" 178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 18a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceCfg.h" 19a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceCfgNode.h" 20a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceClFlags.h" 21a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceDefs.h" 22e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf#include "IceGlobalInits.h" 23a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceInst.h" 24a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceOperand.h" 25dd6dcfaf765dc93ae64ec45d623106f4b3a3c13aJim Stichnoth#include "IceRangeSpec.h" 2698da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth 27b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth#ifdef __clang__ 2898da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth#pragma clang diagnostic push 2998da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth#pragma clang diagnostic ignored "-Wunused-parameter" 30b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth#endif // __clang__ 31b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth 3252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf#include "llvm/ADT/Hashing.h" 3367f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/ADT/SmallString.h" 3467f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" 3567f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" 3667f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" 3767f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" 3867f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 3967f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Support/Format.h" 4067f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Support/MemoryBuffer.h" 4167f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Support/raw_ostream.h" 42b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth 43b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth#ifdef __clang__ 4498da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth#pragma clang diagnostic pop 45b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth#endif // __clang__ 46b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth 47b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth#include <unordered_set> 488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 4952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf// Define a hash function for SmallString's, so that it can be used in hash 5052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf// tables. 5152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpfnamespace std { 5252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpftemplate <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> { 5352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf size_t operator()(const llvm::SmallString<InternalLen> &Key) const { 5452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf return llvm::hash_combine_range(Key.begin(), Key.end()); 5552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf } 5652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf}; 5752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf} // end of namespace std 5852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 598d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfnamespace { 609d98d791123ce157aab73fba210e4d068935011fKarl Schimpfusing namespace llvm; 618d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 6257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Models elements in the list of types defined in the types block. These 6357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// elements can be undefined, a (simple) type, or a function type signature. 6457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Note that an extended type is undefined on construction. Use methods 6557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// setAsSimpleType and setAsFuncSigType to define the extended type. 66645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfclass ExtendedType { 67645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType &operator=(const ExtendedType &Ty) = delete; 68dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth 69645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfpublic: 70645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Discriminator for LLVM-style RTTI. 71645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf enum TypeKind { Undefined, Simple, FuncSig }; 72645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 73eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth ExtendedType() = default; 747e571364bcc48d361b71c1402611873fb8544117Jim Stichnoth ExtendedType(const ExtendedType &Ty) = default; 75645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 76eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth virtual ~ExtendedType() = default; 77645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 78645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind getKind() const { return Kind; } 79aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf void dump(Ice::Ostream &Stream) const; 80645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 8157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Changes the extended type to a simple type with the given / value. 82645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setAsSimpleType(Ice::Type Ty) { 83645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf assert(Kind == Undefined); 84645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Kind = Simple; 85645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Signature.setReturnType(Ty); 86645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 87645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 88645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Changes the extended type to an (empty) function signature type. 89645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setAsFunctionType() { 90645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf assert(Kind == Undefined); 91645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Kind = FuncSig; 92645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 93645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 94645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfprotected: 9557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: For simple types, the return type of the signature will be used to 9657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // hold the simple type. 97645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::FuncSigType Signature; 98645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 99645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfprivate: 100eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth ExtendedType::TypeKind Kind = Undefined; 101645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf}; 102645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 103645aa1a9a21d41f523575afad356e76062e9d696Karl SchimpfIce::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) { 10420b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 105b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return Stream; 106aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ty.dump(Stream); 107645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Stream; 108645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf} 109645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 110645aa1a9a21d41f523575afad356e76062e9d696Karl SchimpfIce::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) { 11120b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 112b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return Stream; 113645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "ExtendedType::"; 114645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Kind) { 115645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case ExtendedType::Undefined: 116645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "Undefined"; 117645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 118645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case ExtendedType::Simple: 119645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "Simple"; 120645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 121645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case ExtendedType::FuncSig: 122645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "FuncSig"; 123645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 124645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 125645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Stream; 126645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf} 127645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 128645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf// Models an ICE type as an extended type. 129645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfclass SimpleExtendedType : public ExtendedType { 130c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth SimpleExtendedType() = delete; 131645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf SimpleExtendedType(const SimpleExtendedType &) = delete; 132645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf SimpleExtendedType &operator=(const SimpleExtendedType &) = delete; 133dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth 134645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfpublic: 135645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type getType() const { return Signature.getReturnType(); } 136645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 137645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf static bool classof(const ExtendedType *Ty) { 138645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ty->getKind() == Simple; 139645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 140645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf}; 141645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 142645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf// Models a function signature as an extended type. 143645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfclass FuncSigExtendedType : public ExtendedType { 144c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth FuncSigExtendedType() = delete; 145645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncSigExtendedType(const FuncSigExtendedType &) = delete; 146645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete; 147dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth 148645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfpublic: 149645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf const Ice::FuncSigType &getSignature() const { return Signature; } 150645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setReturnType(Ice::Type ReturnType) { 151645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Signature.setReturnType(ReturnType); 152645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 153645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); } 154645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf static bool classof(const ExtendedType *Ty) { 155645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ty->getKind() == FuncSig; 156645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 157645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf}; 158645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 159aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpfvoid ExtendedType::dump(Ice::Ostream &Stream) const { 16020b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 161b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return; 162645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << Kind; 163645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Kind) { 164645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Simple: { 165645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << " " << Signature.getReturnType(); 166645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 167645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 168645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case FuncSig: { 169645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << " " << Signature; 170645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 171645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 172645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 173645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 174645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf} 175645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 176a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf// Models integer literals as a sequence of bits. Used to read integer values 177a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf// from bitcode files. Based on llvm::APInt. 178a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpfclass BitcodeInt { 179a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf BitcodeInt() = delete; 180a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf BitcodeInt(const BitcodeInt &) = delete; 181a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf BitcodeInt &operator=(const BitcodeInt &) = delete; 182a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 183a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpfpublic: 184a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf BitcodeInt(Ice::SizeT Bits, uint64_t Val) : BitWidth(Bits), Val(Val) { 185a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf assert(Bits && "bitwidth too small"); 186a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf assert(Bits <= BITS_PER_WORD && "bitwidth too big"); 187a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf clearUnusedBits(); 188a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf } 189a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 190a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf int64_t getSExtValue() const { 191a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf return static_cast<int64_t>(Val << (BITS_PER_WORD - BitWidth)) >> 192a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf (BITS_PER_WORD - BitWidth); 193a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf } 194a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 195a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf template <typename IntType, typename FpType> 196a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf inline FpType convertToFp() const { 197a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf static_assert(sizeof(IntType) == sizeof(FpType), 198a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf "IntType and FpType should be the same width"); 199a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf assert(BitWidth == sizeof(IntType) * CHAR_BIT); 200a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf auto V = static_cast<IntType>(Val); 201b0051dfaca6e957fa62ab61c0ef2a42df7964d37Jim Stichnoth return Ice::Utils::bitCopy<FpType>(V); 202a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf } 203a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 204a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpfprivate: 205a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf /// Bits in the (internal) value. 206a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf static const Ice::SizeT BITS_PER_WORD = sizeof(uint64_t) * CHAR_BIT; 207a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 208a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf uint32_t BitWidth; /// The number of bits in the floating point number. 209a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf uint64_t Val; /// The (64-bit) equivalent integer value. 210a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 211a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf /// Clear unused high order bits. 212a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf void clearUnusedBits() { 213a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf // If all bits are used, we want to leave the value alone. 214a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf if (BitWidth == BITS_PER_WORD) 215a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf return; 216a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 217a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf // Mask out the high bits. 218a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf Val &= ~static_cast<uint64_t>(0) >> (BITS_PER_WORD - BitWidth); 219a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf } 220a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf}; 221a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf 2222f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpfclass BlockParserBaseClass; 2232f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 2248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// Top-level class to read PNaCl bitcode files, and translate to ICE. 225e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass TopLevelParser final : public NaClBitcodeParser { 226c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TopLevelParser() = delete; 2270795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth TopLevelParser(const TopLevelParser &) = delete; 2280795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth TopLevelParser &operator=(const TopLevelParser &) = delete; 2298d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 2308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 23122ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor, 23222ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Ice::ErrorCode &ErrorStatus) 23322ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf : NaClBitcodeParser(Cursor), Translator(Translator), 234eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth ErrorStatus(ErrorStatus), 235eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth VariableDeclarations(new Ice::VariableDeclarationList()) {} 2368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 237e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~TopLevelParser() override = default; 2388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 2396ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Ice::Translator &getTranslator() const { return Translator; } 240d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 24157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Generates error with given Message, occurring at BitPosition within the 24257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// bitcode file. Always returns true. 24317b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, 244e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const std::string &Message) override; 2452f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 24622ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf /// Generates error message with respect to the current block parser. 24774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool blockError(const std::string &Message); 2482f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 2498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf /// Changes the size of the type list to the given size. 25074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } 25174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf 25274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t getNumTypeIDValues() const { return TypeIDValues.size(); } 2538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 254a78e4baab1557beccdb7604175dcea97ef1afe06John Porto /// Returns a pointer to the pool where globals are allocated. 255a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Ice::VariableDeclarationList *getGlobalVariablesPool() { 256a78e4baab1557beccdb7604175dcea97ef1afe06John Porto return VariableDeclarations.get(); 257a78e4baab1557beccdb7604175dcea97ef1afe06John Porto } 258a78e4baab1557beccdb7604175dcea97ef1afe06John Porto 25957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the undefined type associated with type ID. Note: Returns extended 26057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// type ready to be defined. 26174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) { 26257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Get corresponding element, verifying the value is still undefined (and 26357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // hence allowed to be defined). 264645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); 2658d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Ty) 2668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Ty; 26774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (ID >= TypeIDValues.size()) { 26874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (ID >= NaClBcIndexSize_t_Max) { 26974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 27074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 27174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max 27274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf << " types\n"; 27374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 27474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf // Recover by using existing type slot. 27574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf return &TypeIDValues[0]; 27674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 2772f00bf6d866b33c9cf57e74a663bf771095ecc6bJim Stichnoth Ice::Utils::reserveAndResize(TypeIDValues, ID + 1); 27874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 279645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return &TypeIDValues[ID]; 2808d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 2818d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 282645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Returns the type associated with the given index. 28374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) { 284645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple); 285645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty == nullptr) 286645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Return error recovery value. 287645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ice::IceType_void; 288645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return cast<SimpleExtendedType>(Ty)->getType(); 289645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 290645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 291645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Returns the type signature associated with the given index. 29274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) { 293645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); 294645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty == nullptr) 295645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Return error recovery value. 296645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return UndefinedFuncSigType; 297645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return cast<FuncSigExtendedType>(Ty)->getSignature(); 2988d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 2998d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf /// Sets the next function ID to the given LLVM function. 3019d98d791123ce157aab73fba210e4d068935011fKarl Schimpf void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { 302209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf FunctionDeclarations.push_back(Fcn); 3038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 30557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the value id that should be associated with the the current 30657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// function block. Increments internal counters during call so that it will 30757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// be in correct position for next function block. 30874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t getNextFunctionBlockValueID() { 309209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf size_t NumDeclaredFunctions = FunctionDeclarations.size(); 3100c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf while (NextDefiningFunctionID < NumDeclaredFunctions && 311209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf FunctionDeclarations[NextDefiningFunctionID]->isProto()) 3120c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf ++NextDefiningFunctionID; 3130c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf if (NextDefiningFunctionID >= NumDeclaredFunctions) 31422ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal("More function blocks than defined function addresses"); 3150c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf return NextDefiningFunctionID++; 316d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 317d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 3189d98d791123ce157aab73fba210e4d068935011fKarl Schimpf /// Returns the function associated with ID. 31974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) { 320209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf if (ID < FunctionDeclarations.size()) 321209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf return FunctionDeclarations[ID]; 3229d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return reportGetFunctionByIDError(ID); 3238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3256ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf /// Returns the constant associated with the given global value ID. 32674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) { 3276ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(ID < ValueIDConstants.size()); 3286ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return ValueIDConstants[ID]; 3299d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 3309d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 33157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Install names for all global values without names. Called after the global 33257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// value symbol table is processed, but before any function blocks are 33357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// processed. 3346ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installGlobalNames() { 3356ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 3366ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installGlobalVarNames(); 3376ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installFunctionNames(); 3386ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 339e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 340bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf void verifyFunctionTypeSignatures(); 341bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf 3426ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void createValueIDs() { 3436ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 3446ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ValueIDConstants.reserve(VariableDeclarations->size() + 345209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf FunctionDeclarations.size()); 3466ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf createValueIDsForFunctions(); 3476ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf createValueIDsForGlobalVars(); 3488df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 3498df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 3509d98d791123ce157aab73fba210e4d068935011fKarl Schimpf /// Returns the number of function declarations in the bitcode file. 351209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); } 3528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 35357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the number of global declarations (i.e. IDs) defined in the 35457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// bitcode file. 35574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t getNumGlobalIDs() const { 3566ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (VariableDeclarations) { 357209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf return FunctionDeclarations.size() + VariableDeclarations->size(); 3586ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } else { 3596ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return ValueIDConstants.size(); 3606ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 3618d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3628d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 363aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf /// Adds the given global declaration to the end of the list of global 364aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf /// declarations. 365aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf void addGlobalDeclaration(Ice::VariableDeclaration *Decl) { 3666ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 367aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf VariableDeclarations->push_back(Decl); 3689d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 369e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 3709d98d791123ce157aab73fba210e4d068935011fKarl Schimpf /// Returns the global variable declaration with the given index. 37174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { 3726ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 3736ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (Index < VariableDeclarations->size()) 3746ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return VariableDeclarations->at(Index); 3759d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return reportGetGlobalVariableByIDError(Index); 3769d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 3779d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 37857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the global declaration (variable or function) with the given 37957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Index. 38074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { 381209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf size_t NumFunctionIds = FunctionDeclarations.size(); 3829d98d791123ce157aab73fba210e4d068935011fKarl Schimpf if (Index < NumFunctionIds) 3839d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return getFunctionByID(Index); 3849d98d791123ce157aab73fba210e4d068935011fKarl Schimpf else 3859d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return getGlobalVariableByID(Index - NumFunctionIds); 386e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf } 387e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 3880b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf /// Returns true if a module block has been parsed. 3890b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf bool parsedModuleBlock() const { return ParsedModuleBlock; } 3900b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf 39157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the list of parsed global variable declarations. Releases 39257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// ownership of the current list of global variables. Note: only returns 39357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// non-null pointer on first call. All successive calls return a null 39457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// pointer. 3956ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { 39657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Before returning, check that ValidIDConstants has already been built. 3976ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(!VariableDeclarations || 3986ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf VariableDeclarations->size() <= ValueIDConstants.size()); 3996ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return std::move(VariableDeclarations); 4008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 4018d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 40207af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf // Upper limit of alignment power allowed by LLVM 40307af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf static constexpr uint32_t AlignPowerLimit = 29; 40407af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf 40507af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf // Extracts the corresponding Alignment to use, given the AlignPower (i.e. 40607af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf // 2**(AlignPower-1), or 0 if AlignPower == 0). Parser defines the block 40707af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf // context the alignment check appears in, and Prefix defines the context the 40807af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf // alignment appears in. 40907af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf uint32_t extractAlignment(NaClBitcodeParser *Parser, const char *Prefix, 41007af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf uint32_t AlignPower) { 41107af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf if (AlignPower <= AlignPowerLimit + 1) 41207af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf return (1 << AlignPower) >> 1; 41307af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf std::string Buffer; 41407af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf raw_string_ostream StrBuf(Buffer); 41507af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf StrBuf << Prefix << " alignment greater than 2**" << AlignPowerLimit 41607af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf << ". Found: 2**" << (AlignPower - 1); 41707af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf Parser->Error(StrBuf.str()); 41807af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf // Error recover with value that is always acceptable. 41907af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf return 1; 42007af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf } 42107af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf 4228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 423d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The translator associated with the parser. 424d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Translator &Translator; 425e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 426e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // ErrorStatus should only be updated while this lock is locked. 427e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Ice::GlobalLockType ErrorReportingLock; 428b164d2085e870e2458c73c70c08ab69e56e2e081Karl Schimpf // The exit status that should be set to true if an error occurs. 429fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth Ice::ErrorCode &ErrorStatus; 430e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 4318d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // The types associated with each type ID. 432645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf std::vector<ExtendedType> TypeIDValues; 4330c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf // The set of functions (prototype and defined). 434209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Ice::FunctionDeclarationList FunctionDeclarations; 435209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // The ID of the next possible defined function ID in FunctionDeclarations. 436209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // FunctionDeclarations is filled first. It's the set of functions (either 437209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // defined or isproto). Then function definitions are encountered/parsed and 438209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // NextDefiningFunctionID is incremented to track the next actually-defined 439209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // function. 440eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth size_t NextDefiningFunctionID = 0; 4419d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // The set of global variables. 4426ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; 4439d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // Relocatable constants associated with global declarations. 444209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Ice::ConstantList ValueIDConstants; 445645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Error recovery value to use when getFuncSigTypeByID fails. 446645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::FuncSigType UndefinedFuncSigType; 4470b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf // Defines if a module block has already been parsed. 4480b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf bool ParsedModuleBlock = false; 4498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 4508e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 4518d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 45257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Gets extended type associated with the given index, assuming the extended 45357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // type is of the WantedKind. Generates error message if corresponding 45457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // extended type of WantedKind can't be found, and returns nullptr. 45574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, 456645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind WantedKind) { 457645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType *Ty = nullptr; 458645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (ID < TypeIDValues.size()) { 459645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ty = &TypeIDValues[ID]; 460645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty->getKind() == WantedKind) 461645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ty; 462645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 463645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Generate an error message and set ErrorStatus. 464645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf this->reportBadTypeIDAs(ID, Ty, WantedKind); 465645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return nullptr; 466645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 4678d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 46857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are 46957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // used to generate the name. NameIndex is automatically incremented if a new 470467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // name is created. DeclType is literal text describing the type of name being 471467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // created. Also generates a warning if created names may conflict with named 472467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // declarations. 4736ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installDeclarationName(Ice::GlobalDeclaration *Decl, 474467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth const std::string &Prefix, const char *DeclType, 47574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t &NameIndex) { 4766ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (Decl->hasName()) { 477467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Translator.checkIfUnnamedNameSafe(Decl->getName().toString(), DeclType, 478467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Prefix); 4796ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } else { 480467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Ice::GlobalContext *Ctx = Translator.getContext(); 481318c01bca3cebe3a452333a5bc4bf64b8ab817c8Jim Stichnoth // Synthesize a dummy name if any of the following is true: 482318c01bca3cebe3a452333a5bc4bf64b8ab817c8Jim Stichnoth // - DUMP is enabled 483318c01bca3cebe3a452333a5bc4bf64b8ab817c8Jim Stichnoth // - The symbol is external 484318c01bca3cebe3a452333a5bc4bf64b8ab817c8Jim Stichnoth // - The -timing-funcs flag is enabled 485dd6dcfaf765dc93ae64ec45d623106f4b3a3c13aJim Stichnoth // - Some RangeSpec is initialized with actual names 486318c01bca3cebe3a452333a5bc4bf64b8ab817c8Jim Stichnoth if (Ice::BuildDefs::dump() || !Decl->isInternal() || 487dd6dcfaf765dc93ae64ec45d623106f4b3a3c13aJim Stichnoth Ice::RangeSpec::hasNames() || Ice::getFlags().getTimeEachFunction()) { 488467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Decl->setName(Ctx, Translator.createUnnamedName(Prefix, NameIndex)); 489467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth } else { 490467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Decl->setName(Ctx); 491467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth } 4926ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ++NameIndex; 4936ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4946ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4956ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 4966ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Installs names for global variables without names. 4976ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installGlobalVarNames() { 4986ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 499d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf const std::string &GlobalPrefix = Ice::getFlags().getDefaultGlobalPrefix(); 5006ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!GlobalPrefix.empty()) { 50174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NameIndex = 0; 5026ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf for (Ice::VariableDeclaration *Var : *VariableDeclarations) { 5036ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installDeclarationName(Var, GlobalPrefix, "global", NameIndex); 5046ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5056ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5066ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5076ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 5086ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Installs names for functions without names. 5096ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installFunctionNames() { 510d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf const std::string &FunctionPrefix = 511d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf Ice::getFlags().getDefaultFunctionPrefix(); 5126ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!FunctionPrefix.empty()) { 51374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NameIndex = 0; 514209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf for (Ice::FunctionDeclaration *Func : FunctionDeclarations) { 5156ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installDeclarationName(Func, FunctionPrefix, "function", NameIndex); 5166ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5176ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5186ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5196ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 52098ba00666271be1bdcd45b72b3dec04419efe61bJim Stichnoth // Builds a constant symbol named Name. IsExternal is true iff the symbol is 52198ba00666271be1bdcd45b72b3dec04419efe61bJim Stichnoth // external. 522467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Ice::Constant *getConstantSym(Ice::GlobalString Name, bool IsExternal) const { 523467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Ice::GlobalContext *Ctx = getTranslator().getContext(); 5246ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (IsExternal) { 525467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth return Ctx->getConstantExternSym(Name); 5266ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } else { 5276ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf const Ice::RelocOffsetT Offset = 0; 528467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth return Ctx->getConstantSym(Offset, Name); 5296ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5306ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5316ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 532a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf void reportLinkageError(const char *Kind, 533a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf const Ice::GlobalDeclaration &Decl) { 534a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf std::string Buffer; 535a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf raw_string_ostream StrBuf(Buffer); 536a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf StrBuf << Kind << " " << Decl.getName() 537a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf << " has incorrect linkage: " << Decl.getLinkageName(); 538a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf if (Decl.isExternal()) 539a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf StrBuf << "\n Use flag -allow-externally-defined-symbols to override"; 540a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf Error(StrBuf.str()); 541a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf } 542a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf 5436ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Converts function declarations into constant value IDs. 5446ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void createValueIDsForFunctions() { 54557d31ac73a35263d42357259329fa7d3e565731bKarl Schimpf Ice::GlobalContext *Ctx = getTranslator().getContext(); 546209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) { 547a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf if (!Func->verifyLinkageCorrect(Ctx)) 548a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf reportLinkageError("Function", *Func); 54998ba00666271be1bdcd45b72b3dec04419efe61bJim Stichnoth Ice::Constant *C = getConstantSym(Func->getName(), Func->isProto()); 5506ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ValueIDConstants.push_back(C); 5516ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5526ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5536ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 5546ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Converts global variable declarations into constant value IDs. 5556ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void createValueIDsForGlobalVars() { 5566ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) { 557d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf if (!Decl->verifyLinkageCorrect()) 558a313a121cc46b81bca7472e43ed0ae72156e8974Karl Schimpf reportLinkageError("Global", *Decl); 5590d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth Ice::Constant *C = 56098ba00666271be1bdcd45b72b3dec04419efe61bJim Stichnoth getConstantSym(Decl->getName(), !Decl->hasInitializer()); 5616ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ValueIDConstants.push_back(C); 5626ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5636ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 5646ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 565645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Reports that type ID is undefined, or not of the WantedType. 56674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty, 567645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind WantedType); 568d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 56957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that there is no function declaration for ID. Returns an error 57057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // recovery value to use. 57174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID); 5729d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 57357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that there is not global variable declaration for ID. Returns an 57457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // error recovery value to use. 57574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::VariableDeclaration * 57674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); 5779d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 57857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that there is no corresponding ICE type for LLVMTy, and returns 57957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Ice::IceType_void. 580d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type convertToIceTypeError(Type *LLVMTy); 5818d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 5828d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 58317b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpfbool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, 58417b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf const std::string &Message) { 585819d7b56fe179db006d1c474b557230d8c8e5e2bKarl Schimpf Ice::GlobalContext *Context = Translator.getContext(); 586e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf { 587e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf std::unique_lock<Ice::GlobalLockType> _(ErrorReportingLock); 588e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ErrorStatus.assign(Ice::EC_Bitcode); 589e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf } 590d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf { // Lock while printing out error message. 591d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf Ice::OstreamLocker L(Context); 5922f67b929c15a30d5ed43b9929cac95a96fec0bbeKarl Schimpf raw_ostream &OldErrStream = setErrStream(Context->getStrError()); 593d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf NaClBitcodeParser::ErrorAt(Level, Bit, Message); 594d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf setErrStream(OldErrStream); 595d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf } 596d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf if (Level >= naclbitc::Error && !Ice::getFlags().getAllowErrorRecovery()) 59722ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal(); 5982f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return true; 5992f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf} 6002f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 60174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID, 60274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf const ExtendedType *Ty, 603645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind WantedType) { 6048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 6058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 606645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty == nullptr) { 607645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Can't find extended type for type id: " << ID; 6088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } else { 609645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; 6108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 61174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 6128d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 6138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 6149d98d791123ce157aab73fba210e4d068935011fKarl SchimpfIce::FunctionDeclaration * 61574cd883a0b3ccb0920e5990ed860b1862ac73090Karl SchimpfTopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) { 6169d98d791123ce157aab73fba210e4d068935011fKarl Schimpf std::string Buffer; 6179d98d791123ce157aab73fba210e4d068935011fKarl Schimpf raw_string_ostream StrBuf(Buffer); 6189d98d791123ce157aab73fba210e4d068935011fKarl Schimpf StrBuf << "Function index " << ID 6199d98d791123ce157aab73fba210e4d068935011fKarl Schimpf << " not allowed. Out of range. Must be less than " 620209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf << FunctionDeclarations.size(); 62174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 622209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf if (!FunctionDeclarations.empty()) 623209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf return FunctionDeclarations[0]; 62422ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal(); 6259d98d791123ce157aab73fba210e4d068935011fKarl Schimpf} 6269d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 6279d98d791123ce157aab73fba210e4d068935011fKarl SchimpfIce::VariableDeclaration * 62874cd883a0b3ccb0920e5990ed860b1862ac73090Karl SchimpfTopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) { 6299d98d791123ce157aab73fba210e4d068935011fKarl Schimpf std::string Buffer; 6309d98d791123ce157aab73fba210e4d068935011fKarl Schimpf raw_string_ostream StrBuf(Buffer); 6319d98d791123ce157aab73fba210e4d068935011fKarl Schimpf StrBuf << "Global index " << Index 6329d98d791123ce157aab73fba210e4d068935011fKarl Schimpf << " not allowed. Out of range. Must be less than " 6336ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf << VariableDeclarations->size(); 63474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 6356ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!VariableDeclarations->empty()) 6366ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return VariableDeclarations->at(0); 63722ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal(); 6389d98d791123ce157aab73fba210e4d068935011fKarl Schimpf} 6399d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 640d6064a1aaca7a5596618e559a17cb9b20283ca46Karl SchimpfIce::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { 641d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 642d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 643d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Invalid LLVM type: " << *LLVMTy; 644d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 645d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return Ice::IceType_void; 646d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 647d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 648bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpfvoid TopLevelParser::verifyFunctionTypeSignatures() { 649bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf const Ice::GlobalContext *Ctx = getTranslator().getContext(); 650bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf for (Ice::FunctionDeclaration *FuncDecl : FunctionDeclarations) { 651bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf if (!FuncDecl->validateTypeSignature(Ctx)) 652bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf Error(FuncDecl->getTypeSignatureError(Ctx)); 653bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf } 654bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf} 655bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf 65657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Base class for parsing blocks within the bitcode file. Note: Because this is 65757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// the base class of block parsers, we generate error messages if ParseBlock or 65857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// ParseRecord is not overridden in derived classes. 6598d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass BlockParserBaseClass : public NaClBitcodeParser { 660c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth BlockParserBaseClass() = delete; 6612f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf BlockParserBaseClass(const BlockParserBaseClass &) = delete; 6622f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; 6632f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 6648d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 6658d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Constructor for the top-level module block parser. 6668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) 667e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf : NaClBitcodeParser(BlockID, Context), Context(Context) {} 6682f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 669e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser, 670e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBitstreamCursor &Cursor) 671e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf : NaClBitcodeParser(BlockID, EnclosingParser, Cursor), 672e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Context(EnclosingParser->Context) {} 673e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 674e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ~BlockParserBaseClass() override {} 6752f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 6762f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf // Returns the printable name of the type of block being parsed. 6772f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf virtual const char *getBlockName() const { 6782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf // If this class is used, it is parsing an unknown block. 6792f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return "unknown"; 6802f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 6818d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 68222ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf // Generates an error Message with the Bit address prefixed to it. 68317b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, 684e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const std::string &Message) override; 6858d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 6868d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprotected: 6878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // The context parser that contains the decoded state. 6888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf TopLevelParser *Context; 689e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // True if ErrorAt has been called in this block. 690e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf bool BlockHasError = false; 6918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 6928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Constructor for nested block parsers. 6938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 6948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf : NaClBitcodeParser(BlockID, EnclosingParser), 6958d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Context(EnclosingParser->Context) {} 6968d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 697d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // Gets the translator associated with the bitcode parser. 6986ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf Ice::Translator &getTranslator() const { return Context->getTranslator(); } 6996ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf 70057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Default implementation. Reports that block is unknown and skips its 70157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // contents. 7028e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 7038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 70457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Default implementation. Reports that the record is not understood. 7058e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 7068d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 70757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the size of the record is Size. Return true if valid. Otherwise 70857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // generates an error and returns false. 70974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSize(size_t Size, const char *RecordName) { 7108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 711d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Values.size() == Size) 712d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 71374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportRecordSizeError(Size, RecordName, nullptr); 7148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 7158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 7168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 71757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the size of the record is at least as large as the LowerLimit. 71857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns true if valid. Otherwise generates an error and returns false. 71974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) { 7208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 721d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Values.size() >= LowerLimit) 722d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 72374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportRecordSizeError(LowerLimit, RecordName, "at least"); 7248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 7258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 7268d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 727d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // Checks if the size of the record is no larger than the 72857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // UpperLimit. Returns true if valid. Otherwise generates an error and 72957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // returns false. 73074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) { 7318d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 732d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Values.size() <= UpperLimit) 733d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 73474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportRecordSizeError(UpperLimit, RecordName, "no more than"); 7358d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 7368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 7378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 73857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the size of the record is at least as large as the LowerLimit, 73957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and no larger than the UpperLimit. Returns true if valid. Otherwise 74057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // generates an error and returns false. 74174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit, 742d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *RecordName) { 743d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidRecordSizeAtLeast(LowerLimit, RecordName) || 744d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf isValidRecordSizeAtMost(UpperLimit, RecordName); 7458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 7468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 7478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 74857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Generates a record size error. ExpectedSize is the number of elements 74957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// expected. RecordName is the name of the kind of record that has incorrect 75057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// size. ContextMessage (if not nullptr) is appended to "record expects" to 75157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// describe how ExpectedSize should be interpreted. 75274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, 753d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *ContextMessage); 7548d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 7558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 75674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfbool TopLevelParser::blockError(const std::string &Message) { 757e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // TODO(kschimpf): Remove this method. This method used to redirect 758e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // block-level errors to the block we are in, rather than the top-level 759e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // block. This gave better bit location for error messages. However, with 760e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // parallel parsing, we can't keep a field to redirect (there could be many 761e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // and we don't know which block parser applies). Hence, This redirect can't 762e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // be applied anymore. 763e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf return Error(Message); 7642f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf} 7652f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 7662f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf// Generates an error Message with the bit address prefixed to it. 767f644a4b3a36d707b32dd4b7855774a346a575e96Jan Voungbool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, 768f644a4b3a36d707b32dd4b7855774a346a575e96Jan Voung const std::string &Message) { 769e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf BlockHasError = true; 7702f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf std::string Buffer; 7712f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf raw_string_ostream StrBuf(Buffer); 77257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: If dump routines have been turned off, the error messages will not 77357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // be readable. Hence, replace with simple error. We also use the simple form 77457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // for unit tests. 775d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf if (Ice::getFlags().getGenerateUnitTestMessages()) { 7762f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); 7772f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf for (const uint64_t Val : Record.GetValues()) { 7782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << " " << Val; 7792f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 7802f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << ">"; 781df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf } else { 782df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf StrBuf << Message; 7832f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 7842a9d186d1cb3eb75f90f2c82ec7c84ee06c3b569Karl Schimpf return Context->ErrorAt(Level, Record.GetCursor().getErrorBitNo(Bit), 7852a9d186d1cb3eb75f90f2c82ec7c84ee06c3b569Karl Schimpf StrBuf.str()); 7862f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf} 7872f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 78874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize, 789d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *RecordName, 790d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *ContextMessage) { 791d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 792d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 7932f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *BlockName = getBlockName(); 7942f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char FirstChar = toupper(*BlockName); 7952f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << FirstChar << (BlockName + 1) << " " << RecordName 7962f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf << " record expects"; 797d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (ContextMessage) 798d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << " " << ContextMessage; 799d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << " " << ExpectedSize << " argument"; 800d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (ExpectedSize > 1) 801d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "s"; 802d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << ". Found: " << Record.GetValues().size(); 803d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 804d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 805d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 8068d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfbool BlockParserBaseClass::ParseBlock(unsigned BlockID) { 80757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // If called, derived class doesn't know how to handle block. Report error 80857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and skip. 8098d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 8108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 8118d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StrBuf << "Don't know how to parse block id: " << BlockID; 8128d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 8138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf SkipBlock(); 8148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 8158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 8168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 8178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid BlockParserBaseClass::ProcessRecord() { 8188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // If called, derived class doesn't know how to handle. 8198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 8208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 8212f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Don't know how to process " << getBlockName() 8222f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf << " record:" << Record; 8238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 8248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 8258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 8268d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// Class to parse a types block. 827e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass TypesParser final : public BlockParserBaseClass { 828c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TypesParser() = delete; 829c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TypesParser(const TypesParser &) = delete; 830c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TypesParser &operator=(const TypesParser &) = delete; 831c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth 8328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 8338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 83458455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser), 835eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} 8368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 83774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ~TypesParser() override { 83874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (ExpectedNumTypes != Context->getNumTypeIDValues()) { 83974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 84074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 84174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Types block expected " << ExpectedNumTypes 84274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf << " types but found: " << NextTypeId; 84374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 84474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 84574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 8468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 8478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 84858455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 84957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // The type ID that will be associated with the next type defining record in 85057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the types block. 85174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NextTypeId = 0; 85274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf 85374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf // The expected number of types, based on record TYPE_CODE_NUMENTRY. 85474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t ExpectedNumTypes = 0; 8558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 8568e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 857645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 8582f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "type"; } 8592f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 860645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setNextTypeIDAsSimpleType(Ice::Type Ty) { 861645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); 862645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 8638d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 8648d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 8658d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid TypesParser::ProcessRecord() { 8668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 8678d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 86874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf case naclbitc::TYPE_CODE_NUMENTRY: { 8698d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // NUMENTRY: [numentries] 8702f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "count")) 8718d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 87274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t Size = Values[0]; 87374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (Size > NaClBcIndexSize_t_Max) { 87474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 87574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 87674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Size to big for count record: " << Size; 87774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 87874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExpectedNumTypes = NaClBcIndexSize_t_Max; 87974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 88057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // The code double checks that Expected size and the actual size at the end 88157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // of the block. To reduce allocations we preallocate the space. 88274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf // 88357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // However, if the number is large, we suspect that the number is 88457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // (possibly) incorrect. In that case, we preallocate a smaller space. 88574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf constexpr uint64_t DefaultLargeResizeValue = 1000000; 88674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue)); 88774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExpectedNumTypes = Size; 8888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 88974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 8908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_VOID: 8918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VOID 8922f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "void")) 893d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 894645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_void); 895645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 8968d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_FLOAT: 8978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // FLOAT 8982f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "float")) 899d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 900645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_f32); 901645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 9028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_DOUBLE: 9038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // DOUBLE 9042f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "double")) 905d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 906645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_f64); 907645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 9088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_INTEGER: 9098d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // INTEGER: [width] 9102f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "integer")) 911d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 912645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Values[0]) { 913645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 1: 914645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i1); 915645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 916645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 8: 917645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i8); 918645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 919645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 16: 920645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i16); 921645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 922645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 32: 923645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i32); 924645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 925645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 64: 926645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i64); 927645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 928645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 929645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 930645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 931645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf { 932d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 933d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 934d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Type integer record with invalid bitsize: " << Values[0]; 935d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 936d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 937645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 938d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::TYPE_CODE_VECTOR: { 9398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VECTOR: [numelts, eltty] 9402f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "vector")) 941d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 942645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]); 943645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::SizeT Size = Values[0]; 944645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (BaseTy) { 945645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i1: 946645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Size) { 947645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 4: 948645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v4i1); 949645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 950645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 8: 951645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v8i1); 952645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 953645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 16: 954645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v16i1); 955645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 956645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 957645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 958645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 959645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 960645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i8: 961645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 16) { 962645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v16i8); 963645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 964645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 965645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 966645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i16: 967645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 8) { 968645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v8i16); 969645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 970645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 971645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 972645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i32: 973645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 4) { 974645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v4i32); 975645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 976645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 977645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 978645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_f32: 979645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 4) { 980645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v4f32); 981645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 982645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 983645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 984645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 985645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 986645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 987645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf { 988d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 989d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 990645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy 991d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf << ">"; 992d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 993d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 994645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 995d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 9968d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_FUNCTION: { 9978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // FUNCTION: [vararg, retty, paramty x N] 9982f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "signature")) 999d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 1000645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Values[0]) 1001645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Error("Function type can't define varargs"); 1002645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++); 1003645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ty->setAsFunctionType(); 100454f3d518805b04b3f2958b7906a7d07dedb4e1aeJim Stichnoth auto *FuncTy = cast<FuncSigExtendedType>(Ty); 1005645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); 100674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf for (size_t i = 2, e = Values.size(); i != e; ++i) { 100757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Check that type void not used as argument type. Note: PNaCl 100857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // restrictions can't be checked until we know the name, because we have 100957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // to check for intrinsic signatures. 1010645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]); 1011645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (ArgTy == Ice::IceType_void) { 1012645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf std::string Buffer; 1013645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf raw_string_ostream StrBuf(Buffer); 1014645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Type for parameter " << (i - 1) 1015645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf << " not valid. Found: " << ArgTy; 1016645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ArgTy = Ice::IceType_i32; 1017645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 1018645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncTy->appendArgType(ArgTy); 10198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1020645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 10218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 10238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 1024d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 10258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1026645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf llvm_unreachable("Unknown type block record not processed!"); 10278d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 10288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 10299d98d791123ce157aab73fba210e4d068935011fKarl Schimpf/// Parses the globals block (i.e. global variable declarations and 10309d98d791123ce157aab73fba210e4d068935011fKarl Schimpf/// corresponding initializers). 1031e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass GlobalsParser final : public BlockParserBaseClass { 1032c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth GlobalsParser() = delete; 1033c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth GlobalsParser(const GlobalsParser &) = delete; 1034c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth GlobalsParser &operator=(const GlobalsParser &) = delete; 1035c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth 10368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 10378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 103858455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser), 103958455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), 1040aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NumFunctionIDs(Context->getNumFunctionIDs()), 1041a78e4baab1557beccdb7604175dcea97ef1afe06John Porto DummyGlobalVar(Ice::VariableDeclaration::create( 1042a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Context->getGlobalVariablesPool())), 1043a78e4baab1557beccdb7604175dcea97ef1afe06John Porto CurGlobalVar(DummyGlobalVar) { 1044a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Context->getGlobalVariablesPool()->willNotBeEmitted(DummyGlobalVar); 1045a78e4baab1557beccdb7604175dcea97ef1afe06John Porto } 10468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1047e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ~GlobalsParser() override = default; 10486fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 10492f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "globals"; } 10502f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 10518d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 10528072bae156fa62e51e02925997992c4908a2682fAndrew Scull using GlobalVarsMapType = 10538072bae156fa62e51e02925997992c4908a2682fAndrew Scull std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; 1054aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 105558455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 1056aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1057aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Holds global variables generated/referenced in the global variables block. 1058aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf GlobalVarsMapType GlobalVarsMap; 1059aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1060aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Holds the number of defined function IDs. 1061aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t NumFunctionIDs; 1062aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 106357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Holds the specified number of global variables by the count record in the 106457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // global variables block. 1065aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t SpecifiedNumberVars = 0; 1066aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1067e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // Keeps track of how many initializers are expected for the global variable 10689d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // declaration being built. 106974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t InitializersNeeded = 0; 10708d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 10719d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // The index of the next global variable declaration. 107274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NextGlobalID = 0; 10738d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 107457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Dummy global variable declaration to guarantee CurGlobalVar is always 107557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // defined (allowing code to not need to check if CurGlobalVar is nullptr). 10769d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::VariableDeclaration *DummyGlobalVar; 1077e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 10789d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // Holds the current global variable declaration being built. 10799d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::VariableDeclaration *CurGlobalVar; 1080e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 1081aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Returns the global variable associated with the given Index. 1082aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) { 1083aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index]; 1084aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (Decl == nullptr) 1085a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Decl = 1086a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Ice::VariableDeclaration::create(Context->getGlobalVariablesPool()); 1087aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return Decl; 1088aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 1089aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1090aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Returns the global declaration associated with the given index. 1091aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) { 1092aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (Index < NumFunctionIDs) 1093aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return Context->getFunctionByID(Index); 1094aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return getGlobalVarByID(Index - NumFunctionIDs); 1095aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 1096aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1097aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // If global variables parsed correctly, install them into the top-level 1098aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // context. 1099aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf void installGlobalVariables() { 1100aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Verify specified number of globals matches number found. 1101aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf size_t NumGlobals = GlobalVarsMap.size(); 1102aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (SpecifiedNumberVars != NumGlobals || 1103aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf SpecifiedNumberVars != NextGlobalID) { 11048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 11058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 1106aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars 1107aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf << " global variables. Found: " << GlobalVarsMap.size(); 11088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 1109aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return; 11108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1111aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Install global variables into top-level context. 1112aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf for (size_t I = 0; I < NumGlobals; ++I) 1113aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Context->addGlobalDeclaration(GlobalVarsMap[I]); 1114aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 1115aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1116aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf void ExitBlock() override { 1117aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf verifyNoMissingInitializers(); 1118aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf installGlobalVariables(); 11198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ExitBlock(); 11208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 11228e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 11238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 11249d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // Checks if the number of initializers for the CurGlobalVar is the same as 1125e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // the number found in the bitcode file. If different, and error message is 1126e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // generated, and the internal state of the parser is fixed so this condition 1127e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // is no longer violated. 11288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf void verifyNoMissingInitializers() { 11299d98d791123ce157aab73fba210e4d068935011fKarl Schimpf size_t NumInits = CurGlobalVar->getInitializers().size(); 1130e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (InitializersNeeded != NumInits) { 11318d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 11328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 1133e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf StrBuf << "Global variable @g" << NextGlobalID << " expected " 11348d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf << InitializersNeeded << " initializer"; 11358d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (InitializersNeeded > 1) 11368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StrBuf << "s"; 1137e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf StrBuf << ". Found: " << NumInits; 11388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 11399d98d791123ce157aab73fba210e4d068935011fKarl Schimpf InitializersNeeded = NumInits; 11408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 11438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 11448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid GlobalsParser::ProcessRecord() { 11458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 11468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 11478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_COUNT: 11488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // COUNT: [n] 11492f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "count")) 11508d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 1151aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (SpecifiedNumberVars || NextGlobalID) { 11528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error("Globals count record not first in block."); 11538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11548d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1155aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf SpecifiedNumberVars = Values[0]; 11568d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11578d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_VAR: { 11588d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VAR: [align, isconst] 11592f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "variable")) 11608d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11618d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf verifyNoMissingInitializers(); 1162aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Always build the global variable, even if IR generation is turned off. 1163aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // This is needed because we need a placeholder in the top-level context 1164aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // when no IR is generated. 116507af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf uint32_t Alignment = 116607af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf Context->extractAlignment(this, "Global variable", Values[0]); 1167aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf CurGlobalVar = getGlobalVarByID(NextGlobalID); 11680d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth InitializersNeeded = 1; 11690d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth CurGlobalVar->setAlignment(Alignment); 11700d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth CurGlobalVar->setIsConstant(Values[1] != 0); 1171e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf ++NextGlobalID; 11728d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11738d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11748d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_COMPOUND: 11758d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // COMPOUND: [size] 11762f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "compound")) 11778d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11789d98d791123ce157aab73fba210e4d068935011fKarl Schimpf if (!CurGlobalVar->getInitializers().empty()) { 11798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error("Globals compound record not first initializer"); 11808d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11818d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11828d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Values[0] < 2) { 11838d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 11848d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 11852f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << getBlockName() 11862f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf << " compound record size invalid. Found: " << Values[0]; 11878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 11888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11898d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf InitializersNeeded = Values[0]; 11918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_ZEROFILL: { 11938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // ZEROFILL: [size] 11942f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "zerofill")) 11958d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 1196a78e4baab1557beccdb7604175dcea97ef1afe06John Porto auto *Pool = Context->getGlobalVariablesPool(); 11979d98d791123ce157aab73fba210e4d068935011fKarl Schimpf CurGlobalVar->addInitializer( 1198a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Ice::VariableDeclaration::ZeroInitializer::create(Pool, Values[0])); 11999d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return; 12008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12018d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_DATA: { 12028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // DATA: [b0, b1, ...] 12032f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(1, "data")) 12048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 1205a78e4baab1557beccdb7604175dcea97ef1afe06John Porto auto *Pool = Context->getGlobalVariablesPool(); 12069d98d791123ce157aab73fba210e4d068935011fKarl Schimpf CurGlobalVar->addInitializer( 1207a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Ice::VariableDeclaration::DataInitializer::create(Pool, Values)); 12089d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return; 12098d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_RELOC: { 12118d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // RELOC: [val, [addend]] 12122f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeInRange(1, 2, "reloc")) 12138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 1214aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t Index = Values[0]; 1215aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs; 1216aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (Index >= IndexLimit) { 1217aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf std::string Buffer; 1218aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf raw_string_ostream StrBuf(Buffer); 1219aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf StrBuf << "Relocation index " << Index << " to big. Expect index < " 1220aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf << IndexLimit; 1221aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Error(StrBuf.str()); 1222aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 122374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t Offset = 0; 122474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (Values.size() == 2) { 1225e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf Offset = Values[1]; 122674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (Offset > std::numeric_limits<uint32_t>::max()) { 122774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 122874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 122974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Addend of global reloc record too big: " << Offset; 123074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 123174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 123274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 1233a78e4baab1557beccdb7604175dcea97ef1afe06John Porto auto *Pool = Context->getGlobalVariablesPool(); 1234844211e75761ad4a87a9685f2b6b43eb2234485bJohn Porto Ice::GlobalContext *Ctx = getTranslator().getContext(); 12351bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto CurGlobalVar->addInitializer( 12361bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Ice::VariableDeclaration::RelocInitializer::create( 1237a78e4baab1557beccdb7604175dcea97ef1afe06John Porto Pool, getGlobalDeclByID(Index), 1238a78e4baab1557beccdb7604175dcea97ef1afe06John Porto {Ice::RelocOffset::create(Ctx, Offset)})); 12399d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return; 12408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 12428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 12438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 12448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 12468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1247c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf/// Base class for parsing a valuesymtab block in the bitcode file. 12488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass ValuesymtabParser : public BlockParserBaseClass { 1249c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ValuesymtabParser() = delete; 12500795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ValuesymtabParser(const ValuesymtabParser &) = delete; 12510795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth void operator=(const ValuesymtabParser &) = delete; 12528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 12538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 1254c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 1255c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser) {} 12568d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1257e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ValuesymtabParser() override = default; 12588d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 12592f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "valuesymtab"; } 12602f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 1261c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfprotected: 12628072bae156fa62e51e02925997992c4908a2682fAndrew Scull using StringType = SmallString<128>; 1263c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 126452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // Returns the name to identify the kind of symbol table this is 126552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // in error messages. 126652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf virtual const char *getTableKind() const = 0; 126752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 1268c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Associates Name with the value defined by the given Index. 126974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1270c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 1271c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Associates Name with the value defined by the given Index; 127274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1273c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 127452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // Reports that the assignment of Name to the value associated with 127552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // index is not possible, for the given Context. 127652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, 127752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StringType &Name); 127852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 12798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 128052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf using NamesSetType = std::unordered_set<StringType>; 128152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf NamesSetType ValueNames; 128252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf NamesSetType BlockNames; 128352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 12848e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 12858d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 128652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // Extracts out ConvertedName. Returns true if unique wrt to Names. 128752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf bool convertToString(NamesSetType &Names, StringType &ConvertedName) { 12888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 12898d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf for (size_t i = 1, e = Values.size(); i != e; ++i) { 12908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ConvertedName += static_cast<char>(Values[i]); 12918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 129252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf auto Pair = Names.insert(ConvertedName); 129352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf return Pair.second; 12948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 129552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 129652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void ReportDuplicateName(const char *NameCat, StringType &Name); 12978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 12988d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 129952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpfvoid ValuesymtabParser::reportUnableToAssign(const char *Context, 130052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf NaClBcIndexSize_t Index, 130152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StringType &Name) { 130252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf std::string Buffer; 130352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf raw_string_ostream StrBuf(Buffer); 130452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StrBuf << getTableKind() << " " << getBlockName() << ": " << Context 130552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf << " name '" << Name << "' can't be associated with index " << Index; 130652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf Error(StrBuf.str()); 130752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf} 130852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 130952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpfvoid ValuesymtabParser::ReportDuplicateName(const char *NameCat, 131052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StringType &Name) { 131152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf std::string Buffer; 131252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf raw_string_ostream StrBuf(Buffer); 131352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate " 131452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf << NameCat << " name: '" << Name << "'"; 131552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf Error(StrBuf.str()); 131652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf} 131752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 13188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid ValuesymtabParser::ProcessRecord() { 13198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 13208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StringType ConvertedName; 13218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 13228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::VST_CODE_ENTRY: { 13238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VST_ENTRY: [ValueId, namechar x N] 13242f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "value entry")) 13258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 132652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf if (convertToString(ValueNames, ConvertedName)) 132752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf setValueName(Values[0], ConvertedName); 132852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf else 132952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf ReportDuplicateName("value", ConvertedName); 13308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 13318d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 13328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::VST_CODE_BBENTRY: { 13338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VST_BBENTRY: [BbId, namechar x N] 13342f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "basic block entry")) 13358d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 133652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf if (convertToString(BlockNames, ConvertedName)) 133752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf setBbName(Values[0], ConvertedName); 133852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf else 133952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf ReportDuplicateName("block", ConvertedName); 1340c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return; 13418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 13428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 13438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf break; 13448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 13458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // If reached, don't know how to handle record. 13468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 13478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 13488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 13498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1350d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf/// Parses function blocks in the bitcode file. 1351e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass FunctionParser final : public BlockParserBaseClass { 1352c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth FunctionParser() = delete; 13530795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth FunctionParser(const FunctionParser &) = delete; 13540795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth FunctionParser &operator=(const FunctionParser &) = delete; 1355d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 1356d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfpublic: 1357e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, 1358e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBcIndexSize_t FcnId) 1359d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser), 136058455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), 1361e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), 1362e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), 1363eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth NextLocalInstIndex(Context->getNumGlobalIDs()) {} 13648e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 1365e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser, 1366e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBcIndexSize_t FcnId, NaClBitstreamCursor &Cursor) 1367e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser, Cursor), 1368e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), 1369e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Func(nullptr), FuncDecl(Context->getFunctionByID(FcnId)), 1370e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), 1371e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NextLocalInstIndex(Context->getNumGlobalIDs()) {} 1372e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 1373e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf std::unique_ptr<Ice::Cfg> parseFunction(uint32_t SeqNumber) { 1374e82b560e649f8a68bcb252b9b002708e74d962d3John Porto bool ParserResult; 1375e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Ice::GlobalContext *Ctx = getTranslator().getContext(); 1376e82b560e649f8a68bcb252b9b002708e74d962d3John Porto { 1377e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Ice::TimerMarker T(Ctx, FuncDecl->getName().toStringOrEmpty()); 1378b88d8c878538d856b845bd5cabdff7e75ef2761aJim Stichnoth // Note: The Cfg is created, even when IR generation is disabled. This is 1379b88d8c878538d856b845bd5cabdff7e75ef2761aJim Stichnoth // done to install a CfgLocalAllocator for various internal containers. 1380467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Ice::GlobalContext *Ctx = getTranslator().getContext(); 1381e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Func = Ice::Cfg::create(Ctx, SeqNumber); 1382b88d8c878538d856b845bd5cabdff7e75ef2761aJim Stichnoth 1383e82b560e649f8a68bcb252b9b002708e74d962d3John Porto Ice::CfgLocalAllocatorScope _(Func.get()); 1384e82b560e649f8a68bcb252b9b002708e74d962d3John Porto 1385e82b560e649f8a68bcb252b9b002708e74d962d3John Porto // TODO(kschimpf) Clean up API to add a function signature to a CFG. 1386e82b560e649f8a68bcb252b9b002708e74d962d3John Porto const Ice::FuncSigType &Signature = FuncDecl->getSignature(); 1387e82b560e649f8a68bcb252b9b002708e74d962d3John Porto 1388e82b560e649f8a68bcb252b9b002708e74d962d3John Porto Func->setFunctionName(FuncDecl->getName()); 1389e82b560e649f8a68bcb252b9b002708e74d962d3John Porto Func->setReturnType(Signature.getReturnType()); 1390e82b560e649f8a68bcb252b9b002708e74d962d3John Porto Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); 1391e82b560e649f8a68bcb252b9b002708e74d962d3John Porto CurrentNode = installNextBasicBlock(); 1392e82b560e649f8a68bcb252b9b002708e74d962d3John Porto Func->setEntryNode(CurrentNode); 1393e82b560e649f8a68bcb252b9b002708e74d962d3John Porto for (Ice::Type ArgType : Signature.getArgList()) { 1394e82b560e649f8a68bcb252b9b002708e74d962d3John Porto Func->addArg(getNextInstVar(ArgType)); 1395e82b560e649f8a68bcb252b9b002708e74d962d3John Porto } 13960d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth 1397e82b560e649f8a68bcb252b9b002708e74d962d3John Porto ParserResult = ParseThisBlock(); 13988e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth } 13998e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 1400e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf if (ParserResult || BlockHasError) 1401e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Func->setError("Unable to parse function"); 1402e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 1403e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf return std::move(Func); 1404d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1405d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 1406e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ~FunctionParser() override = default; 1407d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 14082f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "function"; } 14092f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 14108e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::Cfg *getFunc() const { return Func.get(); } 14112f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 141274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } 14132f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 14146fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf void setNextLocalInstIndex(Ice::Operand *Op) { 14156fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setOperand(NextLocalInstIndex++, Op); 14168f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 1417f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 14186fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // Set the next constant ID to the given constant C. 14196fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } 14206fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 14212f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf // Returns the value referenced by the given value Index. 142274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Operand *getOperand(NaClBcIndexSize_t Index) { 14232f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (Index < CachedNumGlobalValueIDs) { 14246ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return Context->getGlobalConstantByID(Index); 14252f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 142674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 14279d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf if (LocalIndex >= LocalOperands.size()) 14289d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf reportGetOperandUndefined(Index); 14292f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf Ice::Operand *Op = LocalOperands[LocalIndex]; 14309d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf if (Op == nullptr) 14319d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf reportGetOperandUndefined(Index); 14322f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return Op; 14332f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 14342f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 1435d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfprivate: 143658455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 143798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // The number of words in the bitstream defining the function block. 143898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf uint64_t NumBytesDefiningFunction = 0; 14397a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // Maximum number of records that can appear in the function block, based on 14407a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // the number of bytes defining the function block. 14417a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf uint64_t MaxRecordsInBlock = 0; 1442d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The corresponding ICE function defined by the function block. 14438e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth std::unique_ptr<Ice::Cfg> Func; 1444d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The index to the current basic block being built. 144574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t CurrentBbIndex = 0; 144698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // The number of basic blocks declared for the function block. 144798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf NaClBcIndexSize_t DeclaredNumberBbs = 0; 1448d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The basic block being built. 1449eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Ice::CfgNode *CurrentNode = nullptr; 14509d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // The corresponding function declaration. 14519d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::FunctionDeclaration *FuncDecl; 14528f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Holds the dividing point between local and global absolute value indices. 145374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t CachedNumGlobalValueIDs; 145457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Holds operands local to the function block, based on indices defined in 145557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the bitcode file. 1456209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Ice::OperandList LocalOperands; 145757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Holds the index within LocalOperands corresponding to the next instruction 145857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // that generates a value. 145974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NextLocalInstIndex; 146057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // True if the last processed instruction was a terminating instruction. 1461eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth bool InstIsTerminating = false; 146241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 14638e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 1464f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 14658e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 1466d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 1467e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf void EnterBlock(unsigned NumWords) override { 146898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Note: Bitstream defines words as 32-bit values. 146998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf NumBytesDefiningFunction = NumWords * sizeof(uint32_t); 14707a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // We know that all records are minimally defined by a two-bit abreviation. 14717a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); 147298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 1473d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 147498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf void ExitBlock() override; 1475d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 147698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Creates and appends a new basic block to the list of basic blocks. 147798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Ice::CfgNode *installNextBasicBlock() { 147898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Ice::CfgNode *Node = Func->makeNode(); 147998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return Node; 148098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 148198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 148298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Returns the Index-th basic block in the list of basic blocks. 148398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { 148498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (Index >= Func->getNumNodes()) { 148598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf std::string Buffer; 148698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf raw_string_ostream StrBuf(Buffer); 148798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf StrBuf << "Reference to basic block " << Index 148898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << " not found. Must be less than " << Func->getNumNodes(); 148998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error(StrBuf.str()); 149098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Index = 0; 149198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 149298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return Func->getNodes()[Index]; 149398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 149498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 149557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns the Index-th basic block in the list of basic blocks. Assumes 149657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Index corresponds to a branch instruction. Hence, if the branch references 149757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the entry block, it also generates a corresponding error. 149874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { 1499c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf if (Index == 0) { 1500c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Error("Branch to entry block not allowed"); 1501c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 150247661568f8c3811634913cfb43144a95d8340758Karl Schimpf return getBasicBlock(Index); 1503c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 1504c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf 15058f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Generate an instruction variable with type Ty. 15068f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Variable *createInstVar(Ice::Type Ty) { 150747661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (Ty == Ice::IceType_void) { 150847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error("Can't define instruction value using type void"); 150947661568f8c3811634913cfb43144a95d8340758Karl Schimpf // Recover since we can't throw an exception. 151047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ty = Ice::IceType_i32; 151147661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 1512144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth return Func->makeVariable(Ty); 15138f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15148f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15158f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Generates the next available local variable using the given type. 15168f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Variable *getNextInstVar(Ice::Type Ty) { 15178f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); 15188f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Before creating one, see if a forwardtyperef has already defined it. 151974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; 15208f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf if (LocalIndex < LocalOperands.size()) { 15218f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Operand *Op = LocalOperands[LocalIndex]; 1522e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (Op != nullptr) { 152354f3d518805b04b3f2958b7906a7d07dedb4e1aeJim Stichnoth if (auto *Var = dyn_cast<Ice::Variable>(Op)) { 15248f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf if (Var->getType() == Ty) { 15258f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf ++NextLocalInstIndex; 15268f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return Var; 15278f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15288f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15298f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf std::string Buffer; 15308f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf raw_string_ostream StrBuf(Buffer); 15318f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf StrBuf << "Illegal forward referenced instruction (" 15328f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf << NextLocalInstIndex << "): " << *Op; 15338f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Error(StrBuf.str()); 15348f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf ++NextLocalInstIndex; 15358f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return createInstVar(Ty); 15368f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15378f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15388f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Variable *Var = createInstVar(Ty); 15398f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf setOperand(NextLocalInstIndex++, Var); 1540d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return Var; 1541d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1542d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 154357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Converts a relative index (wrt to BaseIndex) to an absolute value index. 154474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id, 154574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClRelBcIndexSize_t BaseIndex) { 154647661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (BaseIndex < Id) { 1547d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 1548d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 1549d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Invalid relative value id: " << Id 155047661568f8c3811634913cfb43144a95d8340758Karl Schimpf << " (must be <= " << BaseIndex << ")"; 1551d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 1552d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return 0; 1553d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 155447661568f8c3811634913cfb43144a95d8340758Karl Schimpf return BaseIndex - Id; 1555d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1556d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 15578f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Sets element Index (in the local operands list) to Op. 155874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) { 15590d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth assert(Op); 15608f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Check if simple push works. 156174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 15627a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (LocalIndex == LocalOperands.size()) { 15637a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands.push_back(Op); 15647a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf return; 15657a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf } 15667a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf 15677a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // Must be forward reference, expand vector to accommodate. 15687a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (LocalIndex >= LocalOperands.size()) { 15697a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (LocalIndex > MaxRecordsInBlock) { 15707a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf std::string Buffer; 15717a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf raw_string_ostream StrBuf(Buffer); 15727a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf StrBuf << "Forward reference @" << Index << " too big. Have " 15737a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf << CachedNumGlobalValueIDs << " globals and function contains " 15747a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf << NumBytesDefiningFunction << " bytes"; 15757a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf Fatal(StrBuf.str()); 15767a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // Recover by using index one beyond the maximal allowed. 15777a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalIndex = MaxRecordsInBlock; 15787a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf } 15792f00bf6d866b33c9cf57e74a663bf771095ecc6bJim Stichnoth Ice::Utils::reserveAndResize(LocalOperands, LocalIndex + 1); 15807a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf } 15818f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15828f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // If element not defined, set it. 15837a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf Ice::Operand *OldOp = LocalOperands[LocalIndex]; 15847a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (OldOp == nullptr) { 15857a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands[LocalIndex] = Op; 15868f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return; 15878f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15888f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15897a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // See if forward reference matches. 15907a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (OldOp == Op) 15918f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return; 15928f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15938f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Error has occurred. 15948f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf std::string Buffer; 15958f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf raw_string_ostream StrBuf(Buffer); 1596d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Multiple definitions for index " << Index << ": " << *Op 15977a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf << " and " << *OldOp; 15988f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Error(StrBuf.str()); 15997a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands[LocalIndex] = Op; 1600d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1601d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 160257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns the relative operand (wrt to BaseIndex) referenced by the given 160357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // value Index. 160474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, 160574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t BaseIndex) { 160647661568f8c3811634913cfb43144a95d8340758Karl Schimpf return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); 160747661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 160847661568f8c3811634913cfb43144a95d8340758Karl Schimpf 160947661568f8c3811634913cfb43144a95d8340758Karl Schimpf // Returns the absolute index of the next value generating instruction. 161074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; } 161171ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf 161257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Generates type error message for binary operator Op operating on Type 161357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // OpTy. 161474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); 1615d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 161657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Validates if integer logical Op, for type OpTy, is valid. Returns true if 161757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // valid. Otherwise generates error message and returns false. 1618d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1619d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Ice::isIntegerType(OpTy)) 1620d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 162174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportInvalidBinaryOp(Op, OpTy); 1622d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1623d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1624d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 162557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Validates if integer (or vector of integers) arithmetic Op, for type OpTy, 162657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // is valid. Returns true if valid. Otherwise generates error message and 162757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // returns false. 1628d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1629d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Ice::isIntegerArithmeticType(OpTy)) 1630d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 163174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportInvalidBinaryOp(Op, OpTy); 1632d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1633d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1634d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 163557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if 163657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // valid. Otherwise generates an error message and returns false; 1637d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1638d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Ice::isFloatingType(OpTy)) 1639d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 164074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportInvalidBinaryOp(Op, OpTy); 1641d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1642d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1643d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 164457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the type of operand Op is the valid pointer type, for the given 164557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // InstructionName. Returns true if valid. Otherwise generates an error 164657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // message and returns false. 164741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { 16484019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf Ice::Type PtrType = Ice::getPointerType(); 164941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (Op->getType() == PtrType) 165041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return true; 165141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 165241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 165341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstructionName << " address not " << PtrType 1654fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf << ". Found: " << Op->getType(); 165541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 165641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 165741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 165841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 165957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if loading/storing a value of type Ty is allowed. Returns true if 166057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Valid. Otherwise generates an error message and returns false. 166141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) { 166241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (isLoadStoreType(Ty)) 166341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return true; 166441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 166541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 166641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstructionName << " type not allowed: " << Ty << "*"; 166741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 166841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 166941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 167041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 167157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if loading/storing a value of type Ty is allowed for the given 167257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Alignment. Otherwise generates an error message and returns false. 1673f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty, 167441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf const char *InstructionName) { 167541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (!isValidLoadStoreType(Ty, InstructionName)) 167641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 1677f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf if (isAllowedAlignment(Alignment, Ty)) 167841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return true; 167941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 168041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 168141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " 168241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf << Alignment; 168341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 168441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 168541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 168641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 1687f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf // Defines if the given alignment is valid for the given type. Simplified 168857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // version of PNaClABIProps::isAllowedAlignment, based on API's offered for 168957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Ice::Type. 1690f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const { 1691f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf return Alignment == typeAlignInBytes(Ty) || 1692f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf (Alignment == 1 && !isVectorType(Ty)); 1693f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf } 1694f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf 1695aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // Types of errors that can occur for insertelement and extractelement 1696aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // instructions. 1697aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf enum VectorIndexCheckValue { 1698aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotVector, 1699aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotConstant, 1700aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotInRange, 1701aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotI32, 1702aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexValid 1703aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf }; 1704aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 1705aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf void dumpVectorIndexCheckValue(raw_ostream &Stream, 1706aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue Value) const { 170720b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 1708b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return; 1709aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf switch (Value) { 1710aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotVector: 1711aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index on non vector"; 1712aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1713aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotConstant: 1714aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index not integer constant"; 1715aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1716aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotInRange: 1717aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index not in range of vector"; 1718aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1719aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotI32: 1720aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index not of type " << Ice::IceType_i32; 1721aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1722aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexValid: 1723aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Valid vector index"; 1724aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1725aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 1726aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 1727aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 1728aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // Returns whether the given vector index (for insertelement and 1729aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // extractelement instructions) is valid. 1730aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec, 1731aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf const Ice::Operand *Index) const { 1732aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type VecType = Vec->getType(); 1733aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!Ice::isVectorType(VecType)) 1734aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotVector; 1735aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); 1736aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (C == nullptr) 1737aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotConstant; 1738d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType)) 1739aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotInRange; 1740aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (Index->getType() != Ice::IceType_i32) 1741aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotI32; 1742aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexValid; 1743aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 1744aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 174557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty, 174657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and sets Op to the corresponding ICE binary opcode. Returns true if able 174757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // to convert, false otherwise. 1748d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, 1749d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::InstArithmetic::OpKind &Op) { 17509bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf switch (Opcode) { 1751d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf default: { 17529bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf std::string Buffer; 17539bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf raw_string_ostream StrBuf(Buffer); 17549bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; 17559bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Error(StrBuf.str()); 1756d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Add; 1757d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1758d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 17599bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_ADD: 17609bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17619bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Add; 17629bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17639bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17649bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fadd; 17659bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17669bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17679bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SUB: 17689bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17699bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Sub; 17709bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17719bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17729bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fsub; 17739bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17749bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17759bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_MUL: 17769bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17779bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Mul; 17789bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17799bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17809bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fmul; 17819bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17829bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17839bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_UDIV: 1784d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Udiv; 1785d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17869bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SDIV: 17879bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17889bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Sdiv; 17899bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17909bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17919bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fdiv; 17929bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17939bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17949bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_UREM: 1795d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Urem; 1796d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17979bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SREM: 17989bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17999bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Srem; 18009bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 18019bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 18029bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Frem; 18039bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 18049bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 18059bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SHL: 1806d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Shl; 1807d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 18089bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_LSHR: 1809d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Lshr; 1810d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 18119bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_ASHR: 1812d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Ashr; 1813d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 18149bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_AND: 1815d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::And; 1816d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerLogicalOp(Op, Ty); 18179bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_OR: 1818d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Or; 1819d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerLogicalOp(Op, Ty); 18209bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_XOR: 1821d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Xor; 1822d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerLogicalOp(Op, Ty); 1823d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1824d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1825c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf 182657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Simplifies out vector types from Type1 and Type2, if both are vectors of 182757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// the same size. Returns true iff both are vectors of the same size, or are 182857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// both scalar types. 1829bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) { 1830bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsType1Vector = isVectorType(Type1); 1831bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsType2Vector = isVectorType(Type2); 1832bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (IsType1Vector != IsType2Vector) 1833bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1834bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!IsType1Vector) 1835bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return true; 1836bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (typeNumElements(Type1) != typeNumElements(Type2)) 1837bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1838bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Type1 = typeElementType(Type1); 1839bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Type2 = typeElementType(Type2); 1840bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return true; 1841bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1842bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1843bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff an integer truncation from SourceType to TargetType is 1844bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// valid. 1845bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) { 1846dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) && 1847dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth simplifyOutCommonVectorType(SourceType, TargetType) && 1848dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType); 1849bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1850bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1851bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff a floating type truncation from SourceType to TargetType 1852bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// is valid. 1853bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isFloatTruncCastValid(Ice::Type SourceType, 1854bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType) { 1855dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth return simplifyOutCommonVectorType(SourceType, TargetType) && 1856dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32; 1857bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1858bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1859bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff an integer extension from SourceType to TargetType is 1860bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// valid. 1861bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { 1862bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return isIntTruncCastValid(TargetType, SourceType); 1863bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1864bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1865bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff a floating type extension from SourceType to TargetType 1866bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// is valid. 1867bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { 1868bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return isFloatTruncCastValid(TargetType, SourceType); 1869bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1870bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 187157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns true iff a cast from floating type SourceType to integer type 187257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// TargetType is valid. 1873bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isFloatToIntCastValid(Ice::Type SourceType, 1874bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType) { 1875bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) 1876bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1877bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsSourceVector = isVectorType(SourceType); 1878bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsTargetVector = isVectorType(TargetType); 1879bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (IsSourceVector != IsTargetVector) 1880bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1881bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (IsSourceVector) { 1882bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return typeNumElements(SourceType) == typeNumElements(TargetType); 1883bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1884bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return true; 1885bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1886bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 188757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns true iff a cast from integer type SourceType to floating type 188857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// TargetType is valid. 1889bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isIntToFloatCastValid(Ice::Type SourceType, 1890bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType) { 1891bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return isFloatToIntCastValid(TargetType, SourceType); 1892bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1893bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 189457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the number of bits used to model type Ty when defining the bitcast 189557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// instruction. 1896bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) { 1897bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (Ice::isVectorType(Ty)) 1898bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return Ice::typeNumElements(Ty) * 1899bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bitcastSizeInBits(Ice::typeElementType(Ty)); 1900bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (Ty == Ice::IceType_i1) 1901bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return 1; 1902bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return Ice::typeWidthInBytes(Ty) * CHAR_BIT; 1903bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1904bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1905bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff a bitcast from SourceType to TargetType is allowed. 1906bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) { 1907bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); 1908bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1909bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 191057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for 191157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// converting SourceType to TargetType. Updates CastKind to the corresponding 191257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// instruction cast opcode. Also generates an error message when this 191357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// function returns false. 1914bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, 1915bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType, 1916bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::InstCast::OpKind &CastKind) { 1917bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool Result; 1918bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf switch (Opcode) { 1919bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf default: { 1920bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf std::string Buffer; 1921bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf raw_string_ostream StrBuf(Buffer); 1922bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf StrBuf << "Cast opcode " << Opcode << " not understood.\n"; 1923bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Error(StrBuf.str()); 1924bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Bitcast; 1925bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1926bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1927bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_TRUNC: 1928bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Trunc; 1929bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntTruncCastValid(SourceType, TargetType); 1930bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf break; 1931bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_ZEXT: 1932c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Zext; 1933bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntExtCastValid(SourceType, TargetType); 1934c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1935bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_SEXT: 1936c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Sext; 1937bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntExtCastValid(SourceType, TargetType); 1938c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1939bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPTOUI: 1940bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Fptoui; 1941bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatToIntCastValid(SourceType, TargetType); 1942c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1943bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPTOSI: 1944c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Fptosi; 1945bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatToIntCastValid(SourceType, TargetType); 1946c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1947bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_UITOFP: 1948bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Uitofp; 1949bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntToFloatCastValid(SourceType, TargetType); 1950c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1951bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_SITOFP: 1952c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Sitofp; 1953bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntToFloatCastValid(SourceType, TargetType); 1954c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1955bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPTRUNC: 1956bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Fptrunc; 1957bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatTruncCastValid(SourceType, TargetType); 1958bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf break; 1959bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPEXT: 1960bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Fpext; 1961bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatExtCastValid(SourceType, TargetType); 1962c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1963bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_BITCAST: 1964c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Bitcast; 1965bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isBitcastValid(SourceType, TargetType); 1966c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1967c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 1968bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!Result) { 1969bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf std::string Buffer; 1970bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf raw_string_ostream StrBuf(Buffer); 1971bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " 1972bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf << SourceType << " to " << TargetType; 1973bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Error(StrBuf.str()); 1974bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1975bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return Result; 1976c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 197783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf 197857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true 197957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // if able to convert, false otherwise. 198083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf bool convertNaClBitcICmpOpToIce(uint64_t Op, 198183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstIcmp::ICond &Cond) const { 198283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf switch (Op) { 198383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_EQ: 198483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Eq; 198583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 198683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_NE: 198783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ne; 198883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 198983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_UGT: 199083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ugt; 199183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 199283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_UGE: 199383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Uge; 199483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 199583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_ULT: 199683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ult; 199783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 199883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_ULE: 199983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ule; 200083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SGT: 200283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Sgt; 200383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SGE: 200583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Sge; 200683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SLT: 200883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Slt; 200983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 201083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SLE: 201183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Sle; 201283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 201383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf default: 2014dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth // Make sure Cond is always initialized. 2015dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth Cond = static_cast<Ice::InstIcmp::ICond>(0); 201683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return false; 201783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 201883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 201983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf 202057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true 202157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // if able to convert, false otherwise. 202283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf bool convertNaClBitcFCompOpToIce(uint64_t Op, 202383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstFcmp::FCond &Cond) const { 202483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf switch (Op) { 202583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_FALSE: 202683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::False; 202783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 202883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OEQ: 202983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Oeq; 203083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 203183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OGT: 203283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ogt; 203383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 203483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OGE: 203583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Oge; 203683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 203783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OLT: 203883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Olt; 203983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 204083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OLE: 204183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ole; 204283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 204383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ONE: 204483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::One; 204583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 204683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ORD: 204783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ord; 204883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 204983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UNO: 205083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Uno; 205183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 205283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UEQ: 205383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ueq; 205483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 205583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UGT: 205683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ugt; 205783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 205883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UGE: 205983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Uge; 206083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 206183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ULT: 206283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ult; 206383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 206483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ULE: 206583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ule; 206683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 206783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UNE: 206883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Une; 206983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 207083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_TRUE: 207183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::True; 207283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 207383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf default: 2074dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth // Make sure Cond is always initialized. 2075dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth Cond = static_cast<Ice::InstFcmp::FCond>(0); 207683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return false; 207783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 207883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 2079aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 208057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Creates an error instruction, generating a value of type Ty, and adds a 208157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // placeholder so that instruction indices line up. Some instructions, such 208257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // as a call, will not generate a value if the return type is void. In such 208357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // cases, a placeholder value for the badly formed instruction is not needed. 208457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Hence, if Ty is void, an error instruction is not appended. 2085aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf void appendErrorInstruction(Ice::Type Ty) { 208657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: we don't worry about downstream translation errors because the 208757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // function will not be translated if any errors occur. 2088aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (Ty == Ice::IceType_void) 2089aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2090aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Variable *Var = getNextInstVar(Ty); 20918e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); 2092aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 20939d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf 20949d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) { 20959d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf std::string Buffer; 20969d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf raw_string_ostream StrBuf(Buffer); 20979d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf StrBuf << "Value index " << Index << " not defined!"; 209843632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf Error(StrBuf.str()); 209943632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf // Recover and return some value. 210043632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf if (!LocalOperands.empty()) 210143632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf return LocalOperands.front(); 210243632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf return Context->getGlobalConstantByID(0); 21039d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf } 2104fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 210548e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth void verifyCallArgTypeMatches(Ice::FunctionDeclaration *Fcn, Ice::SizeT Index, 210648e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth Ice::Type ArgType, Ice::Type ParamType) { 2107fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (ArgType != ParamType) { 2108fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf std::string Buffer; 2109fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf raw_string_ostream StrBuf(Buffer); 211048e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth StrBuf << "Argument " << (Index + 1) << " of " << printName(Fcn) 2111fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf << " expects " << ParamType << ". Found: " << ArgType; 2112fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Error(StrBuf.str()); 2113fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2114fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2115fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 2116467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth const std::string printName(Ice::FunctionDeclaration *Fcn) { 2117fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (Fcn) 2118467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth return Fcn->getName().toString(); 2119fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf return "function"; 2120fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2121d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf}; 2122d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2123d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfvoid FunctionParser::ExitBlock() { 21246c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf // Check if the last instruction in the function was terminating. 21256c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf if (!InstIsTerminating) { 21266c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf Error("Last instruction in function not terminator"); 21276c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf // Recover by inserting an unreachable instruction. 21286c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 21296fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 213098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf ++CurrentBbIndex; 213198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (CurrentBbIndex != DeclaredNumberBbs) { 213298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf std::string Buffer; 213398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf raw_string_ostream StrBuf(Buffer); 213498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf StrBuf << "Function declared " << DeclaredNumberBbs 213598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << " basic blocks, but defined " << CurrentBbIndex << "."; 213698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error(StrBuf.str()); 213798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 213857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Before translating, check for blocks without instructions, and insert 213957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // unreachable. This shouldn't happen, but be safe. 214074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t Index = 0; 2141f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth for (Ice::CfgNode *Node : Func->getNodes()) { 2142bfb410dd04d46ca34b2ea437151af2dc26930b5bJim Stichnoth if (Node->getInsts().empty()) { 2143d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 2144d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 2145d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Basic block " << Index << " contains no instructions"; 2146d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 21478e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Node->appendInst(Ice::InstUnreachable::create(Func.get())); 2148d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2149f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth ++Index; 2150d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 215169d3f9c6698150a88fcc89a20bb93823895dfaf8Jim Stichnoth Func->computeInOutEdges(); 2152d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 2153d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 215474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, 2155d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type OpTy) { 2156d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 2157d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 2158d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) 2159d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf << ". Found " << OpTy; 2160d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 2161d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 2162d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2163d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfvoid FunctionParser::ProcessRecord() { 216457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: To better separate parse/IR generation times, when IR generation is 216557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // disabled we do the following: 21666fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // 1) Delay exiting until after we extract operands. 21676fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // 2) return before we access operands, since all operands will be a nullptr. 2168d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 2169d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (InstIsTerminating) { 2170d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf InstIsTerminating = false; 217198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf ++CurrentBbIndex; 21720d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth CurrentNode = getBasicBlock(CurrentBbIndex); 2173d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 217447661568f8c3811634913cfb43144a95d8340758Karl Schimpf // The base index for relative indexing. 217574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t BaseIndex = getNextInstIndex(); 2176d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf switch (Record.GetCode()) { 2177d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::FUNC_CODE_DECLAREBLOCKS: { 2178d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // DECLAREBLOCKS: [n] 21792f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "count")) 2180c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 218198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (DeclaredNumberBbs > 0) { 218298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error("Duplicate function block count record"); 218398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return; 218498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 218598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 218698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Check for bad large sizes, since they can make ridiculous memory 21877a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // requests and hang the user for large amounts of time. 21887a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf uint64_t NumBbs = Values[0]; 21897a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (NumBbs > MaxRecordsInBlock) { 219074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 219174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 219298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf StrBuf << "Function defines " << NumBbs 219398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << " basic blocks, which is too big for a function containing " 219498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << NumBytesDefiningFunction << " bytes"; 219574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 21967a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf NumBbs = MaxRecordsInBlock; 2197d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 219898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 219998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (NumBbs == 0) { 220098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error("Functions must contain at least one basic block."); 220198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf NumBbs = 1; 220298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 220398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 220498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf DeclaredNumberBbs = NumBbs; 220598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Install the basic blocks, skipping bb0 which was created in the 220698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // constructor. 220798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf for (size_t i = 1; i < NumBbs; ++i) 220898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf installNextBasicBlock(); 2209aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2210d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2211d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::FUNC_CODE_INST_BINOP: { 2212e73ee859fdc010f7a7d73f91b22f594af6e69525Karl Schimpf // Note: Old bitcode files may have an additional 'flags' operand, which is 2213e73ee859fdc010f7a7d73f91b22f594af6e69525Karl Schimpf // ignored. 2214e73ee859fdc010f7a7d73f91b22f594af6e69525Karl Schimpf 2215e73ee859fdc010f7a7d73f91b22f594af6e69525Karl Schimpf // BINOP: [opval, opval, opcode, [flags]] 2216e73ee859fdc010f7a7d73f91b22f594af6e69525Karl Schimpf 2217e73ee859fdc010f7a7d73f91b22f594af6e69525Karl Schimpf if (!isValidRecordSizeInRange(3, 4, "binop")) 2218c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 221947661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); 222047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); 2221d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type Type1 = Op1->getType(); 2222d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type Type2 = Op2->getType(); 2223d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Type1 != Type2) { 2224d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 2225d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 2226d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; 2227d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 2228aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Type1); 2229aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2230d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2231d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2232d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::InstArithmetic::OpKind Opcode; 22339bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (!convertBinopOpcode(Values[2], Type1, Opcode)) { 22349bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf appendErrorInstruction(Type1); 2235c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 22369bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 223747661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstArithmetic::create( 22388e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2)); 2239aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2240d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2241c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf case naclbitc::FUNC_CODE_INST_CAST: { 2242c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf // CAST: [opval, destty, castopc] 22432f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "cast")) 2244c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 224547661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); 2246645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); 2247c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf Ice::InstCast::OpKind CastKind; 2248bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) { 2249aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(CastType); 2250c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 2251c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 22528e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstCast::create( 22538e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), CastKind, getNextInstVar(CastType), Src)); 2254aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2255c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 22561d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf case naclbitc::FUNC_CODE_INST_VSELECT: { 22571d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf // VSELECT: [opval, opval, pred] 22582f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "select")) 22596fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 226047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); 226147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); 22626fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); 22636fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type ThenType = ThenVal->getType(); 22641d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Ice::Type ElseType = ElseVal->getType(); 22651d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf if (ThenType != ElseType) { 22661d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf std::string Buffer; 22671d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf raw_string_ostream StrBuf(Buffer); 22681d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf StrBuf << "Select operands not same type. Found " << ThenType << " and " 22691d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf << ElseType; 22701d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Error(StrBuf.str()); 2271aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(ThenType); 22721d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf return; 22731d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 22741d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Ice::Type CondType = CondVal->getType(); 22751d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf if (isVectorType(CondType)) { 22761d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf if (!isVectorType(ThenType) || 22771d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf typeElementType(CondType) != Ice::IceType_i1 || 22781d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf typeNumElements(ThenType) != typeNumElements(CondType)) { 22791d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf std::string Buffer; 22801d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf raw_string_ostream StrBuf(Buffer); 228197501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf StrBuf << "Select condition type " << CondType 22821d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf << " not allowed for values of type " << ThenType; 22831d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Error(StrBuf.str()); 2284aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(ThenType); 22851d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf return; 22861d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 22871d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } else if (CondVal->getType() != Ice::IceType_i1) { 22881d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf std::string Buffer; 22891d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2290dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth StrBuf << "Select condition " << CondVal 2291dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth << " not type i1. Found: " << CondVal->getType(); 22921d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Error(StrBuf.str()); 2293aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(ThenType); 22941d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf return; 22951d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 229647661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstSelect::create( 22978e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); 2298aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 22991d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 230071ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf case naclbitc::FUNC_CODE_INST_EXTRACTELT: { 230171ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf // EXTRACTELT: [opval, opval] 23022f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "extract element")) 230383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 230447661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); 230547661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); 23066fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type VecType = Vec->getType(); 2307aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); 2308aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (IndexCheckValue != VectorIndexValid) { 230971ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf std::string Buffer; 231071ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2311aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); 2312aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf StrBuf << ": extractelement " << VecType << " " << *Vec << ", " 2313aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << Index->getType() << " " << *Index; 231471ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf Error(StrBuf.str()); 2315aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(VecType); 2316aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 231771ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 231847661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstExtractElement::create( 23198e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index)); 2320aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 232171ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 232271ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf case naclbitc::FUNC_CODE_INST_INSERTELT: { 232371ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf // INSERTELT: [opval, opval, opval] 23242f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "insert element")) 232583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 232647661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); 232747661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); 232847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); 23296fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type VecType = Vec->getType(); 2330aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); 2331aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (IndexCheckValue != VectorIndexValid) { 233271ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf std::string Buffer; 233371ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2334aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); 2335aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf StrBuf << ": insertelement " << VecType << " " << *Vec << ", " 2336aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << Elt->getType() << " " << *Elt << ", " << Index->getType() << " " 2337aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << *Index; 233871ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf Error(StrBuf.str()); 2339aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Elt->getType()); 2340aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 234171ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 234243632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf if (Ice::typeElementType(VecType) != Elt->getType()) { 234343632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf std::string Buffer; 234443632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf raw_string_ostream StrBuf(Buffer); 234543632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf StrBuf << "Insertelement: Element type " 234643632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf << Ice::typeString(Elt->getType()) << " doesn't match vector type " 234743632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf << Ice::typeString(VecType); 234843632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf Error(StrBuf.str()); 234943632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf appendErrorInstruction(Elt->getType()); 235043632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf return; 235143632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf } 235247661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstInsertElement::create( 23538e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(VecType), Vec, Elt, Index)); 2354aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 235571ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 235683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FUNC_CODE_INST_CMP2: { 235783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf // CMP2: [opval, opval, pred] 23582f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "compare")) 235983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 236047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); 236147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); 236283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::Type Op1Type = Op1->getType(); 236383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::Type Op2Type = Op2->getType(); 2364aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type DestType = getCompareResultType(Op1Type); 236583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (Op1Type != Op2Type) { 236683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 236783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 2368dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth StrBuf << "Compare argument types differ: " << Op1Type << " and " 2369dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth << Op2Type; 237083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2371aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 237283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Op2 = Op1; 237383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 237483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (DestType == Ice::IceType_void) { 237583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 237683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 237783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare not defined for type " << Op1Type; 237883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 237983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 238083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 238147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Variable *Dest = getNextInstVar(DestType); 238283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (isIntegerType(Op1Type)) { 238383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstIcmp::ICond Cond; 238483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { 238583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 238683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 238783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare record contains unknown integer predicate index: " 238883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf << Values[2]; 238983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2390aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 239183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 239247661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 23938e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2)); 2394dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth } else if (isFloatingType(Op1Type)) { 239583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstFcmp::FCond Cond; 239683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { 239783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 239883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 239983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare record contains unknown float predicate index: " 240083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf << Values[2]; 240183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2402aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 240383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 240447661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 24058e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2)); 240683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } else { 240783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf // Not sure this can happen, but be safe. 240883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 240983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 241083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare on type not understood: " << Op1Type; 241183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2412aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 241383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 241483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 2415aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 241683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 2417d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::FUNC_CODE_INST_RET: { 2418d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // RET: [opval?] 24196c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 24202f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeInRange(0, 1, "return")) 2421c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 2422bfb410dd04d46ca34b2ea437151af2dc26930b5bJim Stichnoth if (Values.empty()) { 24238e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstRet::create(Func.get())); 2424d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } else { 24256fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex); 24268e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal)); 2427d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2428aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2429c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 2430c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf case naclbitc::FUNC_CODE_INST_BR: { 24316c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 2432c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf if (Values.size() == 1) { 2433c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf // BR: [bb#] 2434c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); 2435e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (Block == nullptr) 2436c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 24378e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block)); 2438c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } else { 2439c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf // BR: [bb#, bb#, opval] 24402f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "branch")) 2441c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 244247661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); 2443c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf if (Cond->getType() != Ice::IceType_i1) { 2444c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf std::string Buffer; 2445c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf raw_string_ostream StrBuf(Buffer); 2446dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth StrBuf << "Branch condition " << *Cond 2447dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth << " not i1. Found: " << Cond->getType(); 2448c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Error(StrBuf.str()); 2449c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 2450c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 2451c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); 2452c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); 2453e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (ThenBlock == nullptr || ElseBlock == nullptr) 2454c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 245547661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 24568e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock)); 2457c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 2458aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2459d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2460d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf case naclbitc::FUNC_CODE_INST_SWITCH: { 2461d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] 2462d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // where Case = [1, 1, Value, BbIndex]. 2463d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // 246457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: Unlike most instructions, we don't infer the type of Cond, but 246557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // provide it as a separate field. There are also unnecessary data fields 246657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because 246757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the bitcode format was already frozen when the problem was noticed. 24686c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 24692f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(4, "switch")) 2470d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 24716fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 2472645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); 2473d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf if (!Ice::isScalarIntegerType(CondTy)) { 2474d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf std::string Buffer; 2475d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf raw_string_ostream StrBuf(Buffer); 2476d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; 2477d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Error(StrBuf.str()); 2478d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 2479d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 2480d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy); 2481d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex); 24826fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 24830d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth if (CondTy != Cond->getType()) { 2484d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf std::string Buffer; 2485d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf raw_string_ostream StrBuf(Buffer); 2486d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Case condition expects type " << CondTy 2487d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf << ". Found: " << Cond->getType(); 2488d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Error(StrBuf.str()); 2489d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 2490d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 24910d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth Ice::CfgNode *DefaultLabel = getBranchBasicBlock(Values[2]); 24920042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf if (DefaultLabel == nullptr) 24930042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf return; 249474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t NumCasesRaw = Values[3]; 249574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) { 249674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 249774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 249874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Too many cases specified in switch: " << NumCasesRaw; 249974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 250074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NumCasesRaw = std::numeric_limits<uint32_t>::max(); 250174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 250274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint32_t NumCases = NumCasesRaw; 2503d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf 2504d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // Now recognize each of the cases. 25052f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(4 + NumCases * 4, "switch")) 2506d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 25070042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf std::unique_ptr<Ice::InstSwitch> Switch( 25080d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth Ice::InstSwitch::create(Func.get(), NumCases, Cond, DefaultLabel)); 2509dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth unsigned ValCaseIndex = 4; // index to beginning of case entry. 251074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf for (uint32_t CaseIndex = 0; CaseIndex < NumCases; 2511d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf ++CaseIndex, ValCaseIndex += 4) { 2512dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) { 2513d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf std::string Buffer; 2514d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf raw_string_ostream StrBuf(Buffer); 2515d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Sequence [1, 1, value, label] expected for case entry " 2516d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf << "in switch record. (at index" << ValCaseIndex << ")"; 2517d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Error(StrBuf.str()); 2518d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 2519d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 2520a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf BitcodeInt Value(BitWidth, 25213281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2])); 2522d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); 25230042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf if (Label == nullptr) 25240042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf return; 2525d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); 2526d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 25270042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf CurrentNode->appendInst(Switch.release()); 2528aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2529d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 253097501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf case naclbitc::FUNC_CODE_INST_UNREACHABLE: { 253197501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf // UNREACHABLE: [] 25326c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 25332f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "unreachable")) 253497501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf return; 25358e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 2536aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 253797501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf } 253847661568f8c3811634913cfb43144a95d8340758Karl Schimpf case naclbitc::FUNC_CODE_INST_PHI: { 253947661568f8c3811634913cfb43144a95d8340758Karl Schimpf // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. 25402f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(3, "phi")) 254147661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 2542aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); 254347661568f8c3811634913cfb43144a95d8340758Karl Schimpf if ((Values.size() & 0x1) == 0) { 254447661568f8c3811634913cfb43144a95d8340758Karl Schimpf // Not an odd number of values. 254547661568f8c3811634913cfb43144a95d8340758Karl Schimpf std::string Buffer; 254647661568f8c3811634913cfb43144a95d8340758Karl Schimpf raw_string_ostream StrBuf(Buffer); 254747661568f8c3811634913cfb43144a95d8340758Karl Schimpf StrBuf << "function block phi record size not valid: " << Values.size(); 254847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error(StrBuf.str()); 2549aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 255047661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 255147661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 255247661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (Ty == Ice::IceType_void) { 255347661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error("Phi record using type void not allowed"); 255447661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 255547661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 255647661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Variable *Dest = getNextInstVar(Ty); 25578e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstPhi *Phi = 25588e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest); 255974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf for (size_t i = 1; i < Values.size(); i += 2) { 256047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op = 256147661568f8c3811634913cfb43144a95d8340758Karl Schimpf getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); 256247661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (Op->getType() != Ty) { 256347661568f8c3811634913cfb43144a95d8340758Karl Schimpf std::string Buffer; 256447661568f8c3811634913cfb43144a95d8340758Karl Schimpf raw_string_ostream StrBuf(Buffer); 256597501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf StrBuf << "Value " << *Op << " not type " << Ty 256697501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf << " in phi instruction. Found: " << Op->getType(); 256747661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error(StrBuf.str()); 2568aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 256947661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 257047661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 257147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Phi->addArgument(Op, getBasicBlock(Values[i + 1])); 257247661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 257347661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Phi); 2574aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 257547661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 2576742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf case naclbitc::FUNC_CODE_INST_ALLOCA: { 2577742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf // ALLOCA: [Size, align] 25782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "alloca")) 2579742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf return; 258047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); 258107af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf uint32_t Alignment = Context->extractAlignment(this, "Alloca", Values[1]); 25824019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf Ice::Type PtrTy = Ice::getPointerType(); 2583742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf if (ByteCount->getType() != Ice::IceType_i32) { 2584742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf std::string Buffer; 2585742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf raw_string_ostream StrBuf(Buffer); 258697501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; 2587742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf Error(StrBuf.str()); 2588aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(PtrTy); 2589742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf return; 2590742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf } 25918e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstAlloca::create( 25922f3b8ec812321b1549bc1714a239b9dd0c95ebd7David Sehr Func.get(), getNextInstVar(PtrTy), ByteCount, Alignment)); 2593aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2594742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf } 259541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf case naclbitc::FUNC_CODE_INST_LOAD: { 259641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf // LOAD: [address, align, ty] 25972f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "load")) 259841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 259947661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); 2600aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); 260107af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf uint32_t Alignment = Context->extractAlignment(this, "Load", Values[1]); 2602aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!isValidPointerType(Address, "Load")) { 2603aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 260441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 2605aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 2606aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { 2607aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 260841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 2609aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 26108e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstLoad::create( 26118e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(Ty), Address, Alignment)); 2612aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 261341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 261441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf case naclbitc::FUNC_CODE_INST_STORE: { 261541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf // STORE: [address, value, align] 26162f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "store")) 261741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 261847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); 261947661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); 262007af2ac73b348fb5e6378a49abcc9c9a36775a08Karl Schimpf uint32_t Alignment = Context->extractAlignment(this, "Store", Values[2]); 26216fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (!isValidPointerType(Address, "Store")) 26226fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 262341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) 262441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 262547661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 26268e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstStore::create(Func.get(), Value, Address, Alignment)); 2627aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 262841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 26298df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case naclbitc::FUNC_CODE_INST_CALL: 26308df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { 26318df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // CALL: [cc, fnid, arg0, arg1...] 26328df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // CALL_INDIRECT: [cc, fn, returnty, args...] 26338df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // 263457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: The difference between CALL and CALL_INDIRECT is that CALL has a 263557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // reference to an explicit function declaration, while the CALL_INDIRECT 263657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // is just an address. For CALL, we can infer the return type by looking up 263757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the type signature associated with the function declaration. For 263857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // CALL_INDIRECT we can only infer the type signature via argument types, 263957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and the corresponding return type stored in CALL_INDIRECT record. 26408df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::SizeT ParamsStartIndex = 2; 26418df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { 26422f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "call")) 26438df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf return; 26448df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } else { 26452f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(3, "call indirect")) 26468df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf return; 26478df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf ParamsStartIndex = 3; 26488df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 26498df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 26508df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); 26518df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::Operand *Callee = getOperand(CalleeIndex); 2652fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 2653fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf // Pull out signature/return type of call (if possible). 2654fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Ice::FunctionDeclaration *Fcn = nullptr; 2655ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf const Ice::FuncSigType *Signature = nullptr; 26568df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::Type ReturnType = Ice::IceType_void; 2657e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; 26588df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { 2659958ff342c2bfd6e6ffaed7c44e170405ae1245d2Karl Schimpf Fcn = Context->getFunctionByID(CalleeIndex); 2660ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Signature = &Fcn->getSignature(); 2661ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf ReturnType = Signature->getReturnType(); 2662fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Ice::SizeT NumParams = Values.size() - ParamsStartIndex; 2663fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (NumParams != Signature->getNumArgs()) { 2664fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf std::string Buffer; 2665fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf raw_string_ostream StrBuf(Buffer); 2666fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf StrBuf << "Call to " << printName(Fcn) << " has " << NumParams 2667fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf << " parameters. Signature expects: " << Signature->getNumArgs(); 2668fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Error(StrBuf.str()); 2669fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (ReturnType != Ice::IceType_void) 2670fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf setNextLocalInstIndex(nullptr); 2671fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf return; 2672fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 26738df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 26748df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // Check if this direct call is to an Intrinsic (starts with "llvm.") 2675bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf IntrinsicInfo = Fcn->getIntrinsicInfo(getTranslator().getContext()); 2676fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (IntrinsicInfo && IntrinsicInfo->getNumArgs() != NumParams) { 2677fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf std::string Buffer; 2678fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf raw_string_ostream StrBuf(Buffer); 2679fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf StrBuf << "Call to " << printName(Fcn) << " has " << NumParams 2680fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf << " parameters. Intrinsic expects: " << Signature->getNumArgs(); 2681a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth Error(StrBuf.str()); 2682ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (ReturnType != Ice::IceType_void) 2683fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf setNextLocalInstIndex(nullptr); 2684a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth return; 26858df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 2686fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } else { // Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL_INDIRECT 2687fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf // There is no signature. Assume defined by parameter types. 2688645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ReturnType = Context->getSimpleTypeByID(Values[2]); 26890d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth if (Callee != nullptr) 2690fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf isValidPointerType(Callee, "Call indirect"); 2691fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2692fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 26930d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth if (Callee == nullptr) 2694fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf return; 2695fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 2696fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf // Extract out the the call parameters. 269748e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth SmallVector<Ice::Operand *, 8> Params; 2698fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf for (Ice::SizeT Index = ParamsStartIndex; Index < Values.size(); ++Index) { 2699fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Ice::Operand *Op = getRelativeOperand(Values[Index], BaseIndex); 2700fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (Op == nullptr) { 2701fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf std::string Buffer; 2702fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf raw_string_ostream StrBuf(Buffer); 270348e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth StrBuf << "Parameter " << (Index - ParamsStartIndex + 1) << " of " 270448e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth << printName(Fcn) << " is not defined"; 2705fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Error(StrBuf.str()); 2706fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (ReturnType != Ice::IceType_void) 2707fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf setNextLocalInstIndex(nullptr); 2708fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf return; 2709fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2710fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Params.push_back(Op); 27118df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 27128df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 2713ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf // Check return type. 2714ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) { 2715ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2716ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 271748e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth StrBuf << "Return type of " << printName(Fcn) 271848e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth << " is invalid: " << ReturnType; 2719ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2720ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf ReturnType = Ice::IceType_i32; 2721ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } 2722ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf 2723fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf // Type check call parameters. 2724fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf for (Ice::SizeT Index = 0; Index < Params.size(); ++Index) { 2725fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Ice::Operand *Op = Params[Index]; 2726fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Ice::Type OpType = Op->getType(); 2727fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf if (Signature) 272848e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth verifyCallArgTypeMatches(Fcn, Index, OpType, 272948e3ae5c62d7e626ed1a0dbbe38a7cc11a356260Jim Stichnoth Signature->getArgType(Index)); 2730bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf else if (!isCallParameterType(OpType)) { 2731fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf std::string Buffer; 2732fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf raw_string_ostream StrBuf(Buffer); 2733fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf StrBuf << "Argument " << *Op << " of " << printName(Fcn) 2734fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf << " has invalid type: " << Op->getType(); 2735fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf Error(StrBuf.str()); 2736fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf appendErrorInstruction(ReturnType); 2737bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf return; 2738fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2739fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf } 2740fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 2741aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // Extract call information. 2742aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf uint64_t CCInfo = Values[0]; 2743aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf CallingConv::ID CallingConv; 2744aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { 2745aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf std::string Buffer; 2746aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2747aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf StrBuf << "Function call calling convention value " << (CCInfo >> 1) 2748aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << " not understood."; 2749aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Error(StrBuf.str()); 2750fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf appendErrorInstruction(ReturnType); 2751aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2752aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 27532d6c82679e9786a924b76023aa30e1f44d0f8cbbJim Stichnoth const bool IsTailCall = (CCInfo & 1); 2754fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf 27558df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // Create the call instruction. 2756e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf Ice::Variable *Dest = (ReturnType == Ice::IceType_void) 2757e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf ? nullptr 2758e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf : getNextInstVar(ReturnType); 27598cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth std::unique_ptr<Ice::InstCall> Instr; 27608df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (IntrinsicInfo) { 27618cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth Instr.reset(Ice::InstIntrinsicCall::create( 27628cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth Func.get(), Params.size(), Dest, Callee, IntrinsicInfo->Info)); 27638df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } else { 27648cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth Instr.reset(Ice::InstCall::create(Func.get(), Params.size(), Dest, Callee, 27658cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth IsTailCall)); 27668df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 2767fc0a52df6a03ee82208c65ae5d33745baf7caa64Karl Schimpf for (Ice::Operand *Param : Params) 27688cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth Instr->addArg(Param); 27698cfeb69e17190d3bfe22a8a1cbd7679a114d68cfJim Stichnoth CurrentNode->appendInst(Instr.release()); 27708df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf return; 27718df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 27728f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { 27738f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // FORWARDTYPEREF: [opval, ty] 27742f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "forward type ref")) 27758f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return; 27766fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type OpType = Context->getSimpleTypeByID(Values[1]); 27770d4fc92b7a200524e6e1e49002fdde58438a1cfeJim Stichnoth setOperand(Values[0], createInstVar(OpType)); 2778aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 27798f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 2780d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf default: 2781d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // Generate error message! 2782d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf BlockParserBaseClass::ProcessRecord(); 2783aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2784d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2785d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 2786d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2787f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf/// Parses constants within a function block. 2788e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass ConstantsParser final : public BlockParserBaseClass { 2789c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ConstantsParser() = delete; 27900795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ConstantsParser(const ConstantsParser &) = delete; 27910795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ConstantsParser &operator=(const ConstantsParser &) = delete; 2792f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2793f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfpublic: 2794f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) 279558455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : BlockParserBaseClass(BlockID, FuncParser), 279658455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), 2797eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth FuncParser(FuncParser) {} 2798f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2799e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ConstantsParser() override = default; 2800f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 28012f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "constants"; } 28022f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 2803f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfprivate: 280458455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 2805f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // The parser of the function block this constants block appears in. 2806f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf FunctionParser *FuncParser; 2807f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // The type to use for succeeding constants. 2808eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Ice::Type NextConstantType = Ice::IceType_void; 2809f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 28108e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 2811f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2812f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Ice::GlobalContext *getContext() { return getTranslator().getContext(); } 2813f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 281457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns true if the type to use for succeeding constants is defined. If 281557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // false, also generates an error message. 2816f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf bool isValidNextConstantType() { 2817f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (NextConstantType != Ice::IceType_void) 2818f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return true; 2819f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error("Constant record not preceded by set type record"); 2820f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return false; 2821f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2822f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf}; 2823f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2824f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfvoid ConstantsParser::ProcessRecord() { 2825f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 2826f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf switch (Record.GetCode()) { 2827f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_SETTYPE: { 2828f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // SETTYPE: [typeid] 28292f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "set type")) 2830f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2831645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf NextConstantType = Context->getSimpleTypeByID(Values[0]); 2832f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (NextConstantType == Ice::IceType_void) 2833f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error("constants block set type not allowed for void type"); 2834f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2835f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2836f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_UNDEF: { 2837f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // UNDEF 28382f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "undef")) 2839f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2840f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (!isValidNextConstantType()) 2841f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2842f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf FuncParser->setNextConstantID( 2843f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf getContext()->getConstantUndef(NextConstantType)); 2844f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2845f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2846f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_INTEGER: { 2847f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // INTEGER: [intval] 28482f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "integer")) 2849f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2850f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (!isValidNextConstantType()) 2851f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 28524019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf if (Ice::isScalarIntegerType(NextConstantType)) { 2853a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf BitcodeInt Value(Ice::getScalarIntBitWidth(NextConstantType), 28543281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf NaClDecodeSignRotatedValue(Values[0])); 2855d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth if (Ice::Constant *C = getContext()->getConstantInt( 2856d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth NextConstantType, Value.getSExtValue())) { 2857d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth FuncParser->setNextConstantID(C); 2858d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth return; 2859d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth } 2860f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2861f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf std::string Buffer; 2862f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf raw_string_ostream StrBuf(Buffer); 2863f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf StrBuf << "constant block integer record for non-integer type " 2864f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf << NextConstantType; 2865f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error(StrBuf.str()); 2866f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2867f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2868f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_FLOAT: { 2869f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // FLOAT: [fpval] 28702f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "float")) 2871f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2872f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (!isValidNextConstantType()) 2873f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2874f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf switch (NextConstantType) { 2875f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case Ice::IceType_f32: { 2876a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf const BitcodeInt Value(32, static_cast<uint32_t>(Values[0])); 2877a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf float FpValue = Value.convertToFp<int32_t, float>(); 28783281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue)); 2879f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2880f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2881f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case Ice::IceType_f64: { 2882a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf const BitcodeInt Value(64, Values[0]); 2883a5295b07896b394092bc00307b2256dda3722e2eKarl Schimpf double FpValue = Value.convertToFp<uint64_t, double>(); 28843281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue)); 2885f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2886f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2887f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf default: { 2888f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf std::string Buffer; 2889f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf raw_string_ostream StrBuf(Buffer); 2890f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf StrBuf << "constant block float record for non-floating type " 2891f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf << NextConstantType; 2892f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error(StrBuf.str()); 2893f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2894f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2895f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2896f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2897f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf default: 2898f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // Generate error message! 2899f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf BlockParserBaseClass::ProcessRecord(); 2900f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2901f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2902f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf} 2903f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2904c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf// Parses valuesymtab blocks appearing in a function block. 2905e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass FunctionValuesymtabParser final : public ValuesymtabParser { 2906c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth FunctionValuesymtabParser() = delete; 29070795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; 29080795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth void operator=(const FunctionValuesymtabParser &) = delete; 2909c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 2910c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfpublic: 2911c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) 291258455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : ValuesymtabParser(BlockID, EnclosingParser), 291358455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, 291458455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf getTranslator().getContext()) {} 2915c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 2916c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfprivate: 291758455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 2918c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Returns the enclosing function parser. 2919c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf FunctionParser *getFunctionParser() const { 2920c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); 2921c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2922c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 2923e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const char *getTableKind() const override { return "Function"; } 292452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 2925e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; 2926e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; 2927c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 292857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that the assignment of Name to the value associated with index is 292957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // not possible, for the given Context. 293074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, 2931c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf StringType &Name) { 2932c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf std::string Buffer; 2933c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf raw_string_ostream StrBuf(Buffer); 2934c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf StrBuf << "Function-local " << Context << " name '" << Name 2935c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf << "' can't be associated with index " << Index; 2936c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf Error(StrBuf.str()); 2937c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2938c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf}; 2939c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 294074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 294174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 2942c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Note: We check when Index is too small, so that we can error recover 2943c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // (FP->getOperand will create fatal error). 29442f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (Index < getFunctionParser()->getNumGlobalIDs()) { 294552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Global value", Index, Name); 2946c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return; 2947c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2948c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf Ice::Operand *Op = getFunctionParser()->getOperand(Index); 294954f3d518805b04b3f2958b7906a7d07dedb4e1aeJim Stichnoth if (auto *V = dyn_cast<Ice::Variable>(Op)) { 295020b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (Ice::BuildDefs::dump()) { 29519a04c0760fe48d0003ffcc5be13f67ccd924a9a4Jim Stichnoth std::string Nm(Name.data(), Name.size()); 29529a04c0760fe48d0003ffcc5be13f67ccd924a9a4Jim Stichnoth V->setName(getFunctionParser()->getFunc(), Nm); 29539a04c0760fe48d0003ffcc5be13f67ccd924a9a4Jim Stichnoth } 2954c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } else { 295552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Local value", Index, Name); 2956c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2957c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 2958c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 295974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 296074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 2961ac7d73441e1c599108b20c4702a96db0e956889eKarl Schimpf if (!Ice::BuildDefs::dump()) 29626fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 296398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { 296452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Basic block", Index, Name); 296598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return; 296698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 2967c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf std::string Nm(Name.data(), Name.size()); 296898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (Ice::BuildDefs::dump()) 296998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); 2970c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 2971c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 2972f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfbool FunctionParser::ParseBlock(unsigned BlockID) { 2973f5fdd2360751122d30280173e0d6c9a3ecf2f72eJim Stichnoth#ifndef PNACL_LLVM 2974f5fdd2360751122d30280173e0d6c9a3ecf2f72eJim Stichnoth constexpr bool PNaClAllowLocalSymbolTables = true; 2975f5fdd2360751122d30280173e0d6c9a3ecf2f72eJim Stichnoth#endif // !PNACL_LLVM 2976f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf switch (BlockID) { 2977f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CONSTANTS_BLOCK_ID: { 2978f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf ConstantsParser Parser(BlockID, this); 2979f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return Parser.ParseThisBlock(); 2980f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2981c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 2982c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf if (PNaClAllowLocalSymbolTables) { 2983c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf FunctionValuesymtabParser Parser(BlockID, this); 2984c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return Parser.ParseThisBlock(); 2985c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2986c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf break; 2987c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2988f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf default: 2989c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf break; 2990f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2991c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return BlockParserBaseClass::ParseBlock(BlockID); 2992f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf} 2993f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 29948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf/// Parses the module block in the bitcode file. 2995e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass ModuleParser final : public BlockParserBaseClass { 2996c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleParser() = delete; 2997c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleParser(const ModuleParser &) = delete; 2998c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleParser &operator=(const ModuleParser &) = delete; 2999c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth 30008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 30018d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ModuleParser(unsigned BlockID, TopLevelParser *Context) 30026ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf : BlockParserBaseClass(BlockID, Context), 300358455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseModule, 30043dd127e67b259fbd6d56ae05834b3c2da03e5219Karl Schimpf Context->getTranslator().getContext()), 3005d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf IsParseParallel(Ice::getFlags().isParseParallel()) {} 3006e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ModuleParser() override = default; 30072f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "module"; } 3008e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBitstreamCursor &getCursor() const { return Record.GetCursor(); } 30092f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 30105ee234a78dbaa81830efed1038161a40ea43d773Karl Schimpfprivate: 301158455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 30129d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // True if we have already installed names for unnamed global declarations, 30139d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // and have generated global constant initializers. 3014eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth bool GlobalDeclarationNamesAndInitializersInstalled = false; 3015c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf // True if we have already processed the symbol table for the module. 3016c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf bool FoundValuesymtab = false; 30173dd127e67b259fbd6d56ae05834b3c2da03e5219Karl Schimpf const bool IsParseParallel; 30189d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 301957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Generates names for unnamed global addresses (i.e. functions and global 302057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // variables). Then lowers global variable declaration initializers to the 302157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // target. May be called multiple times. Only the first call will do the 302257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // installation. 302374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void installGlobalNamesAndGlobalVarInitializers() { 30249d98d791123ce157aab73fba210e4d068935011fKarl Schimpf if (!GlobalDeclarationNamesAndInitializersInstalled) { 30256ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Context->installGlobalNames(); 30266ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Context->createValueIDs(); 3027bba776874b3c0cc37e43bfa58d45630f2887bc0bKarl Schimpf Context->verifyFunctionTypeSignatures(); 3028c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf std::unique_ptr<Ice::VariableDeclarationList> Globals = 3029c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf Context->getGlobalVariables(); 3030c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf if (Globals) 3031c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf getTranslator().lowerGlobals(std::move(Globals)); 30329d98d791123ce157aab73fba210e4d068935011fKarl Schimpf GlobalDeclarationNamesAndInitializersInstalled = true; 30339d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 30349d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 30358e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 30368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3037e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf void ExitBlock() override { 3038e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf installGlobalNamesAndGlobalVarInitializers(); 3039e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Context->getTranslator().getContext()->waitForWorkerThreads(); 3040e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf } 30416ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf 30428e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 30438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 30448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3045c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfclass ModuleValuesymtabParser : public ValuesymtabParser { 3046c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleValuesymtabParser() = delete; 30470795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; 30480795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth void operator=(const ModuleValuesymtabParser &) = delete; 3049c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3050c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfpublic: 3051c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) 305258455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : ValuesymtabParser(BlockID, MP), 305358455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, 305458455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf getTranslator().getContext()) {} 3055c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3056e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ModuleValuesymtabParser() override = default; 3057c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3058c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfprivate: 305958455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 3060e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const char *getTableKind() const override { return "Module"; } 3061e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf void setValueName(NaClBcIndexSize_t Index, StringType &Name) override; 3062e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf void setBbName(NaClBcIndexSize_t Index, StringType &Name) override; 3063c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf}; 3064c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 306574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 306674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 30670a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein Ice::GlobalDeclaration *Decl = Context->getGlobalDeclarationByID(Index); 30680a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein if (llvm::isa<Ice::VariableDeclaration>(Decl) && 30690a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein Decl->isPNaClABIExternalName(Name.str())) { 30700a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein // Force linkage of (specific) Global Variables be external for the PNaCl 30710a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein // ABI. PNaCl bitcode has a linkage field for Functions, but not for 30720a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein // GlobalVariables (because the latter is not needed for pexes, so it has 30730a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein // been removed). 30740a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein Decl->setLinkage(llvm::GlobalValue::ExternalLinkage); 30750a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein } 30760a3c523d94c620457f1572ac5c526a4fee983b0eSean Klein 3077467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // Unconditionally capture the name if it is provided in the input file, 3078467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // regardless of whether dump is enabled or whether the symbol is internal vs 3079467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // external. This fits in well with the lit tests, and most symbols in a 3080467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth // conforming pexe are nameless and don't take this path. 3081467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth Decl->setName(getTranslator().getContext(), 3082467ffe51bebcb3ae3e3ce745c38fc20e8837c31cJim Stichnoth StringRef(Name.data(), Name.size())); 3083c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 3084c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 308574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 308674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 308752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Basic block", Index, Name); 3088c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 3089c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3090e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfclass CfgParserWorkItem final : public Ice::OptWorkItem { 3091e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf CfgParserWorkItem() = delete; 3092e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf CfgParserWorkItem(const CfgParserWorkItem &) = delete; 3093e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf CfgParserWorkItem &operator=(const CfgParserWorkItem &) = delete; 3094e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 3095e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfpublic: 3096e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf CfgParserWorkItem(unsigned BlockID, NaClBcIndexSize_t FcnId, 3097e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ModuleParser *ModParser, std::unique_ptr<uint8_t[]> Buffer, 3098e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf uintptr_t BufferSize, uint64_t StartBit, uint32_t SeqNumber) 3099e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf : BlockID(BlockID), FcnId(FcnId), ModParser(ModParser), 3100e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Buffer(std::move(Buffer)), BufferSize(BufferSize), StartBit(StartBit), 3101e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf SeqNumber(SeqNumber) {} 3102e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf std::unique_ptr<Ice::Cfg> getParsedCfg() override; 3103e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ~CfgParserWorkItem() override = default; 3104e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 3105e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfprivate: 3106e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const unsigned BlockID; 3107e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const NaClBcIndexSize_t FcnId; 3108e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // Note: ModParser can't be const because the function parser needs to 3109e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // access non-const member functions (of ModuleParser and TopLevelParser). 3110e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // TODO(kschimpf): Fix this issue. 3111e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf ModuleParser *ModParser; 3112e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const std::unique_ptr<uint8_t[]> Buffer; 3113e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uintptr_t BufferSize; 3114e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uint64_t StartBit; 3115e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uint32_t SeqNumber; 3116e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf}; 3117e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 3118e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpfstd::unique_ptr<Ice::Cfg> CfgParserWorkItem::getParsedCfg() { 3119e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBitstreamCursor &OldCursor(ModParser->getCursor()); 31202a9d186d1cb3eb75f90f2c82ec7c84ee06c3b569Karl Schimpf llvm::NaClBitstreamReader Reader(OldCursor.getStartWordByteForBit(StartBit), 31212a9d186d1cb3eb75f90f2c82ec7c84ee06c3b569Karl Schimpf Buffer.get(), Buffer.get() + BufferSize, 3122e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf OldCursor.getBitStreamReader()); 3123e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBitstreamCursor NewCursor(Reader); 3124e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NewCursor.JumpToBit(NewCursor.getWordBitNo(StartBit)); 3125e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf FunctionParser Parser(BlockID, ModParser, FcnId, NewCursor); 3126e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf return Parser.parseFunction(SeqNumber); 3127e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf} 3128e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf 31298e8042c42b71675891b824b6bfcd8938174661bcJim Stichnothbool ModuleParser::ParseBlock(unsigned BlockID) { 31308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (BlockID) { 31318d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::BLOCKINFO_BLOCK_ID: 31328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return NaClBitcodeParser::ParseBlock(BlockID); 31338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_BLOCK_ID_NEW: { 31348d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf TypesParser Parser(BlockID, this); 31358d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 31368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_BLOCK_ID: { 31388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf GlobalsParser Parser(BlockID, this); 31398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 31408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 3142c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf if (FoundValuesymtab) 3143c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf Fatal("Duplicate valuesymtab in module"); 3144c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf 314528fc2d7dce3693b40d2a99d84d4147274d66784cKarl Schimpf // If we have already processed a function block (i.e. we have already 314628fc2d7dce3693b40d2a99d84d4147274d66784cKarl Schimpf // installed global names and variable initializers) we can no longer accept 314728fc2d7dce3693b40d2a99d84d4147274d66784cKarl Schimpf // the value symbol table. Names have already been generated. 314828fc2d7dce3693b40d2a99d84d4147274d66784cKarl Schimpf if (GlobalDeclarationNamesAndInitializersInstalled) 314928fc2d7dce3693b40d2a99d84d4147274d66784cKarl Schimpf Fatal("Module valuesymtab not allowed after function blocks"); 315028fc2d7dce3693b40d2a99d84d4147274d66784cKarl Schimpf 3151c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf FoundValuesymtab = true; 3152c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf ModuleValuesymtabParser Parser(BlockID, this); 31538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 31548d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::FUNCTION_BLOCK_ID: { 315674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf installGlobalNamesAndGlobalVarInitializers(); 3157e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Ice::GlobalContext *Ctx = Context->getTranslator().getContext(); 3158e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf uint32_t SeqNumber = Context->getTranslator().getNextSequenceNumber(); 3159e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBcIndexSize_t FcnId = Context->getNextFunctionBlockValueID(); 31603dd127e67b259fbd6d56ae05834b3c2da03e5219Karl Schimpf if (IsParseParallel) { 3161e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // Skip the block and copy into a buffer. Note: We copy into a buffer 3162e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // using the top-level parser to make sure that the underlying 3163e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf // buffer reading from the data streamer is not thread safe. 3164e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf NaClBitstreamCursor &Cursor = Record.GetCursor(); 3165e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf uint64_t StartBit = Cursor.GetCurrentBitNo(); 3166e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf if (SkipBlock()) 3167e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf return true; 3168e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uint64_t EndBit = Cursor.GetCurrentBitNo(); 3169e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uintptr_t StartByte = Cursor.getStartWordByteForBit(StartBit); 3170e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uintptr_t EndByte = Cursor.getEndWordByteForBit(EndBit); 3171e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf const uintptr_t BufferSize = EndByte - StartByte; 3172e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf std::unique_ptr<uint8_t[]> Buffer((uint8_t *)(new uint8_t[BufferSize])); 3173e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf for (size_t i = Cursor.fillBuffer(Buffer.get(), BufferSize, StartByte); 3174e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf i < BufferSize; ++i) { 3175e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Buffer[i] = 0; 3176e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf } 3177e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf Ctx->optQueueBlockingPush(Ice::makeUnique<CfgParserWorkItem>( 3178e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf BlockID, FcnId, this, std::move(Buffer), BufferSize, StartBit, 3179e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf SeqNumber)); 3180e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf return false; 3181e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf } else { 3182e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf FunctionParser Parser(BlockID, this, FcnId); 3183e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf std::unique_ptr<Ice::Cfg> Func = Parser.parseFunction(SeqNumber); 3184e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf bool Failed = Func->hasError(); 3185e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf getTranslator().translateFcn(std::move(Func)); 3186d46999474d2b4a388e1d8a7c71f06cd4cec51bfcKarl Schimpf return Failed && !Ice::getFlags().getAllowErrorRecovery(); 3187e8457a26638d4d3ea5420ff80ff4ad9fc1ea1fb0Karl Schimpf } 31888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31898d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 31908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return BlockParserBaseClass::ParseBlock(BlockID); 31918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 31938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 31948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid ModuleParser::ProcessRecord() { 31958d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 31968d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 31978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::MODULE_CODE_VERSION: { 31988d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VERSION: [version#] 31992f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "version")) 32008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 320174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t Version = Values[0]; 32028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Version != 1) { 32038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 32048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 32058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StrBuf << "Unknown bitstream version: " << Version; 32068d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 32078d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32098d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::MODULE_CODE_FUNCTION: { 32118d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // FUNCTION: [type, callingconv, isproto, linkage] 32122f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(4, "address")) 32138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32149d98d791123ce157aab73fba210e4d068935011fKarl Schimpf const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]); 32158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf CallingConv::ID CallingConv; 32168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { 32178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 32188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 32192f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Function address has unknown calling convention: " 32208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf << Values[1]; 32218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 32228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf GlobalValue::LinkageTypes Linkage; 32258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { 32268d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 32278d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 32282f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Function address has unknown linkage. Found " << Values[3]; 32298d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 32308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32318d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32320c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf bool IsProto = Values[2] == 1; 323354f3d518805b04b3f2958b7906a7d07dedb4e1aeJim Stichnoth auto *Func = Ice::FunctionDeclaration::create( 32341bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Context->getTranslator().getContext(), Signature, CallingConv, Linkage, 32351bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto IsProto); 32368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Context->setNextFunctionID(Func); 32378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 32408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 32418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 32448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfbool TopLevelParser::ParseBlock(unsigned BlockID) { 32468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (BlockID == naclbitc::MODULE_BLOCK_ID) { 32470b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf if (ParsedModuleBlock) 32480b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf Fatal("Input can't contain more than one module"); 32498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ModuleParser Parser(BlockID, this); 32500b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf bool ParseFailed = Parser.ParseThisBlock(); 32510b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf ParsedModuleBlock = true; 32520b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf return ParseFailed; 32538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32548d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Generate error message by using default block implementation. 32558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass Parser(BlockID, this); 32568d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 32578d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 32588d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3259989a703f0c58731b79c83b186c726877b508be71Jim Stichnoth} // end of anonymous namespace 32608d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32618d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfnamespace Ice { 32628d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32632e7daeff480fa07a3bb8b3eeeedaec369a7521a7Karl Schimpfvoid PNaClTranslator::translateBuffer(const std::string &IRFilename, 32642e7daeff480fa07a3bb8b3eeeedaec369a7521a7Karl Schimpf MemoryBuffer *MemBuf) { 3265c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject( 3266c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()), 3267c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd()))); 3268c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung translate(IRFilename, std::move(MemObj)); 3269c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung} 32708d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3271c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voungvoid PNaClTranslator::translate(const std::string &IRFilename, 3272c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung std::unique_ptr<MemoryObject> &&MemObj) { 327357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // On error, we report_fatal_error to avoid destroying the MemObj. That may 327457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // still be in use by IceBrowserCompileServer. Otherwise, we need to change 327557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also 327657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // need a hook to tell the IceBrowserCompileServer to unblock its 327757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // QueueStreamer. 32782f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung // https://code.google.com/p/nativeclient/issues/detail?id=4163 32798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Read header and verify it is good. 32808d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf NaClBitcodeHeader Header; 3281b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf if (Header.Read(MemObj.get())) { 32822f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Invalid PNaCl bitcode header"); 32838d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3284b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf if (!Header.IsSupported()) { 32850b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf getContext()->getStrError() << Header.Unsupported(); 3286b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf if (!Header.IsReadable()) { 32872f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Invalid PNaCl bitcode header"); 3288b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf } 3289b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf } 32908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Create a bitstream reader to read the bitcode file. 3292b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf NaClBitstreamReader InputStreamFile(MemObj.release(), Header); 32938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf NaClBitstreamCursor InputStream(InputStreamFile); 32948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 329522ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf TopLevelParser Parser(*this, InputStream, ErrorStatus); 32968d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf while (!InputStream.AtEndOfStream()) { 32978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Parser.Parse()) { 3298fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth ErrorStatus.assign(EC_Bitcode); 32998d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 33008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 33018d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 33028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 33030b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf if (!Parser.parsedModuleBlock()) { 33040b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf std::string Buffer; 33050b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf raw_string_ostream StrBuf(Buffer); 33060b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf StrBuf << IRFilename << ": Does not contain a module!"; 33070b8763eae21d5d8952d401cf8e4dd7e4fe9b401dKarl Schimpf llvm::report_fatal_error(StrBuf.str()); 33088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3309c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 33102f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3311c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung } 33128d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 33138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3314989a703f0c58731b79c83b186c726877b508be71Jim Stichnoth} // end of namespace Ice 3315