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