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