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 33namespace android { 34namespace spirit { 35 36// Word count for a serialized operand 37template <typename T> uint16_t WordCount(T) { return 1; } 38 39inline uint16_t WordCount(PairLiteralIntegerIdRef) { return 2; } 40inline uint16_t WordCount(PairIdRefLiteralInteger) { return 2; } 41inline uint16_t WordCount(PairIdRefIdRef) { return 2; } 42inline uint16_t WordCount(const std::string &operand) { 43 return operand.length() / 4 + 1; 44} 45 46class Instruction : public Entity { 47public: 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