+
+/// OpInit - Base class for operators
+///
+class OpInit : public TypedInit {
+public:
+ OpInit(RecTy *Type) : TypedInit(Type) {}
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) = 0;
+
+ virtual int getNumOperands() const = 0;
+ virtual Init *getOperand(int i) = 0;
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ virtual Init *Fold(Record *CurRec, MultiClass *CurMultiClass) = 0;
+
+ virtual Init *convertInitializerTo(RecTy *Ty) {
+ return Ty->convertValue(this);
+ }
+
+ virtual Init *resolveBitReference(Record &R, const RecordVal *RV,
+ unsigned Bit);
+ virtual Init *resolveListElementReference(Record &R, const RecordVal *RV,
+ unsigned Elt);
+};
+
+
+/// UnOpInit - !op (X) - Transform an init.
+///
+class UnOpInit : public OpInit {
+public:
+ enum UnaryOp { CAST, CAR, CDR, LNULL };
+private:
+ UnaryOp Opc;
+ Init *LHS;
+public:
+ UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) :
+ OpInit(Type), Opc(opc), LHS(lhs) {
+ }
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) {
+ assert(Operands.size() == 1 &&
+ "Wrong number of operands for unary operation");
+ return new UnOpInit(getOpcode(), *Operands.begin(), getType());
+ }
+
+ int getNumOperands() const { return 1; }
+ Init *getOperand(int i) {
+ assert(i == 0 && "Invalid operand id for unary operator");
+ return getOperand();
+ }
+
+ UnaryOp getOpcode() const { return Opc; }
+ Init *getOperand() const { return LHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ /// getFieldType - This method is used to implement the FieldInit class.
+ /// Implementors of this method should return the type of the named field if
+ /// they are of record type.
+ ///
+ virtual RecTy *getFieldType(const std::string &FieldName) const;
+
+ virtual std::string getAsString() const;
+};
+
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public OpInit {
+public:
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
+private:
+ BinaryOp Opc;
+ Init *LHS, *RHS;
+public:
+ BinOpInit(BinaryOp opc, Init *lhs, Init *rhs, RecTy *Type) :
+ OpInit(Type), Opc(opc), LHS(lhs), RHS(rhs) {
+ }
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) {
+ assert(Operands.size() == 2 &&
+ "Wrong number of operands for binary operation");
+ return new BinOpInit(getOpcode(), Operands[0], Operands[1], getType());
+ }
+
+ int getNumOperands() const { return 2; }
+ Init *getOperand(int i) {
+ assert((i == 0 || i == 1) && "Invalid operand id for binary operator");
+ if (i == 0) {
+ return getLHS();
+ } else {
+ return getRHS();
+ }
+ }
+
+ BinaryOp getOpcode() const { return Opc; }
+ Init *getLHS() const { return LHS; }
+ Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ 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;
+ Init *LHS, *MHS, *RHS;
+public:
+ TernOpInit(TernaryOp opc, Init *lhs, Init *mhs, Init *rhs, RecTy *Type) :
+ OpInit(Type), Opc(opc), LHS(lhs), MHS(mhs), RHS(rhs) {
+ }
+
+ // Clone - Clone this operator, replacing arguments with the new list
+ virtual OpInit *clone(std::vector<Init *> &Operands) {
+ assert(Operands.size() == 3 &&
+ "Wrong number of operands for ternary operation");
+ return new TernOpInit(getOpcode(), Operands[0], Operands[1], Operands[2],
+ getType());
+ }
+
+ int getNumOperands() const { return 3; }
+ Init *getOperand(int i) {
+ 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; }
+ Init *getLHS() const { return LHS; }
+ Init *getMHS() const { return MHS; }
+ Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ virtual std::string getAsString() const;
+};
+
+