PNaClTranslator.cpp revision 43632b954abab0a7dcca3441a5e9239be98f6328
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 119612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// This file implements the PNaCl bitcode file to Ice, to machine code 129612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// translator. 139612d32c7e5eb2cb403686ef31172d42e075e460Andrew Scull/// 148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf//===----------------------------------------------------------------------===// 158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1667f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "PNaClTranslator.h" 178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 183281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf#include "IceAPInt.h" 193281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf#include "IceAPFloat.h" 20a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceCfg.h" 21a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceCfgNode.h" 22a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceClFlags.h" 23a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceDefs.h" 24e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf#include "IceGlobalInits.h" 25a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceInst.h" 26a18cc9c60a032e4a02ea0aef08bc758e5acb4cd0Jim Stichnoth#include "IceOperand.h" 2798da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth 2898da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth#pragma clang diagnostic push 2998da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth#pragma clang diagnostic ignored "-Wunused-parameter" 3052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf#include "llvm/ADT/Hashing.h" 3167f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/ADT/SmallString.h" 3267f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeDecoders.h" 3367f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeDefs.h" 3467f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeHeader.h" 3567f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClBitcodeParser.h" 3667f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Bitcode/NaCl/NaClReaderWriter.h" 3767f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Support/Format.h" 3867f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Support/MemoryBuffer.h" 3967f8de9adf6439881a00d8e0f081918436c71f62John Porto#include "llvm/Support/raw_ostream.h" 4052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf#include <unordered_set> 4198da96678bc2705d4a37e17b87bbb3c031be9ae0Jim Stichnoth#pragma clang diagnostic pop 428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 4352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf// Define a hash function for SmallString's, so that it can be used in hash 4452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf// tables. 4552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpfnamespace std { 4652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpftemplate <unsigned InternalLen> struct hash<llvm::SmallString<InternalLen>> { 4752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf size_t operator()(const llvm::SmallString<InternalLen> &Key) const { 4852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf return llvm::hash_combine_range(Key.begin(), Key.end()); 4952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf } 5052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf}; 5152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf} // end of namespace std 5252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfnamespace { 549d98d791123ce157aab73fba210e4d068935011fKarl Schimpfusing namespace llvm; 558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 5657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Models elements in the list of types defined in the types block. These 5757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// elements can be undefined, a (simple) type, or a function type signature. 5857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Note that an extended type is undefined on construction. Use methods 5957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// setAsSimpleType and setAsFuncSigType to define the extended type. 60645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfclass ExtendedType { 61645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType &operator=(const ExtendedType &Ty) = delete; 62dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth 63645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfpublic: 64645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Discriminator for LLVM-style RTTI. 65645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf enum TypeKind { Undefined, Simple, FuncSig }; 66645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 67eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth ExtendedType() = default; 687e571364bcc48d361b71c1402611873fb8544117Jim Stichnoth ExtendedType(const ExtendedType &Ty) = default; 69645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 70eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth virtual ~ExtendedType() = default; 71645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 72645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind getKind() const { return Kind; } 73aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf void dump(Ice::Ostream &Stream) const; 74645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 7557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Changes the extended type to a simple type with the given / value. 76645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setAsSimpleType(Ice::Type Ty) { 77645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf assert(Kind == Undefined); 78645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Kind = Simple; 79645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Signature.setReturnType(Ty); 80645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 81645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 82645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Changes the extended type to an (empty) function signature type. 83645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setAsFunctionType() { 84645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf assert(Kind == Undefined); 85645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Kind = FuncSig; 86645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 87645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 88645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfprotected: 8957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: For simple types, the return type of the signature will be used to 9057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // hold the simple type. 91645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::FuncSigType Signature; 92645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 93645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfprivate: 94eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth ExtendedType::TypeKind Kind = Undefined; 95645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf}; 96645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 97645aa1a9a21d41f523575afad356e76062e9d696Karl SchimpfIce::Ostream &operator<<(Ice::Ostream &Stream, const ExtendedType &Ty) { 9820b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 99b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return Stream; 100aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ty.dump(Stream); 101645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Stream; 102645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf} 103645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 104645aa1a9a21d41f523575afad356e76062e9d696Karl SchimpfIce::Ostream &operator<<(Ice::Ostream &Stream, ExtendedType::TypeKind Kind) { 10520b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 106b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return Stream; 107645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "ExtendedType::"; 108645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Kind) { 109645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case ExtendedType::Undefined: 110645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "Undefined"; 111645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 112645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case ExtendedType::Simple: 113645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "Simple"; 114645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 115645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case ExtendedType::FuncSig: 116645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << "FuncSig"; 117645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 118645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 119645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Stream; 120645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf} 121645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 122645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf// Models an ICE type as an extended type. 123645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfclass SimpleExtendedType : public ExtendedType { 124c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth SimpleExtendedType() = delete; 125645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf SimpleExtendedType(const SimpleExtendedType &) = delete; 126645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf SimpleExtendedType &operator=(const SimpleExtendedType &) = delete; 127dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth 128645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfpublic: 129645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type getType() const { return Signature.getReturnType(); } 130645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 131645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf static bool classof(const ExtendedType *Ty) { 132645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ty->getKind() == Simple; 133645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 134645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf}; 135645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 136645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf// Models a function signature as an extended type. 137645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfclass FuncSigExtendedType : public ExtendedType { 138c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth FuncSigExtendedType() = delete; 139645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncSigExtendedType(const FuncSigExtendedType &) = delete; 140645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncSigExtendedType &operator=(const FuncSigExtendedType &) = delete; 141dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth 142645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpfpublic: 143645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf const Ice::FuncSigType &getSignature() const { return Signature; } 144645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setReturnType(Ice::Type ReturnType) { 145645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Signature.setReturnType(ReturnType); 146645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 147645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void appendArgType(Ice::Type ArgType) { Signature.appendArgType(ArgType); } 148645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf static bool classof(const ExtendedType *Ty) { 149645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ty->getKind() == FuncSig; 150645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 151645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf}; 152645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 153aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpfvoid ExtendedType::dump(Ice::Ostream &Stream) const { 15420b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 155b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return; 156645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << Kind; 157645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Kind) { 158645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Simple: { 159645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << " " << Signature.getReturnType(); 160645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 161645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 162645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case FuncSig: { 163645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Stream << " " << Signature; 164645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 165645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 166645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 167645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 168645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf} 169645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 1702f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpfclass BlockParserBaseClass; 1712f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 1728d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// Top-level class to read PNaCl bitcode files, and translate to ICE. 1738d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass TopLevelParser : public NaClBitcodeParser { 174c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TopLevelParser() = delete; 1750795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth TopLevelParser(const TopLevelParser &) = delete; 1760795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth TopLevelParser &operator=(const TopLevelParser &) = delete; 1778d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1788d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 17922ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf TopLevelParser(Ice::Translator &Translator, NaClBitstreamCursor &Cursor, 18022ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Ice::ErrorCode &ErrorStatus) 18122ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf : NaClBitcodeParser(Cursor), Translator(Translator), 182eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth ErrorStatus(ErrorStatus), 183eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth VariableDeclarations(new Ice::VariableDeclarationList()) {} 1848d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 185e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~TopLevelParser() override = default; 1868d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1876ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Ice::Translator &getTranslator() const { return Translator; } 188d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 1892f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf void setBlockParser(BlockParserBaseClass *NewBlockParser) { 1902f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf BlockParser = NewBlockParser; 1918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 19357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Generates error with given Message, occurring at BitPosition within the 19457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// bitcode file. Always returns true. 19517b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t BitPosition, 19617b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf const std::string &Message) final; 1972f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 19822ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf /// Generates error message with respect to the current block parser. 19974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool blockError(const std::string &Message); 2002f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 20157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the number of errors found while parsing the bitcode file. 2028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf unsigned getNumErrors() const { return NumErrors; } 2038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 2048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf /// Changes the size of the type list to the given size. 20574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void resizeTypeIDValues(size_t NewSize) { TypeIDValues.resize(NewSize); } 20674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf 20774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t getNumTypeIDValues() const { return TypeIDValues.size(); } 2088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 2096fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf /// Returns true if generation of Subzero IR is disabled. 2106fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf bool isIRGenerationDisabled() const { 211df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf return Translator.getFlags().getDisableIRGeneration(); 2126fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2136fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 21457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the undefined type associated with type ID. Note: Returns extended 21557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// type ready to be defined. 21674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExtendedType *getTypeByIDForDefining(NaClBcIndexSize_t ID) { 21757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Get corresponding element, verifying the value is still undefined (and 21857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // hence allowed to be defined). 219645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Undefined); 2208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Ty) 2218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Ty; 22274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (ID >= TypeIDValues.size()) { 22374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (ID >= NaClBcIndexSize_t_Max) { 22474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 22574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 22674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Can't define more than " << NaClBcIndexSize_t_Max 22774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf << " types\n"; 22874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 22974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf // Recover by using existing type slot. 23074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf return &TypeIDValues[0]; 23174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 232dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth TypeIDValues.resize(ID + 1); 23374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 234645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return &TypeIDValues[ID]; 2358d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 2368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 237645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Returns the type associated with the given index. 23874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Type getSimpleTypeByID(NaClBcIndexSize_t ID) { 239645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::Simple); 240645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty == nullptr) 241645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Return error recovery value. 242645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ice::IceType_void; 243645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return cast<SimpleExtendedType>(Ty)->getType(); 244645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 245645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 246645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf /// Returns the type signature associated with the given index. 24774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf const Ice::FuncSigType &getFuncSigTypeByID(NaClBcIndexSize_t ID) { 248645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf const ExtendedType *Ty = getTypeByIDAsKind(ID, ExtendedType::FuncSig); 249645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty == nullptr) 250645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Return error recovery value. 251645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return UndefinedFuncSigType; 252645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return cast<FuncSigExtendedType>(Ty)->getSignature(); 2538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 2548d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 2558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf /// Sets the next function ID to the given LLVM function. 2569d98d791123ce157aab73fba210e4d068935011fKarl Schimpf void setNextFunctionID(Ice::FunctionDeclaration *Fcn) { 257209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf FunctionDeclarations.push_back(Fcn); 2588d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 2598d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 26057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the value id that should be associated with the the current 26157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// function block. Increments internal counters during call so that it will 26257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// be in correct position for next function block. 26374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t getNextFunctionBlockValueID() { 264209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf size_t NumDeclaredFunctions = FunctionDeclarations.size(); 2650c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf while (NextDefiningFunctionID < NumDeclaredFunctions && 266209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf FunctionDeclarations[NextDefiningFunctionID]->isProto()) 2670c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf ++NextDefiningFunctionID; 2680c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf if (NextDefiningFunctionID >= NumDeclaredFunctions) 26922ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal("More function blocks than defined function addresses"); 2700c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf return NextDefiningFunctionID++; 271d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 272d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2739d98d791123ce157aab73fba210e4d068935011fKarl Schimpf /// Returns the function associated with ID. 27474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::FunctionDeclaration *getFunctionByID(NaClBcIndexSize_t ID) { 275209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf if (ID < FunctionDeclarations.size()) 276209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf return FunctionDeclarations[ID]; 2779d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return reportGetFunctionByIDError(ID); 2788d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 2798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 2806ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf /// Returns the constant associated with the given global value ID. 28174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Constant *getGlobalConstantByID(NaClBcIndexSize_t ID) { 2826ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(ID < ValueIDConstants.size()); 2836ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return ValueIDConstants[ID]; 2849d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 2859d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 28657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Install names for all global values without names. Called after the global 28757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// value symbol table is processed, but before any function blocks are 28857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// processed. 2896ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installGlobalNames() { 2906ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 2916ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installGlobalVarNames(); 2926ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installFunctionNames(); 2936ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 294e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 2956ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void createValueIDs() { 2966ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 2976ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ValueIDConstants.reserve(VariableDeclarations->size() + 298209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf FunctionDeclarations.size()); 2996ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf createValueIDsForFunctions(); 3006ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf createValueIDsForGlobalVars(); 3018df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 3028df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 3039d98d791123ce157aab73fba210e4d068935011fKarl Schimpf /// Returns the number of function declarations in the bitcode file. 304209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf size_t getNumFunctionIDs() const { return FunctionDeclarations.size(); } 3058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 30657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the number of global declarations (i.e. IDs) defined in the 30757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// bitcode file. 30874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t getNumGlobalIDs() const { 3096ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (VariableDeclarations) { 310209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf return FunctionDeclarations.size() + VariableDeclarations->size(); 3116ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } else { 3126ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return ValueIDConstants.size(); 3136ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 3148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 316aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf /// Adds the given global declaration to the end of the list of global 317aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf /// declarations. 318aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf void addGlobalDeclaration(Ice::VariableDeclaration *Decl) { 3196ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 320aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf VariableDeclarations->push_back(Decl); 3219d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 322e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 3239d98d791123ce157aab73fba210e4d068935011fKarl Schimpf /// Returns the global variable declaration with the given index. 32474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::VariableDeclaration *getGlobalVariableByID(NaClBcIndexSize_t Index) { 3256ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 3266ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (Index < VariableDeclarations->size()) 3276ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return VariableDeclarations->at(Index); 3289d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return reportGetGlobalVariableByIDError(Index); 3299d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 3309d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 33157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the global declaration (variable or function) with the given 33257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Index. 33374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::GlobalDeclaration *getGlobalDeclarationByID(NaClBcIndexSize_t Index) { 334209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf size_t NumFunctionIds = FunctionDeclarations.size(); 3359d98d791123ce157aab73fba210e4d068935011fKarl Schimpf if (Index < NumFunctionIds) 3369d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return getFunctionByID(Index); 3379d98d791123ce157aab73fba210e4d068935011fKarl Schimpf else 3389d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return getGlobalVariableByID(Index - NumFunctionIds); 339e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf } 340e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 34157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the list of parsed global variable declarations. Releases 34257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// ownership of the current list of global variables. Note: only returns 34357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// non-null pointer on first call. All successive calls return a null 34457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// pointer. 3456ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf std::unique_ptr<Ice::VariableDeclarationList> getGlobalVariables() { 34657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Before returning, check that ValidIDConstants has already been built. 3476ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(!VariableDeclarations || 3486ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf VariableDeclarations->size() <= ValueIDConstants.size()); 3496ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return std::move(VariableDeclarations); 3508d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3518d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 353d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The translator associated with the parser. 354d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Translator &Translator; 355b164d2085e870e2458c73c70c08ab69e56e2e081Karl Schimpf // The exit status that should be set to true if an error occurs. 356fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth Ice::ErrorCode &ErrorStatus; 3578d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // The number of errors reported. 358eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth unsigned NumErrors = 0; 3598d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // The types associated with each type ID. 360645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf std::vector<ExtendedType> TypeIDValues; 3610c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf // The set of functions (prototype and defined). 362209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Ice::FunctionDeclarationList FunctionDeclarations; 363209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // The ID of the next possible defined function ID in FunctionDeclarations. 364209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // FunctionDeclarations is filled first. It's the set of functions (either 365209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // defined or isproto). Then function definitions are encountered/parsed and 366209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // NextDefiningFunctionID is incremented to track the next actually-defined 367209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf // function. 368eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth size_t NextDefiningFunctionID = 0; 3699d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // The set of global variables. 3706ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf std::unique_ptr<Ice::VariableDeclarationList> VariableDeclarations; 3719d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // Relocatable constants associated with global declarations. 372209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Ice::ConstantList ValueIDConstants; 373645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Error recovery value to use when getFuncSigTypeByID fails. 374645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::FuncSigType UndefinedFuncSigType; 37557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // The block parser currently being applied. Used for error reporting. 376eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth BlockParserBaseClass *BlockParser = nullptr; 3778d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3788e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 3798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 38057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Gets extended type associated with the given index, assuming the extended 38157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // type is of the WantedKind. Generates error message if corresponding 38257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // extended type of WantedKind can't be found, and returns nullptr. 38374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExtendedType *getTypeByIDAsKind(NaClBcIndexSize_t ID, 384645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind WantedKind) { 385645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType *Ty = nullptr; 386645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (ID < TypeIDValues.size()) { 387645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ty = &TypeIDValues[ID]; 388645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty->getKind() == WantedKind) 389645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return Ty; 390645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 391645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Generate an error message and set ErrorStatus. 392645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf this->reportBadTypeIDAs(ID, Ty, WantedKind); 393645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return nullptr; 394645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 3958d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 39657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Gives Decl a name if it doesn't already have one. Prefix and NameIndex are 39757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // used to generate the name. NameIndex is automatically incremented if a new 39857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // name is created. DeclType is literal text describing the type of name 39957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // being created. Also generates warning if created names may conflict with 40057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // named declarations. 4016ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installDeclarationName(Ice::GlobalDeclaration *Decl, 4026ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf const Ice::IceString &Prefix, 40374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf const char *DeclType, 40474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t &NameIndex) { 4056ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (Decl->hasName()) { 4066ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Translator.checkIfUnnamedNameSafe(Decl->getName(), DeclType, Prefix); 4076ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } else { 4086ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Decl->setName(Translator.createUnnamedName(Prefix, NameIndex)); 4096ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ++NameIndex; 4106ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4116ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4126ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 4136ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Installs names for global variables without names. 4146ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installGlobalVarNames() { 4156ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf assert(VariableDeclarations); 4166ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf const Ice::IceString &GlobalPrefix = 4176ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf getTranslator().getFlags().getDefaultGlobalPrefix(); 4186ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!GlobalPrefix.empty()) { 41974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NameIndex = 0; 4206ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf for (Ice::VariableDeclaration *Var : *VariableDeclarations) { 4216ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installDeclarationName(Var, GlobalPrefix, "global", NameIndex); 4226ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4236ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4246ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4256ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 4266ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Installs names for functions without names. 4276ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void installFunctionNames() { 4286ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf const Ice::IceString &FunctionPrefix = 4296ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf getTranslator().getFlags().getDefaultFunctionPrefix(); 4306ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!FunctionPrefix.empty()) { 43174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NameIndex = 0; 432209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf for (Ice::FunctionDeclaration *Func : FunctionDeclarations) { 4336ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf installDeclarationName(Func, FunctionPrefix, "function", NameIndex); 4346ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4356ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4366ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4376ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 4386ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Builds a constant symbol named Name, suppressing name mangling if 43957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // SuppressMangling. IsExternal is true iff the symbol is external. 4406ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Ice::Constant *getConstantSym(const Ice::IceString &Name, 4416ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf bool SuppressMangling, bool IsExternal) const { 4426ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (IsExternal) { 4436ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return getTranslator().getContext()->getConstantExternSym(Name); 4446ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } else { 4456ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf const Ice::RelocOffsetT Offset = 0; 4466ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return getTranslator().getContext()->getConstantSym(Offset, Name, 4476ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf SuppressMangling); 4486ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4496ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4506ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 4516ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Converts function declarations into constant value IDs. 4526ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void createValueIDsForFunctions() { 453209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf for (const Ice::FunctionDeclaration *Func : FunctionDeclarations) { 4546ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Ice::Constant *C = nullptr; 4556ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!isIRGenerationDisabled()) { 4566ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf C = getConstantSym(Func->getName(), Func->getSuppressMangling(), 4576ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Func->isProto()); 4586ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4596ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ValueIDConstants.push_back(C); 4606ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4616ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4626ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 4636ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf // Converts global variable declarations into constant value IDs. 4646ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf void createValueIDsForGlobalVars() { 4656ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf for (const Ice::VariableDeclaration *Decl : *VariableDeclarations) { 4666ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Ice::Constant *C = nullptr; 4676ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!isIRGenerationDisabled()) { 4686ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf C = getConstantSym(Decl->getName(), Decl->getSuppressMangling(), 4696ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf !Decl->hasInitializer()); 4706ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4716ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf ValueIDConstants.push_back(C); 4726ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4736ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf } 4746ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf 475645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf // Reports that type ID is undefined, or not of the WantedType. 47674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportBadTypeIDAs(NaClBcIndexSize_t ID, const ExtendedType *Ty, 477645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind WantedType); 478d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 47957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that there is no function declaration for ID. Returns an error 48057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // recovery value to use. 48174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::FunctionDeclaration *reportGetFunctionByIDError(NaClBcIndexSize_t ID); 4829d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 48357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that there is not global variable declaration for ID. Returns an 48457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // error recovery value to use. 48574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::VariableDeclaration * 48674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index); 4879d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 48857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that there is no corresponding ICE type for LLVMTy, and returns 48957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Ice::IceType_void. 490d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type convertToIceTypeError(Type *LLVMTy); 4918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 4928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 49317b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpfbool TopLevelParser::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, 49417b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf const std::string &Message) { 495fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth ErrorStatus.assign(Ice::EC_Bitcode); 4962f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf ++NumErrors; 497819d7b56fe179db006d1c474b557230d8c8e5e2bKarl Schimpf Ice::GlobalContext *Context = Translator.getContext(); 498d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf { // Lock while printing out error message. 499d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf Ice::OstreamLocker L(Context); 5002f67b929c15a30d5ed43b9929cac95a96fec0bbeKarl Schimpf raw_ostream &OldErrStream = setErrStream(Context->getStrError()); 501d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf NaClBitcodeParser::ErrorAt(Level, Bit, Message); 502d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf setErrStream(OldErrStream); 503d8b32896948f53c572b844fee77bb442c8aeff86Karl Schimpf } 504f644a4b3a36d707b32dd4b7855774a346a575e96Jan Voung if (Level >= naclbitc::Error && 505f644a4b3a36d707b32dd4b7855774a346a575e96Jan Voung !Translator.getFlags().getAllowErrorRecovery()) 50622ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal(); 5072f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return true; 5082f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf} 5092f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 51074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid TopLevelParser::reportBadTypeIDAs(NaClBcIndexSize_t ID, 51174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf const ExtendedType *Ty, 512645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType::TypeKind WantedType) { 5138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 5148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 515645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Ty == nullptr) { 516645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Can't find extended type for type id: " << ID; 5178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } else { 518645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Type id " << ID << " not " << WantedType << ". Found: " << *Ty; 5198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 52074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 5218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 5228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 5239d98d791123ce157aab73fba210e4d068935011fKarl SchimpfIce::FunctionDeclaration * 52474cd883a0b3ccb0920e5990ed860b1862ac73090Karl SchimpfTopLevelParser::reportGetFunctionByIDError(NaClBcIndexSize_t ID) { 5259d98d791123ce157aab73fba210e4d068935011fKarl Schimpf std::string Buffer; 5269d98d791123ce157aab73fba210e4d068935011fKarl Schimpf raw_string_ostream StrBuf(Buffer); 5279d98d791123ce157aab73fba210e4d068935011fKarl Schimpf StrBuf << "Function index " << ID 5289d98d791123ce157aab73fba210e4d068935011fKarl Schimpf << " not allowed. Out of range. Must be less than " 529209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf << FunctionDeclarations.size(); 53074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 531209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf if (!FunctionDeclarations.empty()) 532209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf return FunctionDeclarations[0]; 53322ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal(); 5349d98d791123ce157aab73fba210e4d068935011fKarl Schimpf} 5359d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 5369d98d791123ce157aab73fba210e4d068935011fKarl SchimpfIce::VariableDeclaration * 53774cd883a0b3ccb0920e5990ed860b1862ac73090Karl SchimpfTopLevelParser::reportGetGlobalVariableByIDError(NaClBcIndexSize_t Index) { 5389d98d791123ce157aab73fba210e4d068935011fKarl Schimpf std::string Buffer; 5399d98d791123ce157aab73fba210e4d068935011fKarl Schimpf raw_string_ostream StrBuf(Buffer); 5409d98d791123ce157aab73fba210e4d068935011fKarl Schimpf StrBuf << "Global index " << Index 5419d98d791123ce157aab73fba210e4d068935011fKarl Schimpf << " not allowed. Out of range. Must be less than " 5426ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf << VariableDeclarations->size(); 54374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf blockError(StrBuf.str()); 5446ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf if (!VariableDeclarations->empty()) 5456ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return VariableDeclarations->at(0); 54622ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf Fatal(); 5479d98d791123ce157aab73fba210e4d068935011fKarl Schimpf} 5489d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 549d6064a1aaca7a5596618e559a17cb9b20283ca46Karl SchimpfIce::Type TopLevelParser::convertToIceTypeError(Type *LLVMTy) { 550d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 551d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 552d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Invalid LLVM type: " << *LLVMTy; 553d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 554d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return Ice::IceType_void; 555d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 556d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 55757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// Base class for parsing blocks within the bitcode file. Note: Because this is 55857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// the base class of block parsers, we generate error messages if ParseBlock or 55957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull// ParseRecord is not overridden in derived classes. 5608d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass BlockParserBaseClass : public NaClBitcodeParser { 561c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth BlockParserBaseClass() = delete; 5622f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf BlockParserBaseClass(const BlockParserBaseClass &) = delete; 5632f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf BlockParserBaseClass &operator=(const BlockParserBaseClass &) = delete; 5642f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 5658d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 5668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Constructor for the top-level module block parser. 5678d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass(unsigned BlockID, TopLevelParser *Context) 5682f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf : NaClBitcodeParser(BlockID, Context), Context(Context) { 5692f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf Context->setBlockParser(this); 5702f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 5712f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 5722f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf ~BlockParserBaseClass() override { Context->setBlockParser(nullptr); } 5732f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 5742f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf // Returns the printable name of the type of block being parsed. 5752f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf virtual const char *getBlockName() const { 5762f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf // If this class is used, it is parsing an unknown block. 5772f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return "unknown"; 5782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 5798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 58022ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf // Generates an error Message with the Bit address prefixed to it. 58117b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf bool ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, 58217b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf const std::string &Message) final; 5838d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 5848d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprotected: 5858d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // The context parser that contains the decoded state. 5868d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf TopLevelParser *Context; 5878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 5888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Constructor for nested block parsers. 5898d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 5908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf : NaClBitcodeParser(BlockID, EnclosingParser), 5918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Context(EnclosingParser->Context) {} 5928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 593d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // Gets the translator associated with the bitcode parser. 5946ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf Ice::Translator &getTranslator() const { return Context->getTranslator(); } 5956ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf 5966ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf const Ice::ClFlags &getFlags() const { return getTranslator().getFlags(); } 597d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 5986fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf bool isIRGenerationDisabled() const { 599df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf return getTranslator().getFlags().getDisableIRGeneration(); 6006fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 6016fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 60257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Default implementation. Reports that block is unknown and skips its 60357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // contents. 6048e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 6058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 60657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Default implementation. Reports that the record is not understood. 6078e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 6088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 60957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the size of the record is Size. Return true if valid. Otherwise 61057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // generates an error and returns false. 61174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSize(size_t Size, const char *RecordName) { 6128d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 613d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Values.size() == Size) 614d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 61574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportRecordSizeError(Size, RecordName, nullptr); 6168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 6178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 6188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 61957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the size of the record is at least as large as the LowerLimit. 62057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns true if valid. Otherwise generates an error and returns false. 62174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSizeAtLeast(size_t LowerLimit, const char *RecordName) { 6228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 623d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Values.size() >= LowerLimit) 624d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 62574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportRecordSizeError(LowerLimit, RecordName, "at least"); 6268d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 6278d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 6288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 629d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // Checks if the size of the record is no larger than the 63057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // UpperLimit. Returns true if valid. Otherwise generates an error and 63157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // returns false. 63274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSizeAtMost(size_t UpperLimit, const char *RecordName) { 6338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 634d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Values.size() <= UpperLimit) 635d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 63674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportRecordSizeError(UpperLimit, RecordName, "no more than"); 6378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 6388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 6398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 64057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the size of the record is at least as large as the LowerLimit, 64157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and no larger than the UpperLimit. Returns true if valid. Otherwise 64257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // generates an error and returns false. 64374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf bool isValidRecordSizeInRange(size_t LowerLimit, size_t UpperLimit, 644d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *RecordName) { 645d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidRecordSizeAtLeast(LowerLimit, RecordName) || 646d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf isValidRecordSizeAtMost(UpperLimit, RecordName); 6478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 6488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 6498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 65057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Generates a record size error. ExpectedSize is the number of elements 65157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// expected. RecordName is the name of the kind of record that has incorrect 65257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// size. ContextMessage (if not nullptr) is appended to "record expects" to 65357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// describe how ExpectedSize should be interpreted. 65474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportRecordSizeError(size_t ExpectedSize, const char *RecordName, 655d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *ContextMessage); 6568d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 6578d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 65874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfbool TopLevelParser::blockError(const std::string &Message) { 6592f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (BlockParser) 6602f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return BlockParser->Error(Message); 6612f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf else 6622f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return Error(Message); 6632f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf} 6642f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 6652f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf// Generates an error Message with the bit address prefixed to it. 666f644a4b3a36d707b32dd4b7855774a346a575e96Jan Voungbool BlockParserBaseClass::ErrorAt(naclbitc::ErrorLevel Level, uint64_t Bit, 667f644a4b3a36d707b32dd4b7855774a346a575e96Jan Voung const std::string &Message) { 6682f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf std::string Buffer; 6692f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf raw_string_ostream StrBuf(Buffer); 67057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: If dump routines have been turned off, the error messages will not 67157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // be readable. Hence, replace with simple error. We also use the simple form 67257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // for unit tests. 673df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf if (getFlags().getGenerateUnitTestMessages()) { 6742f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Invalid " << getBlockName() << " record: <" << Record.GetCode(); 6752f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf for (const uint64_t Val : Record.GetValues()) { 6762f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << " " << Val; 6772f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 6782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << ">"; 679df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf } else { 680df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf StrBuf << Message; 6812f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 68217b1a133a805ea9384d4a5ae5e0b449162b794f7Karl Schimpf return Context->ErrorAt(Level, Bit, StrBuf.str()); 6832f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf} 6842f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 68574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid BlockParserBaseClass::reportRecordSizeError(size_t ExpectedSize, 686d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *RecordName, 687d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const char *ContextMessage) { 688d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 689d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 6902f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *BlockName = getBlockName(); 6912f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char FirstChar = toupper(*BlockName); 6922f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << FirstChar << (BlockName + 1) << " " << RecordName 6932f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf << " record expects"; 694d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (ContextMessage) 695d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << " " << ContextMessage; 696d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << " " << ExpectedSize << " argument"; 697d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (ExpectedSize > 1) 698d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "s"; 699d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << ". Found: " << Record.GetValues().size(); 700d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 701d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 702d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 7038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfbool BlockParserBaseClass::ParseBlock(unsigned BlockID) { 70457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // If called, derived class doesn't know how to handle block. Report error 70557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and skip. 7068d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 7078d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 7088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StrBuf << "Don't know how to parse block id: " << BlockID; 7098d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 7108d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf SkipBlock(); 7118d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return false; 7128d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 7138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 7148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid BlockParserBaseClass::ProcessRecord() { 7158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // If called, derived class doesn't know how to handle. 7168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 7178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 7182f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Don't know how to process " << getBlockName() 7192f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf << " record:" << Record; 7208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 7218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 7228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 7238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf// Class to parse a types block. 7248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass TypesParser : public BlockParserBaseClass { 725c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TypesParser() = delete; 726c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TypesParser(const TypesParser &) = delete; 727c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth TypesParser &operator=(const TypesParser &) = delete; 728c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth 7298d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 7308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf TypesParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 73158455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser), 732eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Timer(Ice::TimerStack::TT_parseTypes, getTranslator().getContext()) {} 7338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 73474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ~TypesParser() override { 73574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (ExpectedNumTypes != Context->getNumTypeIDValues()) { 73674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 73774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 73874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Types block expected " << ExpectedNumTypes 73974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf << " types but found: " << NextTypeId; 74074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 74174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 74274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 7438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 7448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 74558455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 74657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // The type ID that will be associated with the next type defining record in 74757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the types block. 74874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NextTypeId = 0; 74974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf 75074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf // The expected number of types, based on record TYPE_CODE_NUMENTRY. 75174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t ExpectedNumTypes = 0; 7528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 7538e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 754645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf 7552f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "type"; } 7562f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 757645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf void setNextTypeIDAsSimpleType(Ice::Type Ty) { 758645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Context->getTypeByIDForDefining(NextTypeId++)->setAsSimpleType(Ty); 759645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 7608d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 7618d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 7628d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid TypesParser::ProcessRecord() { 7638d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 7648d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 76574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf case naclbitc::TYPE_CODE_NUMENTRY: { 7668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // NUMENTRY: [numentries] 7672f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "count")) 7688d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 76974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t Size = Values[0]; 77074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (Size > NaClBcIndexSize_t_Max) { 77174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 77274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 77374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Size to big for count record: " << Size; 77474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 77574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExpectedNumTypes = NaClBcIndexSize_t_Max; 77674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 77757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // The code double checks that Expected size and the actual size at the end 77857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // of the block. To reduce allocations we preallocate the space. 77974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf // 78057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // However, if the number is large, we suspect that the number is 78157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // (possibly) incorrect. In that case, we preallocate a smaller space. 78274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf constexpr uint64_t DefaultLargeResizeValue = 1000000; 78374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Context->resizeTypeIDValues(std::min(Size, DefaultLargeResizeValue)); 78474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf ExpectedNumTypes = Size; 7858d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 78674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 7878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_VOID: 7888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VOID 7892f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "void")) 790d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 791645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_void); 792645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 7938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_FLOAT: 7948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // FLOAT 7952f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "float")) 796d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 797645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_f32); 798645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 7998d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_DOUBLE: 8008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // DOUBLE 8012f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "double")) 802d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 803645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_f64); 804645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 8058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_INTEGER: 8068d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // INTEGER: [width] 8072f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "integer")) 808d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 809645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Values[0]) { 810645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 1: 811645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i1); 812645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 813645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 8: 814645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i8); 815645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 816645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 16: 817645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i16); 818645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 819645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 32: 820645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i32); 821645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 822645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 64: 823645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_i64); 824645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 825645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 826645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 827645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 828645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf { 829d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 830d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 831d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Type integer record with invalid bitsize: " << Values[0]; 832d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 833d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 834645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 835d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::TYPE_CODE_VECTOR: { 8368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VECTOR: [numelts, eltty] 8372f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "vector")) 838d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 839645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type BaseTy = Context->getSimpleTypeByID(Values[1]); 840645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::SizeT Size = Values[0]; 841645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (BaseTy) { 842645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i1: 843645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf switch (Size) { 844645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 4: 845645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v4i1); 846645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 847645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 8: 848645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v8i1); 849645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 850645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case 16: 851645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v16i1); 852645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 853645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 854645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 855645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 856645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 857645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i8: 858645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 16) { 859645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v16i8); 860645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 861645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 862645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 863645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i16: 864645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 8) { 865645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v8i16); 866645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 867645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 868645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 869645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_i32: 870645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 4) { 871645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v4i32); 872645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 873645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 874645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 875645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf case Ice::IceType_f32: 876645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Size == 4) { 877645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf setNextTypeIDAsSimpleType(Ice::IceType_v4f32); 878645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 879645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 880645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 881645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf default: 882645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf break; 883645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 884645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf { 885d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 886d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 887645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Invalid type vector record: <" << Values[0] << " x " << BaseTy 888d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf << ">"; 889d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 890d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 891645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 892d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 8938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_CODE_FUNCTION: { 8948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // FUNCTION: [vararg, retty, paramty x N] 8952f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "signature")) 896d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 897645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (Values[0]) 898645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Error("Function type can't define varargs"); 899645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ExtendedType *Ty = Context->getTypeByIDForDefining(NextTypeId++); 900645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ty->setAsFunctionType(); 901645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncSigExtendedType *FuncTy = cast<FuncSigExtendedType>(Ty); 902645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncTy->setReturnType(Context->getSimpleTypeByID(Values[1])); 90374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf for (size_t i = 2, e = Values.size(); i != e; ++i) { 90457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Check that type void not used as argument type. Note: PNaCl 90557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // restrictions can't be checked until we know the name, because we have 90657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // to check for intrinsic signatures. 907645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type ArgTy = Context->getSimpleTypeByID(Values[i]); 908645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf if (ArgTy == Ice::IceType_void) { 909645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf std::string Buffer; 910645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf raw_string_ostream StrBuf(Buffer); 911645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf StrBuf << "Type for parameter " << (i - 1) 912645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf << " not valid. Found: " << ArgTy; 913645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ArgTy = Ice::IceType_i32; 914645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf } 915645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf FuncTy->appendArgType(ArgTy); 9168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 917645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf return; 9188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 9198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 9208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 921d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return; 9228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 923645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf llvm_unreachable("Unknown type block record not processed!"); 9248d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 9258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 9269d98d791123ce157aab73fba210e4d068935011fKarl Schimpf/// Parses the globals block (i.e. global variable declarations and 9279d98d791123ce157aab73fba210e4d068935011fKarl Schimpf/// corresponding initializers). 9288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass GlobalsParser : public BlockParserBaseClass { 929c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth GlobalsParser() = delete; 930c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth GlobalsParser(const GlobalsParser &) = delete; 931c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth GlobalsParser &operator=(const GlobalsParser &) = delete; 932c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth 9338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 9348d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf GlobalsParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 93558455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser), 93658455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseGlobals, getTranslator().getContext()), 937aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NumFunctionIDs(Context->getNumFunctionIDs()), 9381bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto DummyGlobalVar( 9391bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Ice::VariableDeclaration::create(getTranslator().getContext())), 9409d98d791123ce157aab73fba210e4d068935011fKarl Schimpf CurGlobalVar(DummyGlobalVar) {} 9418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 942e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~GlobalsParser() final = default; 9436fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 9442f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "globals"; } 9452f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 9468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 9478072bae156fa62e51e02925997992c4908a2682fAndrew Scull using GlobalVarsMapType = 9488072bae156fa62e51e02925997992c4908a2682fAndrew Scull std::unordered_map<NaClBcIndexSize_t, Ice::VariableDeclaration *>; 949aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 95058455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 951aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 952aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Holds global variables generated/referenced in the global variables block. 953aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf GlobalVarsMapType GlobalVarsMap; 954aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 955aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Holds the number of defined function IDs. 956aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t NumFunctionIDs; 957aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 95857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Holds the specified number of global variables by the count record in the 95957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // global variables block. 960aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t SpecifiedNumberVars = 0; 961aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 962e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // Keeps track of how many initializers are expected for the global variable 9639d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // declaration being built. 96474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t InitializersNeeded = 0; 9658d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 9669d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // The index of the next global variable declaration. 96774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NextGlobalID = 0; 9688d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 96957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Dummy global variable declaration to guarantee CurGlobalVar is always 97057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // defined (allowing code to not need to check if CurGlobalVar is nullptr). 9719d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::VariableDeclaration *DummyGlobalVar; 972e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 9739d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // Holds the current global variable declaration being built. 9749d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::VariableDeclaration *CurGlobalVar; 975e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf 976aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Returns the global variable associated with the given Index. 977aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Ice::VariableDeclaration *getGlobalVarByID(NaClBcIndexSize_t Index) { 978aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Ice::VariableDeclaration *&Decl = GlobalVarsMap[Index]; 979aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (Decl == nullptr) 980aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Decl = Ice::VariableDeclaration::create(getTranslator().getContext()); 981aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return Decl; 982aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 983aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 984aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Returns the global declaration associated with the given index. 985aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Ice::GlobalDeclaration *getGlobalDeclByID(NaClBcIndexSize_t Index) { 986aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (Index < NumFunctionIDs) 987aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return Context->getFunctionByID(Index); 988aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return getGlobalVarByID(Index - NumFunctionIDs); 989aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 990aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 991aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // If global variables parsed correctly, install them into the top-level 992aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // context. 993aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf void installGlobalVariables() { 994aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Verify specified number of globals matches number found. 995aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf size_t NumGlobals = GlobalVarsMap.size(); 996aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (SpecifiedNumberVars != NumGlobals || 997aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf SpecifiedNumberVars != NextGlobalID) { 9988d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 9998d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 1000aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf StrBuf << getBlockName() << " block expects " << SpecifiedNumberVars 1001aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf << " global variables. Found: " << GlobalVarsMap.size(); 10028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 1003aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf return; 10048d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1005aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Install global variables into top-level context. 1006aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf for (size_t I = 0; I < NumGlobals; ++I) 1007aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Context->addGlobalDeclaration(GlobalVarsMap[I]); 1008aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 1009aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf 1010aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf void ExitBlock() override { 1011aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf verifyNoMissingInitializers(); 1012aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf installGlobalVariables(); 10138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ExitBlock(); 10148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 10168e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 10178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 10189d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // Checks if the number of initializers for the CurGlobalVar is the same as 1019e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // the number found in the bitcode file. If different, and error message is 1020e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // generated, and the internal state of the parser is fixed so this condition 1021e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf // is no longer violated. 10228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf void verifyNoMissingInitializers() { 10239d98d791123ce157aab73fba210e4d068935011fKarl Schimpf size_t NumInits = CurGlobalVar->getInitializers().size(); 1024e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (InitializersNeeded != NumInits) { 10258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 10268d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 1027e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf StrBuf << "Global variable @g" << NextGlobalID << " expected " 10288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf << InitializersNeeded << " initializer"; 10298d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (InitializersNeeded > 1) 10308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StrBuf << "s"; 1031e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf StrBuf << ". Found: " << NumInits; 10328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 10339d98d791123ce157aab73fba210e4d068935011fKarl Schimpf InitializersNeeded = NumInits; 10348d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10358d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10368d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 10378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 10388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid GlobalsParser::ProcessRecord() { 10398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 10408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 10418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_COUNT: 10428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // COUNT: [n] 10432f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "count")) 10448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 1045aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (SpecifiedNumberVars || NextGlobalID) { 10468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error("Globals count record not first in block."); 10478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 1049aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf SpecifiedNumberVars = Values[0]; 10508d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10518d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_VAR: { 10528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VAR: [align, isconst] 10532f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "variable")) 10548d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf verifyNoMissingInitializers(); 1056aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // Always build the global variable, even if IR generation is turned off. 1057aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // This is needed because we need a placeholder in the top-level context 1058aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf // when no IR is generated. 1059aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf CurGlobalVar = getGlobalVarByID(NextGlobalID); 10606fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (!isIRGenerationDisabled()) { 10616fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf InitializersNeeded = 1; 10626fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf CurGlobalVar->setAlignment((1 << Values[0]) >> 1); 10636fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf CurGlobalVar->setIsConstant(Values[1] != 0); 10646fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 1065e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf ++NextGlobalID; 10668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10678d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10688d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_COMPOUND: 10698d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // COMPOUND: [size] 10702f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "compound")) 10718d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10729d98d791123ce157aab73fba210e4d068935011fKarl Schimpf if (!CurGlobalVar->getInitializers().empty()) { 10738d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error("Globals compound record not first initializer"); 10748d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10758d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10768d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Values[0] < 2) { 10778d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 10788d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 10792f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << getBlockName() 10802f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf << " compound record size invalid. Found: " << Values[0]; 10818d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 10828d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10838d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10846fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 10856fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 10868d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf InitializersNeeded = Values[0]; 10878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_ZEROFILL: { 10898d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // ZEROFILL: [size] 10902f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "zerofill")) 10918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 10926fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 10936fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 10949d98d791123ce157aab73fba210e4d068935011fKarl Schimpf CurGlobalVar->addInitializer( 10951bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Ice::VariableDeclaration::ZeroInitializer::create(Values[0])); 10969d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return; 10978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 10988d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_DATA: { 10998d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // DATA: [b0, b1, ...] 11002f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(1, "data")) 11018d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11026fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 11036fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 11049d98d791123ce157aab73fba210e4d068935011fKarl Schimpf CurGlobalVar->addInitializer( 11051bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Ice::VariableDeclaration::DataInitializer::create(Values)); 11069d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return; 11078d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_RELOC: { 11098d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // RELOC: [val, [addend]] 11102f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeInRange(1, 2, "reloc")) 11118d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11126fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 11136fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 1114aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t Index = Values[0]; 1115aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf NaClBcIndexSize_t IndexLimit = SpecifiedNumberVars + NumFunctionIDs; 1116aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf if (Index >= IndexLimit) { 1117aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf std::string Buffer; 1118aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf raw_string_ostream StrBuf(Buffer); 1119aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf StrBuf << "Relocation index " << Index << " to big. Expect index < " 1120aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf << IndexLimit; 1121aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf Error(StrBuf.str()); 1122aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf } 112374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t Offset = 0; 112474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (Values.size() == 2) { 1125e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf Offset = Values[1]; 112674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (Offset > std::numeric_limits<uint32_t>::max()) { 112774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 112874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 112974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Addend of global reloc record too big: " << Offset; 113074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 113174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 113274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 11331bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto CurGlobalVar->addInitializer( 11341bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Ice::VariableDeclaration::RelocInitializer::create( 1135aa0ce790f7426ad3be6e3c648ba84abbf1928378Karl Schimpf getGlobalDeclByID(Index), Offset)); 11369d98d791123ce157aab73fba210e4d068935011fKarl Schimpf return; 11378d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 11398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 11408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 11418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 11428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 11438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1144c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf/// Base class for parsing a valuesymtab block in the bitcode file. 11458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass ValuesymtabParser : public BlockParserBaseClass { 1146c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ValuesymtabParser() = delete; 11470795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ValuesymtabParser(const ValuesymtabParser &) = delete; 11480795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth void operator=(const ValuesymtabParser &) = delete; 11498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 11508d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 1151c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf ValuesymtabParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 1152c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser) {} 11538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1154e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ValuesymtabParser() override = default; 11558d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 11562f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "valuesymtab"; } 11572f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 1158c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfprotected: 11598072bae156fa62e51e02925997992c4908a2682fAndrew Scull using StringType = SmallString<128>; 1160c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 116152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // Returns the name to identify the kind of symbol table this is 116252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // in error messages. 116352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf virtual const char *getTableKind() const = 0; 116452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 1165c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Associates Name with the value defined by the given Index. 116674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf virtual void setValueName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1167c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 1168c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Associates Name with the value defined by the given Index; 116974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf virtual void setBbName(NaClBcIndexSize_t Index, StringType &Name) = 0; 1170c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 117152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // Reports that the assignment of Name to the value associated with 117252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // index is not possible, for the given Context. 117352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, 117452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StringType &Name); 117552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 11768d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfprivate: 117752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf using NamesSetType = std::unordered_set<StringType>; 117852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf NamesSetType ValueNames; 117952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf NamesSetType BlockNames; 118052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 11818e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 11828d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 118352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf // Extracts out ConvertedName. Returns true if unique wrt to Names. 118452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf bool convertToString(NamesSetType &Names, StringType &ConvertedName) { 11858d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 11868d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf for (size_t i = 1, e = Values.size(); i != e; ++i) { 11878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ConvertedName += static_cast<char>(Values[i]); 11888d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 118952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf auto Pair = Names.insert(ConvertedName); 119052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf return Pair.second; 11918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 119252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 119352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void ReportDuplicateName(const char *NameCat, StringType &Name); 11948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 11958d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 119652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpfvoid ValuesymtabParser::reportUnableToAssign(const char *Context, 119752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf NaClBcIndexSize_t Index, 119852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StringType &Name) { 119952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf std::string Buffer; 120052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf raw_string_ostream StrBuf(Buffer); 120152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StrBuf << getTableKind() << " " << getBlockName() << ": " << Context 120252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf << " name '" << Name << "' can't be associated with index " << Index; 120352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf Error(StrBuf.str()); 120452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf} 120552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 120652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpfvoid ValuesymtabParser::ReportDuplicateName(const char *NameCat, 120752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StringType &Name) { 120852863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf std::string Buffer; 120952863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf raw_string_ostream StrBuf(Buffer); 121052863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf StrBuf << getTableKind() << " " << getBlockName() << " defines duplicate " 121152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf << NameCat << " name: '" << Name << "'"; 121252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf Error(StrBuf.str()); 121352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf} 121452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 12158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid ValuesymtabParser::ProcessRecord() { 12168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 12178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StringType ConvertedName; 12188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 12198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::VST_CODE_ENTRY: { 12208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VST_ENTRY: [ValueId, namechar x N] 12212f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "value entry")) 12228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 122352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf if (convertToString(ValueNames, ConvertedName)) 122452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf setValueName(Values[0], ConvertedName); 122552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf else 122652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf ReportDuplicateName("value", ConvertedName); 12278d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 12288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12298d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::VST_CODE_BBENTRY: { 12308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VST_BBENTRY: [BbId, namechar x N] 12312f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "basic block entry")) 12328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 123352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf if (convertToString(BlockNames, ConvertedName)) 123452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf setBbName(Values[0], ConvertedName); 123552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf else 123652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf ReportDuplicateName("block", ConvertedName); 1237c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return; 12388d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12398d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 12408d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf break; 12418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 12428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // If reached, don't know how to handle record. 12438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 12448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 12458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 12468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 1247d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf/// Parses function blocks in the bitcode file. 1248d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfclass FunctionParser : public BlockParserBaseClass { 1249c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth FunctionParser() = delete; 12500795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth FunctionParser(const FunctionParser &) = delete; 12510795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth FunctionParser &operator=(const FunctionParser &) = delete; 1252d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 1253d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfpublic: 1254d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf FunctionParser(unsigned BlockID, BlockParserBaseClass *EnclosingParser) 1255d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf : BlockParserBaseClass(BlockID, EnclosingParser), 125658455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseFunctions, getTranslator().getContext()), 1257eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Func(nullptr), FcnId(Context->getNextFunctionBlockValueID()), 12589d98d791123ce157aab73fba210e4d068935011fKarl Schimpf FuncDecl(Context->getFunctionByID(FcnId)), 1259e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf CachedNumGlobalValueIDs(Context->getNumGlobalIDs()), 1260eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth NextLocalInstIndex(Context->getNumGlobalIDs()) {} 12618e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 12628e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth bool convertFunction() { 12638e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth const Ice::TimerStackIdT StackID = Ice::GlobalContext::TSK_Funcs; 12648e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::TimerIdT TimerID = 0; 1265df80eb862a6e44a4ee0a4e868f5ef1543f368020Karl Schimpf const bool TimeThisFunction = getFlags().getTimeEachFunction(); 12668e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth if (TimeThisFunction) { 12678e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth TimerID = getTranslator().getContext()->getTimerID(StackID, 12688e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth FuncDecl->getName()); 12698e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth getTranslator().getContext()->pushTimer(TimerID, StackID); 12708e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth } 12718e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 127257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: The Cfg is created, even when IR generation is disabled. This is 127357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // done to install a CfgLocalAllocator for various internal containers. 1274209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Func = Ice::Cfg::create(getTranslator().getContext(), 1275209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf getTranslator().getNextSequenceNumber()); 12768e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::Cfg::setCurrentCfg(Func.get()); 12778e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 127857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // TODO(kschimpf) Clean up API to add a function signature to a CFG. 12799d98d791123ce157aab73fba210e4d068935011fKarl Schimpf const Ice::FuncSigType &Signature = FuncDecl->getSignature(); 12806fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 12816fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf CurrentNode = nullptr; 12826fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf for (Ice::Type ArgType : Signature.getArgList()) { 12836fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf (void)ArgType; 12846fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 12856fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 12866fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } else { 12876fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Func->setFunctionName(FuncDecl->getName()); 12886fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Func->setReturnType(Signature.getReturnType()); 12896fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Func->setInternal(FuncDecl->getLinkage() == GlobalValue::InternalLinkage); 129098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf CurrentNode = installNextBasicBlock(); 12916fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Func->setEntryNode(CurrentNode); 12926fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf for (Ice::Type ArgType : Signature.getArgList()) { 12936fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Func->addArg(getNextInstVar(ArgType)); 12946fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 1295d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 12968e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth bool ParserResult = ParseThisBlock(); 12978e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 129857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Temporarily end per-function timing, which will be resumed by the 129957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // translator function. This is because translation may be done 130057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // asynchronously in a separate thread. 13018e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth if (TimeThisFunction) 13028e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth getTranslator().getContext()->popTimer(TimerID, StackID); 13038e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 13048e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::Cfg::setCurrentCfg(nullptr); 130557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: Once any errors have been found, we turn off all translation of 130657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // all remaining functions. This allows successive parsing errors to be 130757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // reported, without adding extra checks to the translator for such parsing 130857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // errors. 1309bbca754a63fb1e80b4d0f034aa26538f3a8a2a26Jim Stichnoth if (Context->getNumErrors() == 0 && Func) { 13108e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth getTranslator().translateFcn(std::move(Func)); 13118e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth // The translator now has ownership of Func. 13128e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth } else { 13138e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.reset(); 13148e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth } 13158e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth 13168e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth return ParserResult; 1317d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1318d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 1319e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~FunctionParser() final = default; 1320d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 13212f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "function"; } 13222f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 13238e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::Cfg *getFunc() const { return Func.get(); } 13242f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 132574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t getNumGlobalIDs() const { return CachedNumGlobalValueIDs; } 13262f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 13276fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf void setNextLocalInstIndex(Ice::Operand *Op) { 13286fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setOperand(NextLocalInstIndex++, Op); 13298f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 1330f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 13316fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // Set the next constant ID to the given constant C. 13326fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf void setNextConstantID(Ice::Constant *C) { setNextLocalInstIndex(C); } 13336fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 13342f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf // Returns the value referenced by the given value Index. 133574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Operand *getOperand(NaClBcIndexSize_t Index) { 13362f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (Index < CachedNumGlobalValueIDs) { 13376ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf return Context->getGlobalConstantByID(Index); 13382f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 13399d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf if (isIRGenerationDisabled()) 13409d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf return nullptr; 134174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 13429d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf if (LocalIndex >= LocalOperands.size()) 13439d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf reportGetOperandUndefined(Index); 13442f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf Ice::Operand *Op = LocalOperands[LocalIndex]; 13459d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf if (Op == nullptr) 13469d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf reportGetOperandUndefined(Index); 13472f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf return Op; 13482f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf } 13492f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 1350d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfprivate: 135158455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 135298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // The number of words in the bitstream defining the function block. 135398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf uint64_t NumBytesDefiningFunction = 0; 13547a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // Maximum number of records that can appear in the function block, based on 13557a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // the number of bytes defining the function block. 13567a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf uint64_t MaxRecordsInBlock = 0; 1357d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The corresponding ICE function defined by the function block. 13588e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth std::unique_ptr<Ice::Cfg> Func; 1359d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The index to the current basic block being built. 136074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t CurrentBbIndex = 0; 136198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // The number of basic blocks declared for the function block. 136298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf NaClBcIndexSize_t DeclaredNumberBbs = 0; 1363d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The basic block being built. 1364eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Ice::CfgNode *CurrentNode = nullptr; 1365d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // The ID for the function. 136674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t FcnId; 13679d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // The corresponding function declaration. 13689d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::FunctionDeclaration *FuncDecl; 13698f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Holds the dividing point between local and global absolute value indices. 137074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t CachedNumGlobalValueIDs; 137157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Holds operands local to the function block, based on indices defined in 137257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the bitcode file. 1373209318af2b035d729225c5d86dbeb27935ebfafbKarl Schimpf Ice::OperandList LocalOperands; 137457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Holds the index within LocalOperands corresponding to the next instruction 137557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // that generates a value. 137674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t NextLocalInstIndex; 137757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // True if the last processed instruction was a terminating instruction. 1378eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth bool InstIsTerminating = false; 1379742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf // Upper limit of alignment power allowed by LLVM 1380f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf static const uint32_t AlignPowerLimit = 29; 1381d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 138257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Extracts the corresponding Alignment to use, given the AlignPower (i.e. 138357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // 2**(AlignPower-1), or 0 if AlignPower == 0). InstName is the name of the 138457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // instruction the alignment appears in. 1385f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf void extractAlignment(const char *InstName, uint32_t AlignPower, 1386f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf uint32_t &Alignment) { 1387af238b25224c684aac5b434c45d6f1c1cf42a1eeKarl Schimpf if (AlignPower <= AlignPowerLimit + 1) { 1388f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf Alignment = (1 << AlignPower) >> 1; 138941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 139041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 139141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 139241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 139341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstName << " alignment greater than 2**" << AlignPowerLimit 1394af238b25224c684aac5b434c45d6f1c1cf42a1eeKarl Schimpf << ". Found: 2**" << (AlignPower - 1); 139541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 139641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf // Error recover with value that is always acceptable. 139741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Alignment = 1; 139841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 139941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 14008e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 1401f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 14028e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 1403d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 140498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf void EnterBlock(unsigned NumWords) final { 140598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Note: Bitstream defines words as 32-bit values. 140698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf NumBytesDefiningFunction = NumWords * sizeof(uint32_t); 14077a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // We know that all records are minimally defined by a two-bit abreviation. 14087a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf MaxRecordsInBlock = NumBytesDefiningFunction * (CHAR_BIT >> 1); 140998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 1410d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 141198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf void ExitBlock() override; 1412d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 141398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Creates and appends a new basic block to the list of basic blocks. 141498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Ice::CfgNode *installNextBasicBlock() { 141598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf assert(!isIRGenerationDisabled()); 141698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Ice::CfgNode *Node = Func->makeNode(); 141798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return Node; 141898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 141998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 142098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Returns the Index-th basic block in the list of basic blocks. 142198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Ice::CfgNode *getBasicBlock(NaClBcIndexSize_t Index) { 142298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf assert(!isIRGenerationDisabled()); 142398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (Index >= Func->getNumNodes()) { 142498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf std::string Buffer; 142598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf raw_string_ostream StrBuf(Buffer); 142698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf StrBuf << "Reference to basic block " << Index 142798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << " not found. Must be less than " << Func->getNumNodes(); 142898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error(StrBuf.str()); 142998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Index = 0; 143098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 143198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return Func->getNodes()[Index]; 143298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 143398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 143457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns the Index-th basic block in the list of basic blocks. Assumes 143557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Index corresponds to a branch instruction. Hence, if the branch references 143657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the entry block, it also generates a corresponding error. 143774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::CfgNode *getBranchBasicBlock(NaClBcIndexSize_t Index) { 14386fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(!isIRGenerationDisabled()); 1439c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf if (Index == 0) { 1440c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Error("Branch to entry block not allowed"); 1441c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 144247661568f8c3811634913cfb43144a95d8340758Karl Schimpf return getBasicBlock(Index); 1443c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 1444c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf 14458f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Generate an instruction variable with type Ty. 14468f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Variable *createInstVar(Ice::Type Ty) { 14476fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(!isIRGenerationDisabled()); 144847661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (Ty == Ice::IceType_void) { 144947661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error("Can't define instruction value using type void"); 145047661568f8c3811634913cfb43144a95d8340758Karl Schimpf // Recover since we can't throw an exception. 145147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ty = Ice::IceType_i32; 145247661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 1453144cdceaebc730d39e35861e4cc9577545e26bceJim Stichnoth return Func->makeVariable(Ty); 14548f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 14558f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 14568f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Generates the next available local variable using the given type. 14578f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Variable *getNextInstVar(Ice::Type Ty) { 14586fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(!isIRGenerationDisabled()); 14598f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf assert(NextLocalInstIndex >= CachedNumGlobalValueIDs); 14608f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Before creating one, see if a forwardtyperef has already defined it. 146174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t LocalIndex = NextLocalInstIndex - CachedNumGlobalValueIDs; 14628f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf if (LocalIndex < LocalOperands.size()) { 14638f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Operand *Op = LocalOperands[LocalIndex]; 1464e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (Op != nullptr) { 14658f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf if (Ice::Variable *Var = dyn_cast<Ice::Variable>(Op)) { 14668f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf if (Var->getType() == Ty) { 14678f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf ++NextLocalInstIndex; 14688f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return Var; 14698f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 14708f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 14718f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf std::string Buffer; 14728f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf raw_string_ostream StrBuf(Buffer); 14738f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf StrBuf << "Illegal forward referenced instruction (" 14748f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf << NextLocalInstIndex << "): " << *Op; 14758f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Error(StrBuf.str()); 14768f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf ++NextLocalInstIndex; 14778f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return createInstVar(Ty); 14788f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 14798f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 14808f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Ice::Variable *Var = createInstVar(Ty); 14818f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf setOperand(NextLocalInstIndex++, Var); 1482d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return Var; 1483d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1484d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 148557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Converts a relative index (wrt to BaseIndex) to an absolute value index. 148674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t convertRelativeToAbsIndex(NaClRelBcIndexSize_t Id, 148774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClRelBcIndexSize_t BaseIndex) { 148847661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (BaseIndex < Id) { 1489d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 1490d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 1491d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Invalid relative value id: " << Id 149247661568f8c3811634913cfb43144a95d8340758Karl Schimpf << " (must be <= " << BaseIndex << ")"; 1493d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 1494d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return 0; 1495d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 149647661568f8c3811634913cfb43144a95d8340758Karl Schimpf return BaseIndex - Id; 1497d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1498d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 14998f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Sets element Index (in the local operands list) to Op. 150074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void setOperand(NaClBcIndexSize_t Index, Ice::Operand *Op) { 15016fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Op || isIRGenerationDisabled()); 15028f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Check if simple push works. 150374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t LocalIndex = Index - CachedNumGlobalValueIDs; 15047a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (LocalIndex == LocalOperands.size()) { 15057a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands.push_back(Op); 15067a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf return; 15077a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf } 15087a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf 15097a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // Must be forward reference, expand vector to accommodate. 15107a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (LocalIndex >= LocalOperands.size()) { 15117a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (LocalIndex > MaxRecordsInBlock) { 15127a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf std::string Buffer; 15137a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf raw_string_ostream StrBuf(Buffer); 15147a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf StrBuf << "Forward reference @" << Index << " too big. Have " 15157a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf << CachedNumGlobalValueIDs << " globals and function contains " 15167a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf << NumBytesDefiningFunction << " bytes"; 15177a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf Fatal(StrBuf.str()); 15187a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // Recover by using index one beyond the maximal allowed. 15197a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalIndex = MaxRecordsInBlock; 15207a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf } 15217a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands.resize(LocalIndex + 1); 15227a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf } 15238f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15248f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // If element not defined, set it. 15257a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf Ice::Operand *OldOp = LocalOperands[LocalIndex]; 15267a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (OldOp == nullptr) { 15277a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands[LocalIndex] = Op; 15288f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return; 15298f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 15308f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15317a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // See if forward reference matches. 15327a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (OldOp == Op) 15338f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return; 15348f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf 15358f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // Error has occurred. 15368f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf std::string Buffer; 15378f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf raw_string_ostream StrBuf(Buffer); 1538d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Multiple definitions for index " << Index << ": " << *Op 15397a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf << " and " << *OldOp; 15408f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf Error(StrBuf.str()); 15417a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf LocalOperands[LocalIndex] = Op; 1542d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1543d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 154457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns the relative operand (wrt to BaseIndex) referenced by the given 154557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // value Index. 154674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Ice::Operand *getRelativeOperand(NaClBcIndexSize_t Index, 154774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t BaseIndex) { 154847661568f8c3811634913cfb43144a95d8340758Karl Schimpf return getOperand(convertRelativeToAbsIndex(Index, BaseIndex)); 154947661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 155047661568f8c3811634913cfb43144a95d8340758Karl Schimpf 155147661568f8c3811634913cfb43144a95d8340758Karl Schimpf // Returns the absolute index of the next value generating instruction. 155274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t getNextInstIndex() const { return NextLocalInstIndex; } 155371ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf 155457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Generates type error message for binary operator Op operating on Type 155557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // OpTy. 155674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy); 1557d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 155857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Validates if integer logical Op, for type OpTy, is valid. Returns true if 155957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // valid. Otherwise generates error message and returns false. 1560d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool isValidIntegerLogicalOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1561d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Ice::isIntegerType(OpTy)) 1562d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 156374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportInvalidBinaryOp(Op, OpTy); 1564d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1565d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1566d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 156757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Validates if integer (or vector of integers) arithmetic Op, for type OpTy, 156857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // is valid. Returns true if valid. Otherwise generates error message and 156957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // returns false. 1570d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool isValidIntegerArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1571d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Ice::isIntegerArithmeticType(OpTy)) 1572d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 157374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportInvalidBinaryOp(Op, OpTy); 1574d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1575d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1576d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 157757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if floating arithmetic Op, for type OpTy, is valid. Returns true if 157857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // valid. Otherwise generates an error message and returns false; 1579d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool isValidFloatingArithOp(Ice::InstArithmetic::OpKind Op, Ice::Type OpTy) { 1580d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Ice::isFloatingType(OpTy)) 1581d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return true; 158274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf reportInvalidBinaryOp(Op, OpTy); 1583d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1584d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1585d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 158657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if the type of operand Op is the valid pointer type, for the given 158757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // InstructionName. Returns true if valid. Otherwise generates an error 158857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // message and returns false. 158941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf bool isValidPointerType(Ice::Operand *Op, const char *InstructionName) { 15904019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf Ice::Type PtrType = Ice::getPointerType(); 159141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (Op->getType() == PtrType) 159241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return true; 159341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 159441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 159541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstructionName << " address not " << PtrType 159697501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf << ". Found: " << *Op; 159741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 159841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 159941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 160041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 160157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if loading/storing a value of type Ty is allowed. Returns true if 160257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Valid. Otherwise generates an error message and returns false. 160341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf bool isValidLoadStoreType(Ice::Type Ty, const char *InstructionName) { 160441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (isLoadStoreType(Ty)) 160541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return true; 160641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 160741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 160841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstructionName << " type not allowed: " << Ty << "*"; 160941689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 161041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 161141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 161241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 161357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Checks if loading/storing a value of type Ty is allowed for the given 161457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Alignment. Otherwise generates an error message and returns false. 1615f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf bool isValidLoadStoreAlignment(size_t Alignment, Ice::Type Ty, 161641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf const char *InstructionName) { 161741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (!isValidLoadStoreType(Ty, InstructionName)) 161841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 1619f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf if (isAllowedAlignment(Alignment, Ty)) 162041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return true; 162141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf std::string Buffer; 162241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf raw_string_ostream StrBuf(Buffer); 162341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf StrBuf << InstructionName << " " << Ty << "*: not allowed for alignment " 162441689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf << Alignment; 162541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf Error(StrBuf.str()); 162641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return false; 162741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 162841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf 1629f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf // Defines if the given alignment is valid for the given type. Simplified 163057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // version of PNaClABIProps::isAllowedAlignment, based on API's offered for 163157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Ice::Type. 1632f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf bool isAllowedAlignment(size_t Alignment, Ice::Type Ty) const { 1633f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf return Alignment == typeAlignInBytes(Ty) || 1634f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf (Alignment == 1 && !isVectorType(Ty)); 1635f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf } 1636f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf 1637aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // Types of errors that can occur for insertelement and extractelement 1638aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // instructions. 1639aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf enum VectorIndexCheckValue { 1640aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotVector, 1641aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotConstant, 1642aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotInRange, 1643aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexNotI32, 1644aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexValid 1645aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf }; 1646aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 1647aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf void dumpVectorIndexCheckValue(raw_ostream &Stream, 1648aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue Value) const { 164920b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (!Ice::BuildDefs::dump()) 1650b6c96af1e5f019374ab93b2b66fbf79247d24660Karl Schimpf return; 1651aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf switch (Value) { 1652aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotVector: 1653aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index on non vector"; 1654aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1655aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotConstant: 1656aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index not integer constant"; 1657aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1658aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotInRange: 1659aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index not in range of vector"; 1660aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1661aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexNotI32: 1662aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Vector index not of type " << Ice::IceType_i32; 1663aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1664aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf case VectorIndexValid: 1665aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Stream << "Valid vector index"; 1666aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf break; 1667aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 1668aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 1669aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 1670aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // Returns whether the given vector index (for insertelement and 1671aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // extractelement instructions) is valid. 1672aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue validateVectorIndex(const Ice::Operand *Vec, 1673aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf const Ice::Operand *Index) const { 1674aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type VecType = Vec->getType(); 1675aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!Ice::isVectorType(VecType)) 1676aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotVector; 1677aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf const auto *C = dyn_cast<Ice::ConstantInteger32>(Index); 1678aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (C == nullptr) 1679aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotConstant; 1680d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth if (static_cast<size_t>(C->getValue()) >= typeNumElements(VecType)) 1681aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotInRange; 1682aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (Index->getType() != Ice::IceType_i32) 1683aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexNotI32; 1684aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return VectorIndexValid; 1685aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 1686aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 168757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Takes the PNaCl bitcode binary operator Opcode, and the opcode type Ty, 168857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and sets Op to the corresponding ICE binary opcode. Returns true if able 168957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // to convert, false otherwise. 1690d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf bool convertBinopOpcode(unsigned Opcode, Ice::Type Ty, 1691d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::InstArithmetic::OpKind &Op) { 16929bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf switch (Opcode) { 1693d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf default: { 16949bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf std::string Buffer; 16959bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf raw_string_ostream StrBuf(Buffer); 16969bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf StrBuf << "Binary opcode " << Opcode << "not understood for type " << Ty; 16979bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Error(StrBuf.str()); 1698d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Add; 1699d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return false; 1700d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 17019bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_ADD: 17029bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17039bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Add; 17049bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17059bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17069bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fadd; 17079bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17089bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17099bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SUB: 17109bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17119bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Sub; 17129bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17139bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17149bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fsub; 17159bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17169bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17179bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_MUL: 17189bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17199bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Mul; 17209bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17219bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17229bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fmul; 17239bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17249bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17259bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_UDIV: 1726d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Udiv; 1727d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17289bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SDIV: 17299bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17309bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Sdiv; 17319bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17329bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17339bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Fdiv; 17349bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17359bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17369bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_UREM: 1737d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Urem; 1738d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17399bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SREM: 17409bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (Ice::isIntegerType(Ty)) { 17419bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Srem; 17429bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17439bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } else { 17449bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf Op = Ice::InstArithmetic::Frem; 17459bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf return isValidFloatingArithOp(Op, Ty); 17469bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 17479bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_SHL: 1748d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Shl; 1749d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17509bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_LSHR: 1751d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Lshr; 1752d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17539bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_ASHR: 1754d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Ashr; 1755d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerArithOp(Op, Ty); 17569bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_AND: 1757d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::And; 1758d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerLogicalOp(Op, Ty); 17599bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_OR: 1760d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Or; 1761d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerLogicalOp(Op, Ty); 17629bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf case naclbitc::BINOP_XOR: 1763d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Op = Ice::InstArithmetic::Xor; 1764d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return isValidIntegerLogicalOp(Op, Ty); 1765d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1766d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 1767c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf 176857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Simplifies out vector types from Type1 and Type2, if both are vectors of 176957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// the same size. Returns true iff both are vectors of the same size, or are 177057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// both scalar types. 1771bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool simplifyOutCommonVectorType(Ice::Type &Type1, Ice::Type &Type2) { 1772bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsType1Vector = isVectorType(Type1); 1773bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsType2Vector = isVectorType(Type2); 1774bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (IsType1Vector != IsType2Vector) 1775bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1776bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!IsType1Vector) 1777bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return true; 1778bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (typeNumElements(Type1) != typeNumElements(Type2)) 1779bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1780bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Type1 = typeElementType(Type1); 1781bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Type2 = typeElementType(Type2); 1782bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return true; 1783bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1784bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1785bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff an integer truncation from SourceType to TargetType is 1786bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// valid. 1787bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isIntTruncCastValid(Ice::Type SourceType, Ice::Type TargetType) { 1788dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth return Ice::isIntegerType(SourceType) && Ice::isIntegerType(TargetType) && 1789dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth simplifyOutCommonVectorType(SourceType, TargetType) && 1790dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth getScalarIntBitWidth(SourceType) > getScalarIntBitWidth(TargetType); 1791bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1792bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1793bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff a floating type truncation from SourceType to TargetType 1794bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// is valid. 1795bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isFloatTruncCastValid(Ice::Type SourceType, 1796bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType) { 1797dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth return simplifyOutCommonVectorType(SourceType, TargetType) && 1798dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth SourceType == Ice::IceType_f64 && TargetType == Ice::IceType_f32; 1799bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1800bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1801bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff an integer extension from SourceType to TargetType is 1802bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// valid. 1803bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isIntExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { 1804bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return isIntTruncCastValid(TargetType, SourceType); 1805bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1806bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1807bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff a floating type extension from SourceType to TargetType 1808bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// is valid. 1809bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isFloatExtCastValid(Ice::Type SourceType, Ice::Type TargetType) { 1810bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return isFloatTruncCastValid(TargetType, SourceType); 1811bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1812bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 181357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns true iff a cast from floating type SourceType to integer type 181457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// TargetType is valid. 1815bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isFloatToIntCastValid(Ice::Type SourceType, 1816bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType) { 1817bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!(Ice::isFloatingType(SourceType) && Ice::isIntegerType(TargetType))) 1818bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1819bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsSourceVector = isVectorType(SourceType); 1820bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool IsTargetVector = isVectorType(TargetType); 1821bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (IsSourceVector != IsTargetVector) 1822bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1823bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (IsSourceVector) { 1824bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return typeNumElements(SourceType) == typeNumElements(TargetType); 1825bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1826bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return true; 1827bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1828bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 182957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns true iff a cast from integer type SourceType to floating type 183057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// TargetType is valid. 1831bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isIntToFloatCastValid(Ice::Type SourceType, 1832bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType) { 1833bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return isFloatToIntCastValid(TargetType, SourceType); 1834bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1835bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 183657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns the number of bits used to model type Ty when defining the bitcast 183757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// instruction. 1838bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static Ice::SizeT bitcastSizeInBits(Ice::Type Ty) { 1839bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (Ice::isVectorType(Ty)) 1840bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return Ice::typeNumElements(Ty) * 1841bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bitcastSizeInBits(Ice::typeElementType(Ty)); 1842bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (Ty == Ice::IceType_i1) 1843bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return 1; 1844bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return Ice::typeWidthInBytes(Ty) * CHAR_BIT; 1845bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1846bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 1847bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf /// Returns true iff a bitcast from SourceType to TargetType is allowed. 1848bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf static bool isBitcastValid(Ice::Type SourceType, Ice::Type TargetType) { 1849bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return bitcastSizeInBits(SourceType) == bitcastSizeInBits(TargetType); 1850bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1851bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf 185257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// Returns true iff the NaCl bitcode Opcode is a valid cast opcode for 185357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// converting SourceType to TargetType. Updates CastKind to the corresponding 185457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// instruction cast opcode. Also generates an error message when this 185557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull /// function returns false. 1856bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool convertCastOpToIceOp(uint64_t Opcode, Ice::Type SourceType, 1857bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::Type TargetType, 1858bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Ice::InstCast::OpKind &CastKind) { 1859bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf bool Result; 1860bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf switch (Opcode) { 1861bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf default: { 1862bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf std::string Buffer; 1863bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf raw_string_ostream StrBuf(Buffer); 1864bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf StrBuf << "Cast opcode " << Opcode << " not understood.\n"; 1865bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Error(StrBuf.str()); 1866bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Bitcast; 1867bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return false; 1868bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1869bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_TRUNC: 1870bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Trunc; 1871bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntTruncCastValid(SourceType, TargetType); 1872bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf break; 1873bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_ZEXT: 1874c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Zext; 1875bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntExtCastValid(SourceType, TargetType); 1876c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1877bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_SEXT: 1878c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Sext; 1879bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntExtCastValid(SourceType, TargetType); 1880c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1881bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPTOUI: 1882bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Fptoui; 1883bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatToIntCastValid(SourceType, TargetType); 1884c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1885bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPTOSI: 1886c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Fptosi; 1887bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatToIntCastValid(SourceType, TargetType); 1888c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1889bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_UITOFP: 1890bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Uitofp; 1891bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntToFloatCastValid(SourceType, TargetType); 1892c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1893bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_SITOFP: 1894c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Sitofp; 1895bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isIntToFloatCastValid(SourceType, TargetType); 1896c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1897bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPTRUNC: 1898bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Fptrunc; 1899bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatTruncCastValid(SourceType, TargetType); 1900bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf break; 1901bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_FPEXT: 1902bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf CastKind = Ice::InstCast::Fpext; 1903bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isFloatExtCastValid(SourceType, TargetType); 1904c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1905bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf case naclbitc::CAST_BITCAST: 1906c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf CastKind = Ice::InstCast::Bitcast; 1907bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Result = isBitcastValid(SourceType, TargetType); 1908c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf break; 1909c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 1910bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!Result) { 1911bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf std::string Buffer; 1912bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf raw_string_ostream StrBuf(Buffer); 1913bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf StrBuf << "Illegal cast: " << Ice::InstCast::getCastName(CastKind) << " " 1914bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf << SourceType << " to " << TargetType; 1915bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf Error(StrBuf.str()); 1916bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf } 1917bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf return Result; 1918c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 191983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf 192057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Converts PNaCl bitcode Icmp operator to corresponding ICE op. Returns true 192157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // if able to convert, false otherwise. 192283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf bool convertNaClBitcICmpOpToIce(uint64_t Op, 192383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstIcmp::ICond &Cond) const { 192483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf switch (Op) { 192583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_EQ: 192683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Eq; 192783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 192883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_NE: 192983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ne; 193083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 193183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_UGT: 193283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ugt; 193383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 193483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_UGE: 193583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Uge; 193683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 193783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_ULT: 193883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ult; 193983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 194083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_ULE: 194183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Ule; 194283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 194383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SGT: 194483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Sgt; 194583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 194683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SGE: 194783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Sge; 194883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 194983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SLT: 195083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Slt; 195183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 195283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::ICMP_SLE: 195383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstIcmp::Sle; 195483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 195583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf default: 1956dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth // Make sure Cond is always initialized. 1957dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth Cond = static_cast<Ice::InstIcmp::ICond>(0); 195883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return false; 195983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 196083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 196183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf 196257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Converts PNaCl bitcode Fcmp operator to corresponding ICE op. Returns true 196357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // if able to convert, false otherwise. 196483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf bool convertNaClBitcFCompOpToIce(uint64_t Op, 196583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstFcmp::FCond &Cond) const { 196683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf switch (Op) { 196783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_FALSE: 196883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::False; 196983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 197083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OEQ: 197183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Oeq; 197283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 197383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OGT: 197483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ogt; 197583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 197683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OGE: 197783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Oge; 197883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 197983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OLT: 198083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Olt; 198183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 198283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_OLE: 198383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ole; 198483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 198583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ONE: 198683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::One; 198783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 198883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ORD: 198983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ord; 199083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 199183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UNO: 199283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Uno; 199383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 199483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UEQ: 199583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ueq; 199683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 199783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UGT: 199883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ugt; 199983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UGE: 200183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Uge; 200283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ULT: 200483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ult; 200583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_ULE: 200783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Ule; 200883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 200983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_UNE: 201083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::Une; 201183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 201283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FCMP_TRUE: 201383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Cond = Ice::InstFcmp::True; 201483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return true; 201583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf default: 2016dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth // Make sure Cond is always initialized. 2017dddaf9cae5107a60becbe69628d774815e9305e7Jim Stichnoth Cond = static_cast<Ice::InstFcmp::FCond>(0); 201883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return false; 201983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 202083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 2021aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf 202257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Creates an error instruction, generating a value of type Ty, and adds a 202357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // placeholder so that instruction indices line up. Some instructions, such 202457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // as a call, will not generate a value if the return type is void. In such 202557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // cases, a placeholder value for the badly formed instruction is not needed. 202657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Hence, if Ty is void, an error instruction is not appended. 2027aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf void appendErrorInstruction(Ice::Type Ty) { 202857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: we don't worry about downstream translation errors because the 202957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // function will not be translated if any errors occur. 2030aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (Ty == Ice::IceType_void) 2031aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2032aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Variable *Var = getNextInstVar(Ty); 20338e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstAssign::create(Func.get(), Var, Var)); 2034aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 20359d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf 20369d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf Ice::Operand *reportGetOperandUndefined(NaClBcIndexSize_t Index) { 20379d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf std::string Buffer; 20389d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf raw_string_ostream StrBuf(Buffer); 20399d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf StrBuf << "Value index " << Index << " not defined!"; 204043632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf Error(StrBuf.str()); 204143632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf // Recover and return some value. 204243632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf if (!LocalOperands.empty()) 204343632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf return LocalOperands.front(); 204443632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf return Context->getGlobalConstantByID(0); 20459d25e620644e1800e381c5c4310a4c79a73a7650Karl Schimpf } 2046d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf}; 2047d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2048d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfvoid FunctionParser::ExitBlock() { 20496c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf // Check if the last instruction in the function was terminating. 20506c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf if (!InstIsTerminating) { 20516c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf Error("Last instruction in function not terminator"); 20526c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf if (isIRGenerationDisabled()) 20536c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf return; 20546c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf // Recover by inserting an unreachable instruction. 20556c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 20566fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 205798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf ++CurrentBbIndex; 205898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (CurrentBbIndex != DeclaredNumberBbs) { 205998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf std::string Buffer; 206098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf raw_string_ostream StrBuf(Buffer); 206198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf StrBuf << "Function declared " << DeclaredNumberBbs 206298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << " basic blocks, but defined " << CurrentBbIndex << "."; 206398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error(StrBuf.str()); 206498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 20656c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf if (isIRGenerationDisabled()) 20666c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf return; 206757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Before translating, check for blocks without instructions, and insert 206857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // unreachable. This shouldn't happen, but be safe. 206974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf size_t Index = 0; 2070f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth for (Ice::CfgNode *Node : Func->getNodes()) { 2071bfb410dd04d46ca34b2ea437151af2dc26930b5bJim Stichnoth if (Node->getInsts().empty()) { 2072d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 2073d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 2074d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Basic block " << Index << " contains no instructions"; 2075d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 20768e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Node->appendInst(Ice::InstUnreachable::create(Func.get())); 2077d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2078f44f371b7f3fab5683e6781873d71987e44fea2fJim Stichnoth ++Index; 2079d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 208069d3f9c6698150a88fcc89a20bb93823895dfaf8Jim Stichnoth Func->computeInOutEdges(); 2081d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 2082d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 208374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid FunctionParser::reportInvalidBinaryOp(Ice::InstArithmetic::OpKind Op, 2084d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type OpTy) { 2085d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 2086d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 2087d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Invalid operator type for " << Ice::InstArithmetic::getOpName(Op) 2088d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf << ". Found " << OpTy; 2089d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 2090d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 2091d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2092d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpfvoid FunctionParser::ProcessRecord() { 209357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: To better separate parse/IR generation times, when IR generation is 209457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // disabled we do the following: 20956fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // 1) Delay exiting until after we extract operands. 20966fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // 2) return before we access operands, since all operands will be a nullptr. 2097d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 2098d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (InstIsTerminating) { 2099d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf InstIsTerminating = false; 210098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf ++CurrentBbIndex; 21016fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (!isIRGenerationDisabled()) 210298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf CurrentNode = getBasicBlock(CurrentBbIndex); 2103d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 210447661568f8c3811634913cfb43144a95d8340758Karl Schimpf // The base index for relative indexing. 210574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NaClBcIndexSize_t BaseIndex = getNextInstIndex(); 2106d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf switch (Record.GetCode()) { 2107d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::FUNC_CODE_DECLAREBLOCKS: { 2108d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // DECLAREBLOCKS: [n] 21092f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "count")) 2110c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 211198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (DeclaredNumberBbs > 0) { 211298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error("Duplicate function block count record"); 211398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return; 211498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 211598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 211698ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Check for bad large sizes, since they can make ridiculous memory 21177a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf // requests and hang the user for large amounts of time. 21187a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf uint64_t NumBbs = Values[0]; 21197a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf if (NumBbs > MaxRecordsInBlock) { 212074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 212174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 212298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf StrBuf << "Function defines " << NumBbs 212398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << " basic blocks, which is too big for a function containing " 212498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf << NumBytesDefiningFunction << " bytes"; 212574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 21267a99327dae74a3abd7f222de1b218d20da665e1cKarl Schimpf NumBbs = MaxRecordsInBlock; 2127d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 212898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 212998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (NumBbs == 0) { 213098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf Error("Functions must contain at least one basic block."); 213198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf NumBbs = 1; 213298ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 213398ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf 213498ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf DeclaredNumberBbs = NumBbs; 21356fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 21366fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 213798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // Install the basic blocks, skipping bb0 which was created in the 213898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf // constructor. 213998ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf for (size_t i = 1; i < NumBbs; ++i) 214098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf installNextBasicBlock(); 2141aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2142d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2143d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::FUNC_CODE_INST_BINOP: { 2144d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // BINOP: [opval, opval, opcode] 21452f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "binop")) 2146c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 214747661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); 214847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); 21496fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 21506fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Op1 == nullptr && Op2 == nullptr); 21516fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 21526fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 21536fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2154d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type Type1 = Op1->getType(); 2155d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::Type Type2 = Op2->getType(); 2156d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf if (Type1 != Type2) { 2157d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf std::string Buffer; 2158d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf raw_string_ostream StrBuf(Buffer); 2159d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf StrBuf << "Binop argument types differ: " << Type1 << " and " << Type2; 2160d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Error(StrBuf.str()); 2161aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Type1); 2162aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2163d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2164d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2165d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf Ice::InstArithmetic::OpKind Opcode; 21669bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf if (!convertBinopOpcode(Values[2], Type1, Opcode)) { 21679bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf appendErrorInstruction(Type1); 2168c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 21699bb188d8afbc0b7d3cde3334cca56b8a09301443Karl Schimpf } 217047661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstArithmetic::create( 21718e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), Opcode, getNextInstVar(Type1), Op1, Op2)); 2172aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2173d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2174c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf case naclbitc::FUNC_CODE_INST_CAST: { 2175c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf // CAST: [opval, destty, castopc] 21762f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "cast")) 2177c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 217847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Src = getRelativeOperand(Values[0], BaseIndex); 2179645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type CastType = Context->getSimpleTypeByID(Values[1]); 2180c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf Ice::InstCast::OpKind CastKind; 21816fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 21826fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Src == nullptr); 21836fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 21846fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 21856fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2186bf170370805150026104a9e42e07fb17b0971ad7Karl Schimpf if (!convertCastOpToIceOp(Values[2], Src->getType(), CastType, CastKind)) { 2187aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(CastType); 2188c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 2189c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 21908e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstCast::create( 21918e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), CastKind, getNextInstVar(CastType), Src)); 2192aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2193c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf } 21941d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf case naclbitc::FUNC_CODE_INST_VSELECT: { 21951d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf // VSELECT: [opval, opval, pred] 21962f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "select")) 21976fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 219847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *ThenVal = getRelativeOperand(Values[0], BaseIndex); 219947661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *ElseVal = getRelativeOperand(Values[1], BaseIndex); 22006fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Operand *CondVal = getRelativeOperand(Values[2], BaseIndex); 22016fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 22026fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(ThenVal == nullptr && ElseVal == nullptr && CondVal == nullptr); 22036fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 22046fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 22056fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 22066fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type ThenType = ThenVal->getType(); 22071d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Ice::Type ElseType = ElseVal->getType(); 22081d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf if (ThenType != ElseType) { 22091d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf std::string Buffer; 22101d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf raw_string_ostream StrBuf(Buffer); 22111d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf StrBuf << "Select operands not same type. Found " << ThenType << " and " 22121d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf << ElseType; 22131d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Error(StrBuf.str()); 2214aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(ThenType); 22151d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf return; 22161d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 22171d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Ice::Type CondType = CondVal->getType(); 22181d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf if (isVectorType(CondType)) { 22191d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf if (!isVectorType(ThenType) || 22201d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf typeElementType(CondType) != Ice::IceType_i1 || 22211d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf typeNumElements(ThenType) != typeNumElements(CondType)) { 22221d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf std::string Buffer; 22231d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf raw_string_ostream StrBuf(Buffer); 222497501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf StrBuf << "Select condition type " << CondType 22251d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf << " not allowed for values of type " << ThenType; 22261d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Error(StrBuf.str()); 2227aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(ThenType); 22281d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf return; 22291d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 22301d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } else if (CondVal->getType() != Ice::IceType_i1) { 22311d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf std::string Buffer; 22321d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2233dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth StrBuf << "Select condition " << CondVal 2234dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth << " not type i1. Found: " << CondVal->getType(); 22351d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf Error(StrBuf.str()); 2236aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(ThenType); 22371d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf return; 22381d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 223947661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstSelect::create( 22408e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(ThenType), CondVal, ThenVal, ElseVal)); 2241aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 22421d6f0e45068045fc30912e6f0907099b53d1064eKarl Schimpf } 224371ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf case naclbitc::FUNC_CODE_INST_EXTRACTELT: { 224471ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf // EXTRACTELT: [opval, opval] 22452f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "extract element")) 224683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 224747661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); 224847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Index = getRelativeOperand(Values[1], BaseIndex); 22496fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 22506fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Vec == nullptr && Index == nullptr); 22516fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 22526fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 22536fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 22546fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type VecType = Vec->getType(); 2255aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); 2256aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (IndexCheckValue != VectorIndexValid) { 225771ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf std::string Buffer; 225871ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2259aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); 2260aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf StrBuf << ": extractelement " << VecType << " " << *Vec << ", " 2261aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << Index->getType() << " " << *Index; 226271ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf Error(StrBuf.str()); 2263aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(VecType); 2264aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 226571ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 226647661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstExtractElement::create( 22678e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(typeElementType(VecType)), Vec, Index)); 2268aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 226971ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 227071ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf case naclbitc::FUNC_CODE_INST_INSERTELT: { 227171ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf // INSERTELT: [opval, opval, opval] 22722f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "insert element")) 227383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 227447661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Vec = getRelativeOperand(Values[0], BaseIndex); 227547661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Elt = getRelativeOperand(Values[1], BaseIndex); 227647661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Index = getRelativeOperand(Values[2], BaseIndex); 22776fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 22786fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Vec == nullptr && Elt == nullptr && Index == nullptr); 22796fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 22806fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 22816fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 22826fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type VecType = Vec->getType(); 2283aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf VectorIndexCheckValue IndexCheckValue = validateVectorIndex(Vec, Index); 2284aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (IndexCheckValue != VectorIndexValid) { 228571ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf std::string Buffer; 228671ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2287aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf dumpVectorIndexCheckValue(StrBuf, IndexCheckValue); 2288aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf StrBuf << ": insertelement " << VecType << " " << *Vec << ", " 2289aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << Elt->getType() << " " << *Elt << ", " << Index->getType() << " " 2290aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << *Index; 229171ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf Error(StrBuf.str()); 2292aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Elt->getType()); 2293aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 229471ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 229543632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf if (Ice::typeElementType(VecType) != Elt->getType()) { 229643632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf std::string Buffer; 229743632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf raw_string_ostream StrBuf(Buffer); 229843632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf StrBuf << "Insertelement: Element type " 229943632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf << Ice::typeString(Elt->getType()) << " doesn't match vector type " 230043632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf << Ice::typeString(VecType); 230143632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf Error(StrBuf.str()); 230243632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf appendErrorInstruction(Elt->getType()); 230343632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf return; 230443632b954abab0a7dcca3441a5e9239be98f6328Karl Schimpf } 230547661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Ice::InstInsertElement::create( 23068e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(VecType), Vec, Elt, Index)); 2307aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 230871ba82224c7aaba79ac43c1afaa6dcde8f4fb88eKarl Schimpf } 230983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf case naclbitc::FUNC_CODE_INST_CMP2: { 231083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf // CMP2: [opval, opval, pred] 23112f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "compare")) 231283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 231347661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op1 = getRelativeOperand(Values[0], BaseIndex); 231447661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op2 = getRelativeOperand(Values[1], BaseIndex); 23156fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 23166fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Op1 == nullptr && Op2 == nullptr); 23176fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 23186fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 23196fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 232083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::Type Op1Type = Op1->getType(); 232183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::Type Op2Type = Op2->getType(); 2322aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type DestType = getCompareResultType(Op1Type); 232383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (Op1Type != Op2Type) { 232483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 232583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 2326dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth StrBuf << "Compare argument types differ: " << Op1Type << " and " 2327dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth << Op2Type; 232883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2329aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 233083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Op2 = Op1; 233183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 233283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (DestType == Ice::IceType_void) { 233383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 233483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 233583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare not defined for type " << Op1Type; 233683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 233783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 233883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 233947661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Variable *Dest = getNextInstVar(DestType); 234083f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (isIntegerType(Op1Type)) { 234183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstIcmp::ICond Cond; 234283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) { 234383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 234483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 234583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare record contains unknown integer predicate index: " 234683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf << Values[2]; 234783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2348aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 234983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 235047661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 23518e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstIcmp::create(Func.get(), Cond, Dest, Op1, Op2)); 2352dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth } else if (isFloatingType(Op1Type)) { 235383f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Ice::InstFcmp::FCond Cond; 235483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) { 235583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 235683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 235783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare record contains unknown float predicate index: " 235883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf << Values[2]; 235983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2360aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 236183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 236247661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 23638e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstFcmp::create(Func.get(), Cond, Dest, Op1, Op2)); 236483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } else { 236583f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf // Not sure this can happen, but be safe. 236683f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf std::string Buffer; 236783f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf raw_string_ostream StrBuf(Buffer); 236883f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf StrBuf << "Compare on type not understood: " << Op1Type; 236983f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf Error(StrBuf.str()); 2370aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(DestType); 237183f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf return; 237283f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 2373aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 237483f9f0c1b516f563efb91f0b69cfa4c075631403Karl Schimpf } 2375d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf case naclbitc::FUNC_CODE_INST_RET: { 2376d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // RET: [opval?] 23776c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 23782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeInRange(0, 1, "return")) 2379c0fdc27ca71ab7123af908c688aa041ba2f18461Karl Schimpf return; 2380bfb410dd04d46ca34b2ea437151af2dc26930b5bJim Stichnoth if (Values.empty()) { 23816fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 23826fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 23838e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstRet::create(Func.get())); 2384d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } else { 23856fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Operand *RetVal = getRelativeOperand(Values[0], BaseIndex); 23866fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 23876fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(RetVal == nullptr); 23886fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 23896fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 23908e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstRet::create(Func.get(), RetVal)); 2391d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2392aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2393c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 2394c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf case naclbitc::FUNC_CODE_INST_BR: { 23956c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 2396c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf if (Values.size() == 1) { 2397c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf // BR: [bb#] 23986fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 23996fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 2400c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Ice::CfgNode *Block = getBranchBasicBlock(Values[0]); 2401e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (Block == nullptr) 2402c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 24038e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstBr::create(Func.get(), Block)); 2404c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } else { 2405c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf // BR: [bb#, bb#, opval] 24062f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "branch")) 2407c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 240847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Cond = getRelativeOperand(Values[2], BaseIndex); 24096fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 24106fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Cond == nullptr); 24116fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 24126fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2413c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf if (Cond->getType() != Ice::IceType_i1) { 2414c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf std::string Buffer; 2415c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf raw_string_ostream StrBuf(Buffer); 2416dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth StrBuf << "Branch condition " << *Cond 2417dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth << " not i1. Found: " << Cond->getType(); 2418c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Error(StrBuf.str()); 2419c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 2420c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 2421c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Ice::CfgNode *ThenBlock = getBranchBasicBlock(Values[0]); 2422c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf Ice::CfgNode *ElseBlock = getBranchBasicBlock(Values[1]); 2423e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf if (ThenBlock == nullptr || ElseBlock == nullptr) 2424c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf return; 242547661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 24268e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstBr::create(Func.get(), Cond, ThenBlock, ElseBlock)); 2427c836acb8d43c41d3d1d840d35446ec61ef7bf981Karl Schimpf } 2428aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2429d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2430d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf case naclbitc::FUNC_CODE_INST_SWITCH: { 2431d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // SWITCH: [Condty, Cond, BbIndex, NumCases Case ...] 2432d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // where Case = [1, 1, Value, BbIndex]. 2433d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // 243457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: Unlike most instructions, we don't infer the type of Cond, but 243557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // provide it as a separate field. There are also unnecessary data fields 243657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // (i.e. constants 1). These were not cleaned up in PNaCl bitcode because 243757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the bitcode format was already frozen when the problem was noticed. 24386c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 24392f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(4, "switch")) 2440d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 24416fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 2442645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf Ice::Type CondTy = Context->getSimpleTypeByID(Values[0]); 2443d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf if (!Ice::isScalarIntegerType(CondTy)) { 2444d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf std::string Buffer; 2445d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf raw_string_ostream StrBuf(Buffer); 2446d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Case condition must be non-wide integer. Found: " << CondTy; 2447d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Error(StrBuf.str()); 2448d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 2449d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 2450d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Ice::SizeT BitWidth = Ice::getScalarIntBitWidth(CondTy); 2451d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Ice::Operand *Cond = getRelativeOperand(Values[1], BaseIndex); 24526fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf 24536fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf const bool isIRGenDisabled = isIRGenerationDisabled(); 24546fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenDisabled) { 24556fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Cond == nullptr); 24566fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } else if (CondTy != Cond->getType()) { 2457d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf std::string Buffer; 2458d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf raw_string_ostream StrBuf(Buffer); 2459d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Case condition expects type " << CondTy 2460d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf << ". Found: " << Cond->getType(); 2461d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Error(StrBuf.str()); 2462d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 2463d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 24646fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::CfgNode *DefaultLabel = 24656fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf isIRGenDisabled ? nullptr : getBranchBasicBlock(Values[2]); 24660042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf if (DefaultLabel == nullptr) 24670042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf return; 246874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t NumCasesRaw = Values[3]; 246974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf if (NumCasesRaw > std::numeric_limits<uint32_t>::max()) { 247074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf std::string Buffer; 247174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf raw_string_ostream StrBuf(Buffer); 247274cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StrBuf << "Too many cases specified in switch: " << NumCasesRaw; 247374cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf Error(StrBuf.str()); 247474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf NumCasesRaw = std::numeric_limits<uint32_t>::max(); 247574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf } 247674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint32_t NumCases = NumCasesRaw; 2477d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf 2478d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf // Now recognize each of the cases. 24792f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(4 + NumCases * 4, "switch")) 2480d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 24810042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf std::unique_ptr<Ice::InstSwitch> Switch( 24820042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf isIRGenDisabled ? nullptr 24830042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf : Ice::InstSwitch::create(Func.get(), NumCases, Cond, 24840042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf DefaultLabel)); 2485dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth unsigned ValCaseIndex = 4; // index to beginning of case entry. 248674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf for (uint32_t CaseIndex = 0; CaseIndex < NumCases; 2487d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf ++CaseIndex, ValCaseIndex += 4) { 2488dd842dbb57b825ed0dd6400648d0602b74c90affJim Stichnoth if (Values[ValCaseIndex] != 1 || Values[ValCaseIndex + 1] != 1) { 2489d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf std::string Buffer; 2490d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf raw_string_ostream StrBuf(Buffer); 2491d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf StrBuf << "Sequence [1, 1, value, label] expected for case entry " 2492d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf << "in switch record. (at index" << ValCaseIndex << ")"; 2493d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Error(StrBuf.str()); 2494d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf return; 2495d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 24963281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf Ice::APInt Value(BitWidth, 24973281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf NaClDecodeSignRotatedValue(Values[ValCaseIndex + 2])); 24986fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenDisabled) 24996fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf continue; 2500d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Ice::CfgNode *Label = getBranchBasicBlock(Values[ValCaseIndex + 3]); 25010042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf if (Label == nullptr) 25020042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf return; 2503d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf Switch->addBranch(CaseIndex, Value.getSExtValue(), Label); 2504d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 25056fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenDisabled) 25066fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 25070042fea38a41488f6da0e49fbe810fcb3bb88622Karl Schimpf CurrentNode->appendInst(Switch.release()); 2508aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2509d1a971a156cbd06b552b5d875883e1a89bd6e535Karl Schimpf } 251097501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf case naclbitc::FUNC_CODE_INST_UNREACHABLE: { 251197501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf // UNREACHABLE: [] 25126c17dd8cb9b7b62b872ce4fd49d61b5f646f4899Karl Schimpf InstIsTerminating = true; 25132f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "unreachable")) 251497501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf return; 25156fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 25166fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 25178e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstUnreachable::create(Func.get())); 2518aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 251997501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf } 252047661568f8c3811634913cfb43144a95d8340758Karl Schimpf case naclbitc::FUNC_CODE_INST_PHI: { 252147661568f8c3811634913cfb43144a95d8340758Karl Schimpf // PHI: [ty, val1, bb1, ..., valN, bbN] for n >= 2. 25222f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(3, "phi")) 252347661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 2524aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type Ty = Context->getSimpleTypeByID(Values[0]); 252547661568f8c3811634913cfb43144a95d8340758Karl Schimpf if ((Values.size() & 0x1) == 0) { 252647661568f8c3811634913cfb43144a95d8340758Karl Schimpf // Not an odd number of values. 252747661568f8c3811634913cfb43144a95d8340758Karl Schimpf std::string Buffer; 252847661568f8c3811634913cfb43144a95d8340758Karl Schimpf raw_string_ostream StrBuf(Buffer); 252947661568f8c3811634913cfb43144a95d8340758Karl Schimpf StrBuf << "function block phi record size not valid: " << Values.size(); 253047661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error(StrBuf.str()); 2531aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 253247661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 253347661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 253447661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (Ty == Ice::IceType_void) { 253547661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error("Phi record using type void not allowed"); 253647661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 253747661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 25386fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 25396fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // Verify arguments are defined before quitting. 25406fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf for (unsigned i = 1; i < Values.size(); i += 2) { 25416fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), 25426fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf BaseIndex) == nullptr); 25436fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 25446fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 25456fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 25466fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 254747661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Variable *Dest = getNextInstVar(Ty); 25488e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstPhi *Phi = 25498e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstPhi::create(Func.get(), Values.size() >> 1, Dest); 255074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf for (size_t i = 1; i < Values.size(); i += 2) { 255147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Op = 255247661568f8c3811634913cfb43144a95d8340758Karl Schimpf getRelativeOperand(NaClDecodeSignRotatedValue(Values[i]), BaseIndex); 255347661568f8c3811634913cfb43144a95d8340758Karl Schimpf if (Op->getType() != Ty) { 255447661568f8c3811634913cfb43144a95d8340758Karl Schimpf std::string Buffer; 255547661568f8c3811634913cfb43144a95d8340758Karl Schimpf raw_string_ostream StrBuf(Buffer); 255697501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf StrBuf << "Value " << *Op << " not type " << Ty 255797501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf << " in phi instruction. Found: " << Op->getType(); 255847661568f8c3811634913cfb43144a95d8340758Karl Schimpf Error(StrBuf.str()); 2559aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 256047661568f8c3811634913cfb43144a95d8340758Karl Schimpf return; 256147661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 256247661568f8c3811634913cfb43144a95d8340758Karl Schimpf Phi->addArgument(Op, getBasicBlock(Values[i + 1])); 256347661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 256447661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst(Phi); 2565aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 256647661568f8c3811634913cfb43144a95d8340758Karl Schimpf } 2567742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf case naclbitc::FUNC_CODE_INST_ALLOCA: { 2568742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf // ALLOCA: [Size, align] 25692f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "alloca")) 2570742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf return; 257147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *ByteCount = getRelativeOperand(Values[0], BaseIndex); 2572f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf uint32_t Alignment; 25736fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf extractAlignment("Alloca", Values[1], Alignment); 25746fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 25756fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(ByteCount == nullptr); 25766fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 25776fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 25786fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 25794019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf Ice::Type PtrTy = Ice::getPointerType(); 2580742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf if (ByteCount->getType() != Ice::IceType_i32) { 2581742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf std::string Buffer; 2582742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf raw_string_ostream StrBuf(Buffer); 258397501839d2dd8210723d132e6555a69d0c297dc7Karl Schimpf StrBuf << "Alloca on non-i32 value. Found: " << *ByteCount; 2584742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf Error(StrBuf.str()); 2585aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(PtrTy); 2586742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf return; 2587742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf } 25888e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstAlloca::create( 25898e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), ByteCount, Alignment, getNextInstVar(PtrTy))); 2590aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2591742d72d800d1fd2450ba7d19b432bb19410e77fdKarl Schimpf } 259241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf case naclbitc::FUNC_CODE_INST_LOAD: { 259341689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf // LOAD: [address, align, ty] 25942f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "load")) 259541689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 259647661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); 2597aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Ice::Type Ty = Context->getSimpleTypeByID(Values[2]); 2598f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf uint32_t Alignment; 25996fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf extractAlignment("Load", Values[1], Alignment); 26006fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 26016fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Address == nullptr); 26026fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 26036fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 26046fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2605aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!isValidPointerType(Address, "Load")) { 2606aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 260741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 2608aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 2609aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!isValidLoadStoreAlignment(Alignment, Ty, "Load")) { 2610aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf appendErrorInstruction(Ty); 261141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 2612aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 26138e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth CurrentNode->appendInst(Ice::InstLoad::create( 26148e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Func.get(), getNextInstVar(Ty), Address, Alignment)); 2615aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 261641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 261741689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf case naclbitc::FUNC_CODE_INST_STORE: { 261841689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf // STORE: [address, value, align] 26192f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(3, "store")) 262041689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 262147661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Address = getRelativeOperand(Values[0], BaseIndex); 262247661568f8c3811634913cfb43144a95d8340758Karl Schimpf Ice::Operand *Value = getRelativeOperand(Values[1], BaseIndex); 2623f875d45fb80c259054f1377ecc8537ddda9204c9Karl Schimpf uint32_t Alignment; 262464dcde7e0a79c375df09362c2d7725dbac9ecb14Karl Schimpf extractAlignment("Store", Values[2], Alignment); 26256fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 26266fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Address == nullptr && Value == nullptr); 26276fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 26286fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 26296fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (!isValidPointerType(Address, "Store")) 26306fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 263141689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf if (!isValidLoadStoreAlignment(Alignment, Value->getType(), "Store")) 263241689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf return; 263347661568f8c3811634913cfb43144a95d8340758Karl Schimpf CurrentNode->appendInst( 26348e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth Ice::InstStore::create(Func.get(), Value, Address, Alignment)); 2635aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 263641689df2f71c6bcf964248f58824bd6061e7f6c3Karl Schimpf } 26378df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case naclbitc::FUNC_CODE_INST_CALL: 26388df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case naclbitc::FUNC_CODE_INST_CALL_INDIRECT: { 26398df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // CALL: [cc, fnid, arg0, arg1...] 26408df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // CALL_INDIRECT: [cc, fn, returnty, args...] 26418df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // 264257e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Note: The difference between CALL and CALL_INDIRECT is that CALL has a 264357e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // reference to an explicit function declaration, while the CALL_INDIRECT 264457e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // is just an address. For CALL, we can infer the return type by looking up 264557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the type signature associated with the function declaration. For 264657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // CALL_INDIRECT we can only infer the type signature via argument types, 264757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // and the corresponding return type stored in CALL_INDIRECT record. 26488df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::SizeT ParamsStartIndex = 2; 26498df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { 26502f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(2, "call")) 26518df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf return; 26528df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } else { 26532f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSizeAtLeast(3, "call indirect")) 26548df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf return; 26558df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf ParamsStartIndex = 3; 26568df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 26578df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 26588df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // Extract out the called function and its return type. 26598df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf uint32_t CalleeIndex = convertRelativeToAbsIndex(Values[1], BaseIndex); 26608df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::Operand *Callee = getOperand(CalleeIndex); 2661ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf const Ice::FuncSigType *Signature = nullptr; 26628df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::Type ReturnType = Ice::IceType_void; 2663e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf const Ice::Intrinsics::FullIntrinsicInfo *IntrinsicInfo = nullptr; 26648df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (Record.GetCode() == naclbitc::FUNC_CODE_INST_CALL) { 26659d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::FunctionDeclaration *Fcn = Context->getFunctionByID(CalleeIndex); 2666ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Signature = &Fcn->getSignature(); 2667ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf ReturnType = Signature->getReturnType(); 26688df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 26698df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // Check if this direct call is to an Intrinsic (starts with "llvm.") 2670a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth bool BadIntrinsic; 2671c9ec5793338dd62d84246f3143fd7ffc70cbc89bJan Voung const Ice::IceString &Name = Fcn->getName(); 2672a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth IntrinsicInfo = getTranslator().getContext()->getIntrinsicsInfo().find( 2673a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth Name, BadIntrinsic); 2674a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth if (BadIntrinsic) { 2675a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth std::string Buffer; 2676a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth raw_string_ostream StrBuf(Buffer); 2677a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth StrBuf << "Invalid PNaCl intrinsic call to " << Name; 2678a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth Error(StrBuf.str()); 2679ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (ReturnType != Ice::IceType_void) 2680ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf appendErrorInstruction(ReturnType); 2681a67fc448e9779ac8b7d9751bd7cf32f94047a345Jim Stichnoth return; 26828df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 26838df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } else { 2684645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf ReturnType = Context->getSimpleTypeByID(Values[2]); 26858df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 26868df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 2687ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf // Check return type. 2688ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (IntrinsicInfo == nullptr && !isCallReturnType(ReturnType)) { 2689ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2690ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 2691ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf StrBuf << "Return type of called function is invalid: " << ReturnType; 2692ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2693ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf ReturnType = Ice::IceType_i32; 2694ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } 2695ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf 2696aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf // Extract call information. 2697aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf uint64_t CCInfo = Values[0]; 2698aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf CallingConv::ID CallingConv; 2699aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf if (!naclbitc::DecodeCallingConv(CCInfo >> 1, CallingConv)) { 2700aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf std::string Buffer; 2701aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf raw_string_ostream StrBuf(Buffer); 2702aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf StrBuf << "Function call calling convention value " << (CCInfo >> 1) 2703aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf << " not understood."; 2704aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf Error(StrBuf.str()); 2705ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (ReturnType != Ice::IceType_void) 2706ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf appendErrorInstruction(ReturnType); 2707aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2708aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf } 2709aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf bool IsTailCall = static_cast<bool>(CCInfo & 1); 27106fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::SizeT NumParams = Values.size() - ParamsStartIndex; 2711ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (Signature && NumParams != Signature->getNumArgs()) { 2712ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2713ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 2714ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf StrBuf << "Call has " << NumParams 2715ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf << " parameters. Signature expects: " << Signature->getNumArgs(); 2716ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2717ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf // Error recover by only checking parameters in both signature and call. 2718ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf NumParams = std::min(NumParams, Signature->getNumArgs()); 2719ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } 27206fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 27216fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(Callee == nullptr); 27226fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // Check that parameters are defined. 27236fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { 27246fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf assert(getRelativeOperand(Values[ParamsStartIndex + ParamIndex], 27256fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf BaseIndex) == nullptr); 27266fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 27276fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf // Define value slot only if value returned. 27286fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (ReturnType != Ice::IceType_void) 27296fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setNextLocalInstIndex(nullptr); 27306fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 27316fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 27328df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // Create the call instruction. 2733e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf Ice::Variable *Dest = (ReturnType == Ice::IceType_void) 2734e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf ? nullptr 2735e3f64d0967aa918a151a1d7e9971060c85f4aa1dKarl Schimpf : getNextInstVar(ReturnType); 2736ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::unique_ptr<Ice::InstCall> Inst; 27378df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (IntrinsicInfo) { 2738ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Inst.reset(Ice::InstIntrinsicCall::create(Func.get(), NumParams, Dest, 2739ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Callee, IntrinsicInfo->Info)); 27408df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } else { 2741ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Inst.reset(Ice::InstCall::create(Func.get(), NumParams, Dest, Callee, 2742ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf IsTailCall)); 27438df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 27448df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 27458df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // Add parameters. 27468df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf for (Ice::SizeT ParamIndex = 0; ParamIndex < NumParams; ++ParamIndex) { 2747ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Ice::Operand *Op = 2748ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf getRelativeOperand(Values[ParamsStartIndex + ParamIndex], BaseIndex); 2749ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (Op == nullptr) { 2750ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2751ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 2752ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf StrBuf << "Parameter " << ParamIndex << " of call not defined"; 2753ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2754ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (ReturnType != Ice::IceType_void) 2755ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf appendErrorInstruction(ReturnType); 2756ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf return; 2757ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } 2758ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf 2759ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf // Check that parameter type is valid. 2760ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (Signature) { 2761ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf if (Op->getType() != Signature->getArgType(ParamIndex)) { 2762ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2763ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 2764ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf StrBuf << "Call argument " << *Op << " expects " 2765ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf << Signature->getArgType(ParamIndex) 2766ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf << ". Found: " << Op->getType(); 2767ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2768ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } else if (IntrinsicInfo == nullptr && 2769ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf !isCallParameterType(Op->getType())) { 2770ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf // TODO(kschimpf): Move this check to the function declaration, so 2771ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf // that it only needs to be checked once. 2772ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2773ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 2774ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf StrBuf << "Call argument " << *Op 2775ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf << " matches declaration but has invalid type: " 2776ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf << Op->getType(); 2777ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2778ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } 2779ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } else if (!isCallParameterType(Op->getType())) { 2780ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf std::string Buffer; 2781ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf raw_string_ostream StrBuf(Buffer); 2782ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf StrBuf << "Call argument " << *Op 2783ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf << " has invalid type: " << Op->getType(); 2784ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Error(StrBuf.str()); 2785ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf } 2786ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf Inst->addArg(Op); 27878df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 27888df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 27898df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf // If intrinsic call, validate call signature. 27908df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf if (IntrinsicInfo) { 27918df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Ice::SizeT ArgIndex = 0; 2792ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf switch (IntrinsicInfo->validateCall(Inst.get(), ArgIndex)) { 27938df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case Ice::Intrinsics::IsValidCall: 27948df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf break; 27958df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case Ice::Intrinsics::BadReturnType: { 27968df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf std::string Buffer; 27978df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf raw_string_ostream StrBuf(Buffer); 27988df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf StrBuf << "Intrinsic call expects return type " 27998df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf << IntrinsicInfo->getReturnType() 28008df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf << ". Found: " << Inst->getReturnType(); 28018df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Error(StrBuf.str()); 28028df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf break; 28038df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 28048df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case Ice::Intrinsics::WrongNumOfArgs: { 28058df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf std::string Buffer; 28068df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf raw_string_ostream StrBuf(Buffer); 28078df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf StrBuf << "Intrinsic call expects " << IntrinsicInfo->getNumArgs() 28088df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf << ". Found: " << Inst->getNumArgs(); 28098df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Error(StrBuf.str()); 28108df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf break; 28118df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 28128df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf case Ice::Intrinsics::WrongCallArgType: { 28138df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf std::string Buffer; 28148df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf raw_string_ostream StrBuf(Buffer); 28158df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf StrBuf << "Intrinsic call argument " << ArgIndex << " expects type " 28168df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf << IntrinsicInfo->getArgType(ArgIndex) 28178df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf << ". Found: " << Inst->getArg(ArgIndex)->getType(); 28188df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf Error(StrBuf.str()); 28198df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf break; 28208df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 28218df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 28228df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 28238df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf 2824ff94f59aec64a95c7c1e42d09e2cb7a4cbe63b9aKarl Schimpf CurrentNode->appendInst(Inst.release()); 28258df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf return; 28268df26f3e5fcfe8f5eff00ebd2f308bebcc09153bKarl Schimpf } 28278f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf case naclbitc::FUNC_CODE_INST_FORWARDTYPEREF: { 28288f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf // FORWARDTYPEREF: [opval, ty] 28292f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(2, "forward type ref")) 28308f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf return; 28316fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf Ice::Type OpType = Context->getSimpleTypeByID(Values[1]); 28326fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf setOperand(Values[0], 28336fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf isIRGenerationDisabled() ? nullptr : createInstVar(OpType)); 2834aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 28358f07aa8811a4e78f74bdfef0a5daddc7a775c21fKarl Schimpf } 2836d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf default: 2837d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf // Generate error message! 2838d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf BlockParserBaseClass::ProcessRecord(); 2839aff9fa2c45e39301b6f8ffb27ba8e0d0c588032eKarl Schimpf return; 2840d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf } 2841d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf} 2842d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf 2843f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf/// Parses constants within a function block. 2844f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfclass ConstantsParser : public BlockParserBaseClass { 2845c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ConstantsParser() = delete; 28460795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ConstantsParser(const ConstantsParser &) = delete; 28470795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ConstantsParser &operator=(const ConstantsParser &) = delete; 2848f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2849f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfpublic: 2850f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf ConstantsParser(unsigned BlockID, FunctionParser *FuncParser) 285158455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : BlockParserBaseClass(BlockID, FuncParser), 285258455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseConstants, getTranslator().getContext()), 2853eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth FuncParser(FuncParser) {} 2854f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2855e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ConstantsParser() override = default; 2856f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 28572f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "constants"; } 28582f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 2859f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfprivate: 286058455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 2861f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // The parser of the function block this constants block appears in. 2862f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf FunctionParser *FuncParser; 2863f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // The type to use for succeeding constants. 2864eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Ice::Type NextConstantType = Ice::IceType_void; 2865f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 28668e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 2867f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2868f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Ice::GlobalContext *getContext() { return getTranslator().getContext(); } 2869f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 287057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Returns true if the type to use for succeeding constants is defined. If 287157e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // false, also generates an error message. 2872f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf bool isValidNextConstantType() { 2873f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (NextConstantType != Ice::IceType_void) 2874f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return true; 2875f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error("Constant record not preceded by set type record"); 2876f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return false; 2877f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2878f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf}; 2879f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2880f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfvoid ConstantsParser::ProcessRecord() { 2881f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 2882f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf switch (Record.GetCode()) { 2883f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_SETTYPE: { 2884f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // SETTYPE: [typeid] 28852f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "set type")) 2886f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2887645aa1a9a21d41f523575afad356e76062e9d696Karl Schimpf NextConstantType = Context->getSimpleTypeByID(Values[0]); 2888f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (NextConstantType == Ice::IceType_void) 2889f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error("constants block set type not allowed for void type"); 2890f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2891f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2892f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_UNDEF: { 2893f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // UNDEF 28942f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(0, "undef")) 2895f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2896f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (!isValidNextConstantType()) 2897f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 28986fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 28996fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf FuncParser->setNextConstantID(nullptr); 29006fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 29016fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2902f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf FuncParser->setNextConstantID( 2903f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf getContext()->getConstantUndef(NextConstantType)); 2904f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2905f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2906f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_INTEGER: { 2907f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // INTEGER: [intval] 29082f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "integer")) 2909f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2910f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (!isValidNextConstantType()) 2911f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 29126fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 29136fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf FuncParser->setNextConstantID(nullptr); 29146fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 29156fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 29164019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf if (Ice::isScalarIntegerType(NextConstantType)) { 29174019f0843ff2efdde366402f692f0853a206bac8Karl Schimpf Ice::APInt Value(Ice::getScalarIntBitWidth(NextConstantType), 29183281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf NaClDecodeSignRotatedValue(Values[0])); 2919d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth if (Ice::Constant *C = getContext()->getConstantInt( 2920d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth NextConstantType, Value.getSExtValue())) { 2921d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth FuncParser->setNextConstantID(C); 2922d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth return; 2923d2cb4361c732dcddc98659415f37be45982e20c3Jim Stichnoth } 2924f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2925f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf std::string Buffer; 2926f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf raw_string_ostream StrBuf(Buffer); 2927f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf StrBuf << "constant block integer record for non-integer type " 2928f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf << NextConstantType; 2929f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error(StrBuf.str()); 2930f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2931f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2932f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CST_CODE_FLOAT: { 2933f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // FLOAT: [fpval] 29342f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "float")) 2935f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2936f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf if (!isValidNextConstantType()) 2937f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 29386fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) { 29396fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf FuncParser->setNextConstantID(nullptr); 29406fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 29416fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf } 2942f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf switch (NextConstantType) { 2943f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case Ice::IceType_f32: { 29443281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf const Ice::APInt IntValue(32, static_cast<uint32_t>(Values[0])); 29453281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf float FpValue = Ice::convertAPIntToFp<int32_t, float>(IntValue); 29463281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf FuncParser->setNextConstantID(getContext()->getConstantFloat(FpValue)); 2947f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2948f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2949f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case Ice::IceType_f64: { 29503281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf const Ice::APInt IntValue(64, Values[0]); 29513281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf double FpValue = Ice::convertAPIntToFp<uint64_t, double>(IntValue); 29523281748ca3956af27081458f7c2daf0973ecf1fdKarl Schimpf FuncParser->setNextConstantID(getContext()->getConstantDouble(FpValue)); 2953f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2954f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2955f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf default: { 2956f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf std::string Buffer; 2957f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf raw_string_ostream StrBuf(Buffer); 2958f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf StrBuf << "constant block float record for non-floating type " 2959f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf << NextConstantType; 2960f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf Error(StrBuf.str()); 2961f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2962f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2963f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2964f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2965f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf default: 2966f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf // Generate error message! 2967f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf BlockParserBaseClass::ProcessRecord(); 2968f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return; 2969f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 2970f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf} 2971f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 2972c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf// Parses valuesymtab blocks appearing in a function block. 2973c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfclass FunctionValuesymtabParser : public ValuesymtabParser { 2974c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth FunctionValuesymtabParser() = delete; 29750795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth FunctionValuesymtabParser(const FunctionValuesymtabParser &) = delete; 29760795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth void operator=(const FunctionValuesymtabParser &) = delete; 2977c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 2978c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfpublic: 2979c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf FunctionValuesymtabParser(unsigned BlockID, FunctionParser *EnclosingParser) 298058455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : ValuesymtabParser(BlockID, EnclosingParser), 298158455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseFunctionValuesymtabs, 298258455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf getTranslator().getContext()) {} 2983c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 2984c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfprivate: 298558455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 2986c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Returns the enclosing function parser. 2987c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf FunctionParser *getFunctionParser() const { 2988c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return reinterpret_cast<FunctionParser *>(GetEnclosingParser()); 2989c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 2990c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 299152863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf const char *getTableKind() const final { return "Function"; } 299252863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf 299352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; 299452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; 2995c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 299657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Reports that the assignment of Name to the value associated with index is 299757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // not possible, for the given Context. 299874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void reportUnableToAssign(const char *Context, NaClBcIndexSize_t Index, 2999c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf StringType &Name) { 3000c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf std::string Buffer; 3001c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf raw_string_ostream StrBuf(Buffer); 3002c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf StrBuf << "Function-local " << Context << " name '" << Name 3003c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf << "' can't be associated with index " << Index; 3004c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf Error(StrBuf.str()); 3005c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 3006c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf}; 3007c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 300874cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid FunctionValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 300974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 3010c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // Note: We check when Index is too small, so that we can error recover 3011c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf // (FP->getOperand will create fatal error). 30122f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (Index < getFunctionParser()->getNumGlobalIDs()) { 301352863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Global value", Index, Name); 3014c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return; 3015c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 30166fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf if (isIRGenerationDisabled()) 30176fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 3018c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf Ice::Operand *Op = getFunctionParser()->getOperand(Index); 3019c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { 302020b71f5890ee8651983b126c5978594a01e0af96Jim Stichnoth if (Ice::BuildDefs::dump()) { 30219a04c0760fe48d0003ffcc5be13f67ccd924a9a4Jim Stichnoth std::string Nm(Name.data(), Name.size()); 30229a04c0760fe48d0003ffcc5be13f67ccd924a9a4Jim Stichnoth V->setName(getFunctionParser()->getFunc(), Nm); 30239a04c0760fe48d0003ffcc5be13f67ccd924a9a4Jim Stichnoth } 3024c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } else { 302552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Local value", Index, Name); 3026c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 3027c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 3028c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 302974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid FunctionValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 303074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 3031ac7d73441e1c599108b20c4702a96db0e956889eKarl Schimpf if (!Ice::BuildDefs::dump()) 30326fcbdddb021da27376e62c32623f92b3904b6211Karl Schimpf return; 3033ac7d73441e1c599108b20c4702a96db0e956889eKarl Schimpf if (isIRGenerationDisabled()) 3034c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return; 303598ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (Index >= getFunctionParser()->getFunc()->getNumNodes()) { 303652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Basic block", Index, Name); 303798ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf return; 303898ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf } 3039c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf std::string Nm(Name.data(), Name.size()); 304098ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf if (Ice::BuildDefs::dump()) 304198ed44642caf4ce694fbc3401c0ec958137b6f31Karl Schimpf getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm); 3042c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 3043c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3044f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpfbool FunctionParser::ParseBlock(unsigned BlockID) { 3045f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf switch (BlockID) { 3046f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf case naclbitc::CONSTANTS_BLOCK_ID: { 3047f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf ConstantsParser Parser(BlockID, this); 3048f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf return Parser.ParseThisBlock(); 3049f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 3050c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 3051c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf if (PNaClAllowLocalSymbolTables) { 3052c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf FunctionValuesymtabParser Parser(BlockID, this); 3053c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return Parser.ParseThisBlock(); 3054c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 3055c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf break; 3056c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf } 3057f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf default: 3058c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf break; 3059f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf } 3060c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf return BlockParserBaseClass::ParseBlock(BlockID); 3061f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf} 3062f12355ec5d0680048003f88435aa895830df4bf2Karl Schimpf 30638d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf/// Parses the module block in the bitcode file. 30648d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfclass ModuleParser : public BlockParserBaseClass { 3065c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleParser() = delete; 3066c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleParser(const ModuleParser &) = delete; 3067c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleParser &operator=(const ModuleParser &) = delete; 3068c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth 30698d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfpublic: 30708d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ModuleParser(unsigned BlockID, TopLevelParser *Context) 30716ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf : BlockParserBaseClass(BlockID, Context), 307258455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseModule, 3073eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth Context->getTranslator().getContext()) {} 30748d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3075e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ModuleParser() override = default; 30768d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 30772f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf const char *getBlockName() const override { return "module"; } 30782f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf 30795ee234a78dbaa81830efed1038161a40ea43d773Karl Schimpfprivate: 308058455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 30819d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // True if we have already installed names for unnamed global declarations, 30829d98d791123ce157aab73fba210e4d068935011fKarl Schimpf // and have generated global constant initializers. 3083eafb56cbab02dbf11071efbc56b4a7098bd40dc7Jim Stichnoth bool GlobalDeclarationNamesAndInitializersInstalled = false; 3084c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf // True if we have already processed the symbol table for the module. 3085c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf bool FoundValuesymtab = false; 30869d98d791123ce157aab73fba210e4d068935011fKarl Schimpf 308757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // Generates names for unnamed global addresses (i.e. functions and global 308857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // variables). Then lowers global variable declaration initializers to the 308957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // target. May be called multiple times. Only the first call will do the 309057e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // installation. 309174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void installGlobalNamesAndGlobalVarInitializers() { 30929d98d791123ce157aab73fba210e4d068935011fKarl Schimpf if (!GlobalDeclarationNamesAndInitializersInstalled) { 30936ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Context->installGlobalNames(); 30946ca7d2b6bfa9e4bca707240208bba6612d58719dKarl Schimpf Context->createValueIDs(); 3095c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf std::unique_ptr<Ice::VariableDeclarationList> Globals = 3096c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf Context->getGlobalVariables(); 3097c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf if (Globals) 3098c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf getTranslator().lowerGlobals(std::move(Globals)); 30999d98d791123ce157aab73fba210e4d068935011fKarl Schimpf GlobalDeclarationNamesAndInitializersInstalled = true; 31009d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 31019d98d791123ce157aab73fba210e4d068935011fKarl Schimpf } 31028e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth bool ParseBlock(unsigned BlockID) override; 31038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 310474cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf void ExitBlock() override { installGlobalNamesAndGlobalVarInitializers(); } 31056ff33d2fdba1ae8dde5e6409d4a21e1e875dcf56Karl Schimpf 31068e8042c42b71675891b824b6bfcd8938174661bcJim Stichnoth void ProcessRecord() override; 31078d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf}; 31088d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3109c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfclass ModuleValuesymtabParser : public ValuesymtabParser { 3110c6ead20cc2e9ecb0ca45b650ce911ef565d88f6eJim Stichnoth ModuleValuesymtabParser() = delete; 31110795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth ModuleValuesymtabParser(const ModuleValuesymtabParser &) = delete; 31120795ba012d00ef611ce1c6898db7652ed4559c62Jim Stichnoth void operator=(const ModuleValuesymtabParser &) = delete; 3113c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3114c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfpublic: 3115c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf ModuleValuesymtabParser(unsigned BlockID, ModuleParser *MP) 311658455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf : ValuesymtabParser(BlockID, MP), 311758455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Timer(Ice::TimerStack::TT_parseModuleValuesymtabs, 311858455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf getTranslator().getContext()) {} 3119c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3120e587d9494fa95920943fafa0f1dac470a298a251Jim Stichnoth ~ModuleValuesymtabParser() override = default; 3121c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 3122c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpfprivate: 312358455876adbd0fc92815bb0e2419363d569df2a5Karl Schimpf Ice::TimerMarker Timer; 312452863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf const char *getTableKind() const final { return "Module"; } 312552863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void setValueName(NaClBcIndexSize_t Index, StringType &Name) final; 312652863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf void setBbName(NaClBcIndexSize_t Index, StringType &Name) final; 3127c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf}; 3128c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 312974cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid ModuleValuesymtabParser::setValueName(NaClBcIndexSize_t Index, 313074cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 31319d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Context->getGlobalDeclarationByID(Index) 31329d98d791123ce157aab73fba210e4d068935011fKarl Schimpf ->setName(StringRef(Name.data(), Name.size())); 3133c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 3134c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 313574cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpfvoid ModuleValuesymtabParser::setBbName(NaClBcIndexSize_t Index, 313674cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf StringType &Name) { 313752863b13f2dfa1659f12f49154bcb13ec218f114Karl Schimpf reportUnableToAssign("Basic block", Index, Name); 3138c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf} 3139c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf 31408e8042c42b71675891b824b6bfcd8938174661bcJim Stichnothbool ModuleParser::ParseBlock(unsigned BlockID) { 31418d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (BlockID) { 31428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::BLOCKINFO_BLOCK_ID: 31438d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return NaClBitcodeParser::ParseBlock(BlockID); 31448d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::TYPE_BLOCK_ID_NEW: { 31458d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf TypesParser Parser(BlockID, this); 31468d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 31478d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31488d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::GLOBALVAR_BLOCK_ID: { 31498d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf GlobalsParser Parser(BlockID, this); 31508d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 31518d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::VALUE_SYMTAB_BLOCK_ID: { 3153c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf if (FoundValuesymtab) 3154c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf Fatal("Duplicate valuesymtab in module"); 3155c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf 3156c49eeae4f33d0048b7099b6756274ae4d61a867eKarl Schimpf FoundValuesymtab = true; 3157c132b767b45448e228d121dc92c61efcf400d3f6Karl Schimpf ModuleValuesymtabParser Parser(BlockID, this); 31588d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 31598d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31608d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::FUNCTION_BLOCK_ID: { 316174cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf installGlobalNamesAndGlobalVarInitializers(); 3162d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf FunctionParser Parser(BlockID, this); 31638e92838b8179d0b4a3022889c3446100b7ef831eJim Stichnoth return Parser.convertFunction(); 31648d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31658d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 31668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return BlockParserBaseClass::ParseBlock(BlockID); 31678d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31688d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 31698d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 31708d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfvoid ModuleParser::ProcessRecord() { 31718d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf const NaClBitcodeRecord::RecordVector &Values = Record.GetValues(); 31728d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf switch (Record.GetCode()) { 31738d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::MODULE_CODE_VERSION: { 31748d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // VERSION: [version#] 31752f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(1, "version")) 31768d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 317774cd883a0b3ccb0920e5990ed860b1862ac73090Karl Schimpf uint64_t Version = Values[0]; 31788d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Version != 1) { 31798d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 31808d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 31818d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf StrBuf << "Unknown bitstream version: " << Version; 31828d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 31838d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31848d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 31858d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 31868d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf case naclbitc::MODULE_CODE_FUNCTION: { 31878d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // FUNCTION: [type, callingconv, isproto, linkage] 31882f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf if (!isValidRecordSize(4, "address")) 31898d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 31909d98d791123ce157aab73fba210e4d068935011fKarl Schimpf const Ice::FuncSigType &Signature = Context->getFuncSigTypeByID(Values[0]); 31918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf CallingConv::ID CallingConv; 31928d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (!naclbitc::DecodeCallingConv(Values[1], CallingConv)) { 31938d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 31948d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 31952f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Function address has unknown calling convention: " 31968d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf << Values[1]; 31978d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 31988d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 31998d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32008d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf GlobalValue::LinkageTypes Linkage; 32018d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (!naclbitc::DecodeLinkage(Values[3], Linkage)) { 32028d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf std::string Buffer; 32038d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf raw_string_ostream StrBuf(Buffer); 32042f6f8605b944b17a307425a81013b51b5a00a1d3Karl Schimpf StrBuf << "Function address has unknown linkage. Found " << Values[3]; 32058d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Error(StrBuf.str()); 32068d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32078d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32080c729c8cb60f1316d589a5890abb5bdc1e59bc9fKarl Schimpf bool IsProto = Values[2] == 1; 32099d98d791123ce157aab73fba210e4d068935011fKarl Schimpf Ice::FunctionDeclaration *Func = Ice::FunctionDeclaration::create( 32101bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto Context->getTranslator().getContext(), Signature, CallingConv, Linkage, 32111bec8bcd64da0cd4855a357d740d3ad45bbef3b9John Porto IsProto); 32128d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf Context->setNextFunctionID(Func); 32138d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32148d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32158d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf default: 32168d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass::ProcessRecord(); 32178d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32188d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32198d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 32208d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32218d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfbool TopLevelParser::ParseBlock(unsigned BlockID) { 32228d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (BlockID == naclbitc::MODULE_BLOCK_ID) { 32238d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ModuleParser Parser(BlockID, this); 3224d6064a1aaca7a5596618e559a17cb9b20283ca46Karl Schimpf return Parser.ParseThisBlock(); 32258d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32268d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Generate error message by using default block implementation. 32278d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf BlockParserBaseClass Parser(BlockID, this); 32288d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return Parser.ParseThisBlock(); 32298d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 32308d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3231989a703f0c58731b79c83b186c726877b508be71Jim Stichnoth} // end of anonymous namespace 32328d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32338d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpfnamespace Ice { 32348d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32352e7daeff480fa07a3bb8b3eeeedaec369a7521a7Karl Schimpfvoid PNaClTranslator::translateBuffer(const std::string &IRFilename, 32362e7daeff480fa07a3bb8b3eeeedaec369a7521a7Karl Schimpf MemoryBuffer *MemBuf) { 3237c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung std::unique_ptr<MemoryObject> MemObj(getNonStreamedMemoryObject( 3238c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung reinterpret_cast<const unsigned char *>(MemBuf->getBufferStart()), 3239c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung reinterpret_cast<const unsigned char *>(MemBuf->getBufferEnd()))); 3240c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung translate(IRFilename, std::move(MemObj)); 3241c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung} 32428d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3243c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voungvoid PNaClTranslator::translate(const std::string &IRFilename, 3244c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung std::unique_ptr<MemoryObject> &&MemObj) { 324557e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // On error, we report_fatal_error to avoid destroying the MemObj. That may 324657e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // still be in use by IceBrowserCompileServer. Otherwise, we need to change 324757e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // the MemObj to be ref-counted, or have a wrapper, or simply leak. We also 324857e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // need a hook to tell the IceBrowserCompileServer to unblock its 324957e126899b20c65ff3ea23a3b7d7a67ab30b99dcAndrew Scull // QueueStreamer. 32502f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung // https://code.google.com/p/nativeclient/issues/detail?id=4163 32512f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung Ostream &ErrStream = getContext()->getStrError(); 32528d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Read header and verify it is good. 32538d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf NaClBitcodeHeader Header; 3254b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf if (Header.Read(MemObj.get())) { 32552f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Invalid PNaCl bitcode header"); 32568d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3257b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf if (!Header.IsSupported()) { 32582f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung ErrStream << Header.Unsupported(); 3259b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf if (!Header.IsReadable()) { 32602f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Invalid PNaCl bitcode header"); 3261b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf } 3262b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf } 32638d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32648d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf // Create a bitstream reader to read the bitcode file. 3265b33a2af2076ec1e24030f2a330fd547a1823b884Karl Schimpf NaClBitstreamReader InputStreamFile(MemObj.release(), Header); 32668d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf NaClBitstreamCursor InputStream(InputStreamFile); 32678d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 326822ed4eb40f1b4e0b92d5ac0db91a8a31824aa49dKarl Schimpf TopLevelParser Parser(*this, InputStream, ErrorStatus); 32698d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf int TopLevelBlocks = 0; 32708d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf while (!InputStream.AtEndOfStream()) { 32718d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (Parser.Parse()) { 3272fa4efea5413aa993e8e6ba10579e0934d1a3e784Jim Stichnoth ErrorStatus.assign(EC_Bitcode); 32738d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf return; 32748d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32758d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf ++TopLevelBlocks; 32768d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 32778d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 32788d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf if (TopLevelBlocks != 1) { 32792f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung ErrStream << IRFilename 32802f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung << ": Contains more than one module. Found: " << TopLevelBlocks 32812f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung << "\n"; 32822f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Bitcode has more than one module"); 32838d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf } 3284c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung if (InputStreamFile.getBitcodeBytes().getExtent() % 4 != 0) { 32852f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung ErrStream 32862f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung << IRFilename 32872f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung << ": Bitcode stream should be a multiple of 4 bytes in length.\n"; 32882f7f2b7e17a1ec338df337c806af657c4ed2cd8eJan Voung llvm::report_fatal_error("Bitcode stream should be a multiple of 4 bytes"); 3289c1f07ea7fbeb4a9de30059c6ca5f0662eb0b1c7dJan Voung } 32908d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf} 32918d7abae9a466e2dfdbca9fef69311e07c7e3690fKarl Schimpf 3292989a703f0c58731b79c83b186c726877b508be71Jim Stichnoth} // end of namespace Ice 3293