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