+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public OpInit {
+public:
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
+private:
+ BinaryOp Opc;
+ const Init *LHS, *RHS;
+
+ BinOpInit(const FoldingSetNodeID &ID, BinaryOp opc, const Init *lhs,
+ const Init *rhs, RecTy *Type) :
+ OpInit(ID, Type), Opc(opc), LHS(lhs), RHS(rhs) {}
+
+ BinOpInit(const BinOpInit &Other); // Do not define.
+ BinOpInit &operator=(const BinOpInit &Other); // Do not define.
+
+public:
+ static const BinOpInit *Create(BinaryOp opc, const Init *lhs, const Init *rhs,
+ RecTy *Type);
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual const OpInit *clone(std::vector<const Init *> &Operands) const {
+ assert(Operands.size() == 2 &&
+ "Wrong number of operands for binary operation");
+ return BinOpInit::Create(getOpcode(), Operands[0], Operands[1], getType());
+ }
+
+ int getNumOperands() const { return 2; }
+ const Init *getOperand(int i) const {
+ assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
+ if (i == 0) {
+ return getLHS();
+ } else {
+ return getRHS();
+ }
+ }
+
+ BinaryOp getOpcode() const { return Opc; }
+ const Init *getLHS() const { return LHS; }
+ const Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ const Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+
+ virtual const Init *resolveReferences(Record &R,
+ const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+};
+
+/// TernOpInit - !op (X, Y, Z) - Combine two inits.
+///
+class TernOpInit : public OpInit {
+public:
+ enum TernaryOp { SUBST, FOREACH, IF };
+private:
+ TernaryOp Opc;
+ const Init *LHS, *MHS, *RHS;
+
+ TernOpInit(const FoldingSetNodeID &ID, TernaryOp opc, const Init *lhs,
+ const Init *mhs, const Init *rhs, RecTy *Type) :
+ OpInit(ID, Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {}
+
+ TernOpInit(const TernOpInit &Other); // Do not define.
+ TernOpInit &operator=(const TernOpInit &Other); // Do not define.
+
+public:
+ static const TernOpInit *Create(TernaryOp opc, const Init *lhs,
+ const Init *mhs, const Init *rhs,
+ RecTy *Type);
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual const OpInit *clone(std::vector<const Init *> &Operands) const {
+ assert(Operands.size() == 3 &&
+ "Wrong number of operands for ternary operation");
+ return TernOpInit::Create(getOpcode(), Operands[0], Operands[1],
+ Operands[2], getType());
+ }
+
+ int getNumOperands() const { return 3; }
+ const Init *getOperand(int i) const {
+ assert((i == 0 || i == 1 || i == 2) &&
+ "Invalid operand id for ternary operator");
+ if (i == 0) {
+ return getLHS();
+ } else if (i == 1) {
+ return getMHS();
+ } else {
+ return getRHS();
+ }
+ }
+
+ TernaryOp getOpcode() const { return Opc; }
+ const Init *getLHS() const { return LHS; }
+ const Init *getMHS() const { return MHS; }
+ const Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ const Init *Fold(Record *CurRec, MultiClass *CurMultiClass) const;
+
+ virtual bool isComplete() const { return false; }
+
+ virtual const Init *resolveReferences(Record &R,
+ const RecordVal *RV) const;
+
+ virtual std::string getAsString() const;
+};
+
+