#ifndef EXPR_H
#define EXPR_H
#include <cstdint>
#include <string>
#include <vector>
struct VSVideoInfo;
namespace expr {
#define MAX_EXPR_INPUTS 26
enum class ExprOpType {
MEM_LOAD_U8, MEM_LOAD_U16, MEM_LOAD_F16, MEM_LOAD_F32, CONSTANT,
MEM_STORE_U8, MEM_STORE_U16, MEM_STORE_F16, MEM_STORE_F32,
ADD, SUB, MUL, DIV, FMA, SQRT, ABS, NEG, MAX, MIN, CMP,
AND, OR, XOR, NOT,
EXP, LOG, POW, SIN, COS,
TERNARY,
MUX,
DUP, SWAP,
};
enum class FMAType {
FMADD = 0, FMSUB = 1, FNMADD = 2, FNMSUB = 3, };
enum class ComparisonType {
EQ = 0,
LT = 1,
LE = 2,
NEQ = 4,
NLT = 5,
NLE = 6,
};
union ExprUnion {
int32_t i;
uint32_t u;
float f;
constexpr ExprUnion() : u{} {}
constexpr ExprUnion(int32_t i) : i(i) {}
constexpr ExprUnion(uint32_t u) : u(u) {}
constexpr ExprUnion(float f) : f(f) {}
};
struct ExprOp {
ExprOpType type;
ExprUnion imm;
ExprOp(ExprOpType type, ExprUnion param = {}) : type(type), imm(param) {}
};
inline bool operator==(const ExprOp &lhs, const ExprOp &rhs) { return lhs.type == rhs.type && lhs.imm.u == rhs.imm.u; }
inline bool operator!=(const ExprOp &lhs, const ExprOp &rhs) { return !(lhs == rhs); }
struct ExprInstruction {
ExprOp op;
int dst;
int src1;
int src2;
int src3;
ExprInstruction(ExprOp op) : op(op), dst(-1), src1(-1), src2(-1), src3(-1) {}
};
std::vector<ExprInstruction> compile(const std::string &expr, const VSVideoInfo * const srcFormats[], int numInputs, const VSVideoInfo &dstFormat, bool optimize = true);
}
#endif