• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INSTRUCTIONS_H
18 #define INSTRUCTIONS_H
19 
20 #include <stdint.h>
21 
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 
26 #include "core_defs.h"
27 #include "entity.h"
28 #include "opcodes_generated.h"
29 #include "types_generated.h"
30 #include "visitor.h"
31 #include "word_stream.h"
32 
33 namespace android {
34 namespace spirit {
35 
36 // Word count for a serialized operand
WordCount(T)37 template <typename T> uint16_t WordCount(T) { return 1; }
38 
WordCount(PairLiteralIntegerIdRef)39 inline uint16_t WordCount(PairLiteralIntegerIdRef) { return 2; }
WordCount(PairIdRefLiteralInteger)40 inline uint16_t WordCount(PairIdRefLiteralInteger) { return 2; }
WordCount(PairIdRefIdRef)41 inline uint16_t WordCount(PairIdRefIdRef) { return 2; }
WordCount(const std::string & operand)42 inline uint16_t WordCount(const std::string &operand) {
43   return operand.length() / 4 + 1;
44 }
45 
46 class Instruction : public Entity {
47 public:
Instruction(uint32_t opCode)48   Instruction(uint32_t opCode) : mCodeAndCount(opCode) {}
Instruction(uint32_t opCode,uint32_t fixedWordCount)49   Instruction(uint32_t opCode, uint32_t fixedWordCount)
50       : mCodeAndCount(opCode), mFixedWordCount(fixedWordCount) {}
~Instruction()51   virtual ~Instruction() {}
52 
53   void accept(IVisitor *v) override;
54 
setWordCount()55   void setWordCount() const {
56     if (mCodeAndCount.mWordCount == 0) {
57       mCodeAndCount.mWordCount = getWordCount();
58     }
59   }
60   virtual uint16_t getWordCount() const = 0;
61   virtual bool hasResult() const = 0;
62   virtual IdResult getId() const = 0;
63   virtual void setId(IdResult) = 0;
64   virtual std::vector<const IdRef *> getAllIdRefs() const = 0;
65 
addExtraOperand(uint32_t word)66   Instruction *addExtraOperand(uint32_t word) {
67     mExtraOperands.push_back(word);
68     return this;
69   }
70 
71   // Adds decoration to the current instruction.
72   // Returns: the result OpDecorate instruction
73   DecorateInst *decorate(Decoration);
74   MemberDecorateInst *memberDecorate(int member, Decoration);
75 
DeserializeFirstWord(InputWordStream & IS,OpCode opcode)76   bool DeserializeFirstWord(InputWordStream &IS, OpCode opcode) {
77     if (IS.empty()) {
78       return false;
79     }
80 
81     OpCodeAndWordCount codeAndCount(*IS);
82 
83     if (codeAndCount.mOpCode != opcode) {
84       return false;
85     }
86 
87     mRemainingWordCount = codeAndCount.mWordCount;
88 
89     IS >> &mCodeAndCount;
90 
91     mRemainingWordCount--;
92 
93     return true;
94   }
95 
96   template <typename T>
DeserializeExactlyOne(InputWordStream & IS,T * operand)97   bool DeserializeExactlyOne(InputWordStream &IS, T *operand) {
98     if (IS.empty()) {
99       return false;
100     }
101 
102     IS >> operand;
103 
104     mRemainingWordCount -= WordCount(*operand);
105 
106     return true;
107   }
108 
109   template <typename T>
DeserializeOptionallyOne(InputWordStream & IS,T ** operand)110   bool DeserializeOptionallyOne(InputWordStream &IS, T **operand) {
111     if (mRemainingWordCount == 0) {
112       return true;
113     }
114     *operand = new T();
115     return DeserializeExactlyOne(IS, *operand);
116   }
117 
118   template <typename T>
DeserializeZeroOrMoreOperands(InputWordStream & IS,std::vector<T> * operands)119   bool DeserializeZeroOrMoreOperands(InputWordStream &IS,
120                                      std::vector<T> *operands) {
121     while (mRemainingWordCount > 0) {
122       T tmp;
123       if (!DeserializeExactlyOne(IS, &tmp)) {
124         return false;
125       }
126       operands->push_back(tmp);
127     }
128     return true;
129   }
130 
DeserializeExtraOperands(InputWordStream & IS)131   bool DeserializeExtraOperands(InputWordStream &IS) {
132     return DeserializeZeroOrMoreOperands(IS, &mExtraOperands);
133   }
134 
SerializeExtraOperands(OutputWordStream & OS)135   void SerializeExtraOperands(OutputWordStream &OS) const {
136     for (uint32_t w : mExtraOperands) {
137       OS << w;
138     }
139   }
140 
getAnnotations()141   const std::vector<Instruction *> &getAnnotations() const {
142     return mDecorations;
143   }
144 
getOpCode()145   uint16_t getOpCode() const { return mCodeAndCount.mOpCode; }
146 
147   mutable OpCodeAndWordCount mCodeAndCount;
148   uint16_t mFixedWordCount;
149   uint16_t mRemainingWordCount;
150   std::vector<uint32_t> mExtraOperands;
151   std::vector<Instruction *> mDecorations;
152 };
153 
154 } // namespace spirit
155 } // namespace android
156 
157 #include "instructions_generated.h"
158 
159 #endif // INSTRUCTIONS_H
160