diff --git a/offlineASL-cpp/aslp_lifter_base.hpp b/offlineASL-cpp/aslp_lifter_base.hpp index 5c44be24..e470186e 100644 --- a/offlineASL-cpp/aslp_lifter_base.hpp +++ b/offlineASL-cpp/aslp_lifter_base.hpp @@ -9,116 +9,7 @@ namespace aslp { -// bits which are known at lift-time -using bits = llvm::APInt; -// bigints which are known at lift-time -using bigint = long long; - -// runtime-expression type, i.e. the type of values produced by the semantics -using rt_expr = llvm::Value *; -// runtime-label, supports switching blocks during semantics generation -using rt_label = llvm::BasicBlock *; - -bits extract_bits(const bits &val, bigint lo, bigint wd); - -bool f_eq_bits(bits x, bits y); -bool f_ne_bits(bits x, bits y); -bits f_add_bits(bits x, bits y); -bits f_sub_bits(bits x, bits y); -bits f_mul_bits(bits x, bits y); -bits f_and_bits(bits x, bits y); -bits f_or_bits(bits x, bits y); -bits f_eor_bits(bits x, bits y); -bits f_not_bits(bits x); -bool f_slt_bits(bits x, bits y); -bool f_sle_bits(bits x, bits y); -bits f_zeros_bits(bigint n); -bits f_ones_bits(bigint n); -bits f_replicate_bits(bits x, bigint n); -bits f_append_bits(bits x, bits y); -bits f_ZeroExtend(bits x, bigint wd); -bits f_SignExtend(bits x, bigint wd); -bits f_lsl_bits(bits x, bits y); -bits f_lsr_bits(bits x, bits y); -bits f_asr_bits(bits x, bits y); -bigint f_cvt_bits_uint(bits x); - -class aslp_lifter_base { - -virtual rt_expr f_decl_bv(const std::string_view& name, bigint width) = 0; -let f_decl_bool name = - -let f_switch_context ctx = - -let f_gen_branch cond = -let f_gen_assert b = -let f_gen_bit_lit w (bv: bitvector) = -let f_gen_bool_lit b = -let f_gen_int_lit i = -let f_gen_load v = v -let f_gen_store v e = push_stmt (Stmt_Assign(to_lexpr v, e, loc)) -let f_gen_array_load a i = -let f_gen_array_store a i e = -let f_gen_Mem_set w x _ y z = -let f_gen_Mem_read w x _ y = -let f_gen_AArch64_MemTag_set x y z: unit = -let f_gen_and_bool e1 e2 = -let f_gen_or_bool e1 e2 = -let f_gen_not_bool e1 = -let f_gen_eq_enum e1 e2 = -let f_gen_cvt_bits_uint w x = -let f_gen_eq_bits w e1 e2 = -let f_gen_ne_bits w e1 e2 = -let f_gen_not_bits w e1 = -let f_gen_cvt_bool_bv e = -let f_gen_or_bits w e1 e2 = -let f_gen_eor_bits w e1 e2 = -let f_gen_and_bits w e1 e2 = -let f_gen_add_bits w e1 e2 = -let f_gen_sub_bits w e1 e2 = -let f_gen_sdiv_bits w e1 e2 = -let f_gen_sle_bits w e1 e2 = -let f_gen_slt_bits w e1 e2 = -let f_gen_mul_bits w e1 e2 = -let f_gen_append_bits xw yw x y = -let f_gen_lsr_bits xw yw x y = -let f_gen_lsl_bits xw yw x y = -let f_gen_asr_bits xw yw x y = -let f_gen_replicate_bits xw yw x y = -let f_gen_ZeroExtend xw yw x y = -let f_gen_SignExtend xw yw x y = -let f_gen_slice e lo wd = -let f_gen_FPCompare w x y s t = -let f_gen_FPCompareEQ w x y r = -let f_gen_FPCompareGE w x y r = -let f_gen_FPCompareGT w x y r = -let f_gen_FPAdd w x y r = -let f_gen_FPSub w x y r = -let f_gen_FPMulAdd w a x y r = -let f_gen_FPMulAddH w a x y r = -let f_gen_FPMulX w x y r = -let f_gen_FPMul w x y r = -let f_gen_FPDiv w x y r = -let f_gen_FPMin w x y r = -let f_gen_FPMinNum w x y r = -let f_gen_FPMax w x y r = -let f_gen_FPMaxNum w x y r = -let f_gen_FPRecpX w x t = -let f_gen_FPSqrt w x t = -let f_gen_FPRecipEstimate w x r = -let f_gen_BFAdd x y = -let f_gen_BFMul x y = -let f_gen_FPConvertBF x t r = -let f_gen_FPRecipStepFused w x y = -let f_gen_FPRSqrtStepFused w x y = -let f_gen_FPToFixed w w' x b u t r = -let f_gen_FixedToFP w w' x b u t r = -let f_gen_FPConvert w w' x t r = -let f_gen_FPRoundInt w x t r e = -let f_gen_FPRoundIntN w x t r e = -let f_gen_FPToFixedJS_impl w w' x t s = - }; -}; \ No newline at end of file +}; diff --git a/offlineASL-cpp/interface.hpp b/offlineASL-cpp/interface.hpp index bf7566c3..1066a40e 100644 --- a/offlineASL-cpp/interface.hpp +++ b/offlineASL-cpp/interface.hpp @@ -1,227 +1,155 @@ #pragma once -#include #include #include +#include namespace aslp { -// an opcode for ASLP is four bytes (= 32 bits), in Arm's conventional little-endian order. -using opcode_t = std::array; - -enum struct err_t { - missing, - banned, -}; - -enum struct pstate_t : uint64_t { - N = 0, Z, C, V -}; - -enum struct reg_t { - X, - V, - PSTATE, -}; - -template +template class lifter_interface { public: - - using type_t = TYPE; - using expr_t = EXPR; - using lexpr_t = LEXPR; - using stmt_t = STMT; - using slice_t = SLICE; - - virtual ~lifter_interface() = default; - - // perform possibly non-atomic memory load/store - // virtual llvm::Value* mem_load(llvm::Value* addr, llvm::Value* size) = 0; - // virtual void mem_store(llvm::Value* addr, llvm::Value* size, llvm::Value* rhs) = 0; - - // should return a ptr type value suitable for load and store - virtual lexpr_t get_reg(reg_t, uint64_t num) = 0; - - // XXX: callback for `aslt_visitor` to inform arm2llvm of changed basic blocks, - // so create* functions create instructions in the right place. - virtual void set_bb(llvm::BasicBlock*) = 0; - virtual llvm::BasicBlock* get_bb() = 0; - - virtual llvm::Function& ll_function() = 0; - - // lifted instructions are named using the number of the ARM - // instruction they come from - virtual std::string nextName() = 0; - - virtual expr_t lookupExprVar(const llvm::MCExpr&) = 0; - virtual void updateOutputReg(expr_t V, bool SExt = false) = 0; - - virtual expr_t getIntConst(uint64_t val, u_int64_t bits) = 0; - virtual type_t getIntTy(unsigned bits) = 0; - virtual type_t getFPType(unsigned bits) = 0; - - virtual void assertTrue(expr_t cond) = 0; - - virtual expr_t makeLoadWithOffset(expr_t base, expr_t offset, int size) = 0; - virtual void storeToMemoryValOffset(expr_t base, expr_t offset, u_int64_t size, expr_t val) = 0; - - virtual lexpr_t createAlloca(type_t ty, expr_t sz, const std::string &NameStr) = 0; - - virtual expr_t createGEP(type_t ty, expr_t v, llvm::ArrayRef idxlist, - const std::string &NameStr) = 0; - - virtual void createBranch(expr_t c, stmt_t t, stmt_t f) = 0; - - virtual void createBranch(stmt_t dst) = 0; - - virtual expr_t createLoad(type_t ty, expr_t ptr) = 0; - - virtual void createStore(expr_t v, expr_t ptr) = 0; - - virtual expr_t createTrap() = 0; - - virtual expr_t createSMin(expr_t a, expr_t b) = 0; - - virtual expr_t createSMax(expr_t a, expr_t b) = 0; - - virtual expr_t createUMin(expr_t a, expr_t b) = 0; - - virtual expr_t createUMax(expr_t a, expr_t b) = 0; - - virtual expr_t createFNeg(expr_t v) = 0; - - virtual expr_t createFAbs(expr_t v) = 0; - - virtual expr_t createSSubOverflow(expr_t a, expr_t b) = 0; - - virtual expr_t createSAddOverflow(expr_t a, expr_t b) = 0; - - virtual expr_t createUSubOverflow(expr_t a, expr_t b) = 0; - - virtual expr_t createUAddOverflow(expr_t a, expr_t b) = 0; - - virtual expr_t createUAddSat(expr_t a, expr_t b) = 0; - - virtual expr_t createUSubSat(expr_t a, expr_t b) = 0; - - virtual expr_t createSAddSat(expr_t a, expr_t b) = 0; - - virtual expr_t createSSubSat(expr_t a, expr_t b) = 0; - - virtual expr_t createCtPop(expr_t v) = 0; - - // first argument is an i16 - virtual expr_t createConvertFromFP16(expr_t v, type_t ty) = 0; - - virtual expr_t createConvertFPToSI(expr_t v, type_t ty) = 0; - - virtual expr_t createConvertFPToUI(expr_t v, type_t ty) = 0; - - virtual expr_t createPtrToInt(expr_t v, type_t ty) = 0; - - virtual expr_t createInsertElement(expr_t vec, expr_t val, int idx) = 0; - - virtual expr_t createExtractElement(expr_t v, expr_t idx) = 0; - - virtual expr_t createExtractElement(expr_t v, int idx) = 0; - - virtual expr_t createShuffleVector(expr_t v, llvm::ArrayRef mask) = 0; - - virtual expr_t getIndexedElement(unsigned idx, unsigned eltSize, unsigned reg) = 0; - - virtual expr_t createExtractValue(expr_t v, llvm::ArrayRef idxs) = 0; - - virtual expr_t createReturn(expr_t v) = 0; - - virtual expr_t createFShr(expr_t a, expr_t b, expr_t c) = 0; - - virtual expr_t createFShl(expr_t a, expr_t b, expr_t c) = 0; - - virtual expr_t createBitReverse(expr_t v) = 0; - - virtual expr_t createAbs(expr_t v) = 0; - - virtual expr_t createCtlz(expr_t v) = 0; - - virtual expr_t createBSwap(expr_t v) = 0; - - virtual expr_t createVectorReduceAdd(expr_t v) = 0; - - virtual expr_t createSelect(expr_t cond, expr_t a, expr_t b) = 0; - - virtual expr_t createICmp(llvm::ICmpInst::Predicate p, expr_t a, expr_t b) = 0; - - virtual expr_t createFCmp(llvm::FCmpInst::Predicate p, expr_t a, expr_t b) = 0; - - virtual expr_t createBinop(expr_t a, expr_t b, llvm::Instruction::BinaryOps op) = 0; - - virtual expr_t createUDiv(expr_t a, expr_t b) = 0; - - virtual expr_t createSDiv(expr_t a, expr_t b) = 0; - - virtual expr_t createMul(expr_t a, expr_t b) = 0; - - virtual expr_t createAdd(expr_t a, expr_t b) = 0; - - virtual expr_t createSub(expr_t a, expr_t b) = 0; - - virtual expr_t createRawLShr(expr_t a, expr_t b) = 0; - - virtual expr_t createMaskedLShr(expr_t a, expr_t b) = 0; - - virtual expr_t createRawAShr(expr_t a, expr_t b) = 0; - - virtual expr_t createMaskedAShr(expr_t a, expr_t b) = 0; - - virtual expr_t createRawShl(expr_t a, expr_t b) = 0; - - virtual expr_t createMaskedShl(expr_t a, expr_t b) = 0; - - virtual expr_t getLowOnes(int ones, int w) = 0; - - virtual expr_t createMSL(expr_t a, int b) = 0; - - virtual expr_t createAnd(expr_t a, expr_t b) = 0; - - virtual expr_t createOr(expr_t a, expr_t b) = 0; - - virtual expr_t createXor(expr_t a, expr_t b) = 0; - - virtual expr_t createNot(expr_t a) = 0; - - virtual expr_t createFreeze(expr_t v) = 0; - - virtual expr_t createTrunc(expr_t v, type_t t) = 0; - - virtual expr_t createSExt(expr_t v, type_t t) = 0; - - virtual expr_t createZExt(expr_t v, type_t t) = 0; - - virtual expr_t createUIToFP(expr_t v, type_t t) = 0; - virtual expr_t createSIToFP(expr_t v, type_t t) = 0; - - virtual expr_t createBitCast(expr_t v, type_t t) = 0; - - virtual expr_t createCast(expr_t v, type_t t, llvm::Instruction::CastOps op) = 0; - + // bits which are known at lift-time + using bits = BITS; + // bigints which are known at lift-time + using bigint = BIGINT; + + // runtime-expression type, i.e. the type of values produced by the semantics + using rt_expr = RT_EXPR; + using rt_lexpr = RT_EXPR; + // runtime-label, supports switching blocks during semantics generation + using rt_label = RT_LABEL; + +protected: + virtual bits extract_bits(const bits &val, bigint lo, bigint wd) = 0; + + virtual bool f_eq_bits(const bits &x, const bits &y) = 0; + virtual bool f_ne_bits(const bits &x, const bits &y) = 0; + virtual bits f_add_bits(const bits &x, const bits &y) = 0; + virtual bits f_sub_bits(const bits &x, const bits &y) = 0; + virtual bits f_mul_bits(const bits &x, const bits &y) = 0; + virtual bits f_and_bits(const bits &x, const bits &y) = 0; + virtual bits f_or_bits(const bits &x, const bits &y) = 0; + virtual bits f_eor_bits(const bits &x, const bits &y) = 0; + virtual bits f_not_bits(const bits &x) = 0; + virtual bool f_slt_bits(const bits &x, const bits &y) = 0; + virtual bool f_sle_bits(const bits &x, const bits &y) = 0; + virtual bits f_zeros_bits(bigint n) = 0; + virtual bits f_ones_bits(bigint n) = 0; + virtual bits f_replicate_bits(const bits &x, bigint n) = 0; + virtual bits f_append_bits(const bits &x, const bits &y) = 0; + virtual bits f_ZeroExtend(const bits &x, bigint wd) = 0; + virtual bits f_SignExtend(const bits &x, bigint wd) = 0; + virtual bits f_lsl_bits(const bits &x, const bits &y) = 0; + virtual bits f_lsr_bits(const bits &x, const bits &y) = 0; + virtual bits f_asr_bits(const bits &x, const bits &y) = 0; + virtual bigint f_cvt_bits_uint(const bits &x) = 0; + + virtual rt_expr f_decl_bv(std::string_view name, bigint width) = 0; + virtual rt_expr f_decl_bool(std::string_view name) = 0; + + virtual void f_switch_context(rt_label label) = 0; + + virtual std::tuple + f_gen_branch(rt_expr cond) = 0; + + virtual void f_gen_assert(rt_expr cond) = 0; + virtual rt_expr f_gen_bit_lit(bits bits) = 0; + virtual rt_expr f_gen_bool_lit(bool b) = 0; + virtual rt_expr f_gen_int_lit(bigint i) = 0; + virtual rt_expr f_gen_load(rt_lexpr ptr) = 0; + virtual void f_gen_store(rt_lexpr var, rt_expr exp) = 0; + virtual void + f_gen_array_load(rt_lexpr array, + rt_expr index) = 0; // XXX unsure of array ptr type. + virtual void f_gen_array_store(rt_lexpr array, rt_expr index, rt_expr exp) = 0; + virtual void f_gen_Mem_set(rt_expr ptr, rt_expr width, rt_expr acctype, + rt_expr exp) = 0; + virtual rt_expr f_gen_Mem_read(rt_expr ptr, rt_expr width, + rt_expr acctype) = 0; + virtual void f_gen_AArch64_MemTag_set(rt_expr desc, rt_expr value) = 0; + + virtual rt_expr f_gen_cvt_bits_uint(rt_expr bits) = 0; + virtual rt_expr f_gen_cvt_bool_bv(rt_expr e) = 0; + + virtual rt_expr f_gen_not_bool(rt_expr e) = 0; + virtual rt_expr f_gen_and_bool(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_or_bool(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_eq_enum(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_eq_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_ne_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_not_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_or_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_eor_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_and_bits(rt_expr x, rt_expr y) = 0; + + virtual rt_expr f_gen_add_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_sub_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_sdiv_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_sle_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_slt_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_mul_bits(rt_expr x, rt_expr y) = 0; + + virtual rt_expr f_gen_append_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_lsr_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_lsl_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_asr_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_replicate_bits(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_ZeroExtend(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_SignExtend(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_slice(rt_expr e, rt_expr lo, rt_expr wd) = 0; + + virtual rt_expr f_gen_FPCompare(rt_expr x, rt_expr y, rt_expr signalnan, + rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPCompareEQ(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPCompareGE(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPCompareGT(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPAdd(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPSub(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMulAdda(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMulAddHa(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMulX(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMul(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPDiv(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMin(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMinNum(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMax(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPMaxNum(rt_expr x, rt_expr y, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPRecpX(rt_expr x, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPSqrt(rt_expr x, rt_expr fpcr) = 0; + virtual rt_expr f_gen_FPRecipEstimate(rt_expr x, rt_expr fpcr) = 0; + virtual rt_expr f_gen_BFAdd(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_BFMul(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_FPConvertBF(rt_expr x, rt_expr fpcr, + rt_expr rounding) = 0; + virtual rt_expr f_gen_FPRecipStepFused(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_FPRSqrtStepFused(rt_expr x, rt_expr y) = 0; + virtual rt_expr f_gen_FPToFixed(rt_expr x, rt_expr fbits, rt_expr isunsigned, + rt_expr fpcr, rt_expr rounding) = 0; + virtual rt_expr f_gen_FixedToFP(rt_expr x, rt_expr fbits, rt_expr isunsigned, + rt_expr fpcr, rt_expr rounding) = 0; + virtual rt_expr f_gen_FPConvert(rt_expr x, rt_expr fpcr, + rt_expr rounding) = 0; + virtual rt_expr f_gen_FPRoundInt(rt_expr x, rt_expr fpcr, rt_expr rounding, + rt_expr isexact) = 0; + virtual rt_expr f_gen_FPRoundIntN(rt_expr x, rt_expr fpcr, rt_expr rounding, + rt_expr intsize) = 0; + virtual rt_expr f_gen_FPToFixedJS_impl(rt_expr x, rt_expr fpcr, + rt_expr is64) = 0; // from override.asl }; +namespace llvm_detail { +using bits = llvm::APInt; +using bigint = long long; +using rt_expr = llvm::Value *; +using rt_lexpr = llvm::AllocaInst *; +using rt_label = llvm::BasicBlock *; -namespace detail { - using type_t = llvm::Type *; - using expr_t = llvm::Value *; - using lexpr_t = llvm::AllocaInst *; - using stmt_t = std::pair; - struct slice_t { - unsigned lo; - unsigned wd; - }; - - using lifter_interface_llvm = lifter_interface; -} - -using detail::lifter_interface_llvm; +using lifter_interface_llvm = + lifter_interface; +} // namespace llvm_detail +using llvm_detail::lifter_interface_llvm; -} +} // namespace aslp