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 37 template <typename T> uint16_t WordCount(T) { return 1; } 38 39 inline uint16_t WordCount(PairLiteralIntegerIdRef) { return 2; } 40 inline uint16_t WordCount(PairIdRefLiteralInteger) { return 2; } 41 inline uint16_t WordCount(PairIdRefIdRef) { return 2; } 42 inline uint16_t WordCount(const std::string &operand) { 43 return operand.length() / 4 + 1; 44 } 45 46 class Instruction : public Entity { 47 public: 48 Instruction(uint32_t opCode) : mCodeAndCount(opCode) {} 49 Instruction(uint32_t opCode, uint32_t fixedWordCount) 50 : mCodeAndCount(opCode), mFixedWordCount(fixedWordCount) {} 51 virtual ~Instruction() {} 52 53 void accept(IVisitor *v) override; 54 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 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 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> 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> 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> 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 131 bool DeserializeExtraOperands(InputWordStream &IS) { 132 return DeserializeZeroOrMoreOperands(IS, &mExtraOperands); 133 } 134 135 void SerializeExtraOperands(OutputWordStream &OS) const { 136 for (uint32_t w : mExtraOperands) { 137 OS << w; 138 } 139 } 140 141 const std::vector<Instruction *> &getAnnotations() const { 142 return mDecorations; 143 } 144 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