| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514 |
- /*
- * Copyright (C) 2021 Intel Corporation. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #ifndef _JIT_FRONTEND_H_
- #define _JIT_FRONTEND_H_
- #include "jit_utils.h"
- #include "jit_ir.h"
- #include "../interpreter/wasm_interp.h"
- #if WASM_ENABLE_AOT != 0
- #include "../aot/aot_runtime.h"
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #if WASM_ENABLE_AOT == 0
- typedef enum IntCond {
- INT_EQZ = 0,
- INT_EQ,
- INT_NE,
- INT_LT_S,
- INT_LT_U,
- INT_GT_S,
- INT_GT_U,
- INT_LE_S,
- INT_LE_U,
- INT_GE_S,
- INT_GE_U
- } IntCond;
- typedef enum FloatCond {
- FLOAT_EQ = 0,
- FLOAT_NE,
- FLOAT_LT,
- FLOAT_GT,
- FLOAT_LE,
- FLOAT_GE,
- FLOAT_UNO
- } FloatCond;
- #else
- #define IntCond AOTIntCond
- #define FloatCond AOTFloatCond
- #endif
- typedef enum IntArithmetic {
- INT_ADD = 0,
- INT_SUB,
- INT_MUL,
- INT_DIV_S,
- INT_DIV_U,
- INT_REM_S,
- INT_REM_U
- } IntArithmetic;
- typedef enum V128Arithmetic {
- V128_ADD = 0,
- V128_SUB,
- V128_MUL,
- V128_DIV,
- V128_NEG,
- V128_MIN,
- V128_MAX,
- } V128Arithmetic;
- typedef enum IntBitwise {
- INT_AND = 0,
- INT_OR,
- INT_XOR,
- } IntBitwise;
- typedef enum V128Bitwise {
- V128_NOT,
- V128_AND,
- V128_ANDNOT,
- V128_OR,
- V128_XOR,
- V128_BITSELECT,
- } V128Bitwise;
- typedef enum IntShift {
- INT_SHL = 0,
- INT_SHR_S,
- INT_SHR_U,
- INT_ROTL,
- INT_ROTR
- } IntShift;
- typedef enum FloatMath {
- FLOAT_ABS = 0,
- FLOAT_NEG,
- FLOAT_CEIL,
- FLOAT_FLOOR,
- FLOAT_TRUNC,
- FLOAT_NEAREST,
- FLOAT_SQRT
- } FloatMath;
- typedef enum FloatArithmetic {
- FLOAT_ADD = 0,
- FLOAT_SUB,
- FLOAT_MUL,
- FLOAT_DIV,
- FLOAT_MIN,
- FLOAT_MAX,
- } FloatArithmetic;
- #if WASM_ENABLE_SHARED_MEMORY != 0
- typedef enum AtomicRMWBinOp {
- AtomicRMWBinOpAdd,
- AtomicRMWBinOpSub,
- AtomicRMWBinOpAnd,
- AtomicRMWBinOpOr,
- AtomicRMWBinOpXor,
- AtomicRMWBinOpXchg
- } AtomicRMWBinOp;
- #endif
- /**
- * Translate instructions in a function. The translated block must
- * end with a branch instruction whose targets are offsets relating to
- * the end bcip of the translated block, which are integral constants.
- * If a target of a branch is really a constant value (which should be
- * rare), put it into a register and then jump to the register instead
- * of using the constant value directly in the target. In the
- * translation process, don't create any new labels. The code bcip of
- * the begin and end of the translated block is stored in the
- * jit_annl_begin_bcip and jit_annl_end_bcip annotations of the label
- * of the block, which must be the same as the bcips used in
- * profiling.
- *
- * NOTE: the function must explicitly set SP to correct value when the
- * entry's bcip is the function's entry address.
- *
- * @param cc containing compilation context of generated IR
- * @param entry entry of the basic block to be translated. If its
- * value is NULL, the function will clean up any pass local data that
- * might be created previously.
- * @param is_reached a bitmap recording which bytecode has been
- * reached as a block entry
- *
- * @return IR block containing translated instructions if succeeds,
- * NULL otherwise
- */
- JitBasicBlock *
- jit_frontend_translate_func(JitCompContext *cc);
- /**
- * Lower the IR of the given compilation context.
- *
- * @param cc the compilation context
- *
- * @return true if succeeds, false otherwise
- */
- bool
- jit_frontend_lower(JitCompContext *cc);
- uint32
- jit_frontend_get_jitted_return_addr_offset();
- uint32
- jit_frontend_get_global_data_offset(const WASMModule *module,
- uint32 global_idx);
- uint32
- jit_frontend_get_table_inst_offset(const WASMModule *module, uint32 tbl_idx);
- uint32
- jit_frontend_get_module_inst_extra_offset(const WASMModule *module);
- JitReg
- get_module_inst_reg(JitFrame *frame);
- JitReg
- get_module_reg(JitFrame *frame);
- JitReg
- get_import_func_ptrs_reg(JitFrame *frame);
- JitReg
- get_fast_jit_func_ptrs_reg(JitFrame *frame);
- JitReg
- get_func_type_indexes_reg(JitFrame *frame);
- JitReg
- get_aux_stack_bound_reg(JitFrame *frame);
- JitReg
- get_aux_stack_bottom_reg(JitFrame *frame);
- JitReg
- get_memory_inst_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_cur_page_count_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_memory_data_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_mem_bound_check_1byte_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_mem_bound_check_2bytes_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx);
- JitReg
- get_table_elems_reg(JitFrame *frame, uint32 table_idx);
- JitReg
- get_table_cur_size_reg(JitFrame *frame, uint32 table_idx);
- void
- clear_fixed_virtual_regs(JitFrame *frame);
- void
- clear_memory_regs(JitFrame *frame);
- void
- clear_table_regs(JitFrame *frame);
- /**
- * Get the offset from frame pointer to the n-th local variable slot.
- *
- * @param n the index to the local variable array
- *
- * @return the offset from frame pointer to the local variable slot
- */
- static inline unsigned
- offset_of_local(unsigned n)
- {
- return offsetof(WASMInterpFrame, lp) + n * 4;
- }
- /**
- * Generate instruction to load an integer from the frame.
- *
- * This and the below gen_load_X functions generate instructions to
- * load values from the frame into registers if the values have not
- * been loaded yet.
- *
- * @param frame the frame information
- * @param n slot index to the local variable array
- *
- * @return register holding the loaded value
- */
- JitReg
- gen_load_i32(JitFrame *frame, unsigned n);
- /**
- * Generate instruction to load a i64 integer from the frame.
- *
- * @param frame the frame information
- * @param n slot index to the local variable array
- *
- * @return register holding the loaded value
- */
- JitReg
- gen_load_i64(JitFrame *frame, unsigned n);
- /**
- * Generate instruction to load a floating point value from the frame.
- *
- * @param frame the frame information
- * @param n slot index to the local variable array
- *
- * @return register holding the loaded value
- */
- JitReg
- gen_load_f32(JitFrame *frame, unsigned n);
- /**
- * Generate instruction to load a double value from the frame.
- *
- * @param frame the frame information
- * @param n slot index to the local variable array
- *
- * @return register holding the loaded value
- */
- JitReg
- gen_load_f64(JitFrame *frame, unsigned n);
- /**
- * Generate instructions to commit computation result to the frame.
- * The general principle is to only commit values that will be used
- * through the frame.
- *
- * @param frame the frame information
- * @param begin the begin value slot to commit
- * @param end the end value slot to commit
- */
- void
- gen_commit_values(JitFrame *frame, JitValueSlot *begin, JitValueSlot *end);
- /**
- * Generate instructions to commit SP and IP pointers to the frame.
- *
- * @param frame the frame information
- */
- void
- gen_commit_sp_ip(JitFrame *frame);
- /**
- * Generate commit instructions for the block end.
- *
- * @param frame the frame information
- */
- static inline void
- gen_commit_for_branch(JitFrame *frame)
- {
- gen_commit_values(frame, frame->lp, frame->sp);
- }
- /**
- * Generate commit instructions for exception checks.
- *
- * @param frame the frame information
- */
- static inline void
- gen_commit_for_exception(JitFrame *frame)
- {
- gen_commit_values(frame, frame->lp, frame->lp + frame->max_locals);
- gen_commit_sp_ip(frame);
- }
- /**
- * Generate commit instructions to commit all status.
- *
- * @param frame the frame information
- */
- static inline void
- gen_commit_for_all(JitFrame *frame)
- {
- gen_commit_values(frame, frame->lp, frame->sp);
- gen_commit_sp_ip(frame);
- }
- static inline void
- clear_values(JitFrame *frame)
- {
- size_t total_size =
- sizeof(JitValueSlot) * (frame->max_locals + frame->max_stacks);
- memset(frame->lp, 0, total_size);
- frame->committed_sp = NULL;
- frame->committed_ip = NULL;
- clear_fixed_virtual_regs(frame);
- }
- static inline void
- push_i32(JitFrame *frame, JitReg value)
- {
- frame->sp->reg = value;
- frame->sp->dirty = 1;
- frame->sp++;
- }
- static inline void
- push_i64(JitFrame *frame, JitReg value)
- {
- frame->sp->reg = value;
- frame->sp->dirty = 1;
- frame->sp++;
- frame->sp->reg = value;
- frame->sp->dirty = 1;
- frame->sp++;
- }
- static inline void
- push_f32(JitFrame *frame, JitReg value)
- {
- push_i32(frame, value);
- }
- static inline void
- push_f64(JitFrame *frame, JitReg value)
- {
- push_i64(frame, value);
- }
- static inline JitReg
- pop_i32(JitFrame *frame)
- {
- frame->sp--;
- return gen_load_i32(frame, frame->sp - frame->lp);
- }
- static inline JitReg
- pop_i64(JitFrame *frame)
- {
- frame->sp -= 2;
- return gen_load_i64(frame, frame->sp - frame->lp);
- }
- static inline JitReg
- pop_f32(JitFrame *frame)
- {
- frame->sp--;
- return gen_load_f32(frame, frame->sp - frame->lp);
- }
- static inline JitReg
- pop_f64(JitFrame *frame)
- {
- frame->sp -= 2;
- return gen_load_f64(frame, frame->sp - frame->lp);
- }
- static inline void
- pop(JitFrame *frame, int n)
- {
- frame->sp -= n;
- memset(frame->sp, 0, n * sizeof(*frame->sp));
- }
- static inline JitReg
- local_i32(JitFrame *frame, int n)
- {
- return gen_load_i32(frame, n);
- }
- static inline JitReg
- local_i64(JitFrame *frame, int n)
- {
- return gen_load_i64(frame, n);
- }
- static inline JitReg
- local_f32(JitFrame *frame, int n)
- {
- return gen_load_f32(frame, n);
- }
- static inline JitReg
- local_f64(JitFrame *frame, int n)
- {
- return gen_load_f64(frame, n);
- }
- static void
- set_local_i32(JitFrame *frame, int n, JitReg val)
- {
- frame->lp[n].reg = val;
- frame->lp[n].dirty = 1;
- }
- static void
- set_local_i64(JitFrame *frame, int n, JitReg val)
- {
- frame->lp[n].reg = val;
- frame->lp[n].dirty = 1;
- frame->lp[n + 1].reg = val;
- frame->lp[n + 1].dirty = 1;
- }
- static inline void
- set_local_f32(JitFrame *frame, int n, JitReg val)
- {
- set_local_i32(frame, n, val);
- }
- static inline void
- set_local_f64(JitFrame *frame, int n, JitReg val)
- {
- set_local_i64(frame, n, val);
- }
- #define POP(jit_value, value_type) \
- do { \
- if (!jit_cc_pop_value(cc, value_type, &jit_value)) \
- goto fail; \
- } while (0)
- #define POP_I32(v) POP(v, VALUE_TYPE_I32)
- #define POP_I64(v) POP(v, VALUE_TYPE_I64)
- #define POP_F32(v) POP(v, VALUE_TYPE_F32)
- #define POP_F64(v) POP(v, VALUE_TYPE_F64)
- #define POP_FUNCREF(v) POP(v, VALUE_TYPE_FUNCREF)
- #define POP_EXTERNREF(v) POP(v, VALUE_TYPE_EXTERNREF)
- #define PUSH(jit_value, value_type) \
- do { \
- if (!jit_value) \
- goto fail; \
- if (!jit_cc_push_value(cc, value_type, jit_value)) \
- goto fail; \
- } while (0)
- #define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32)
- #define PUSH_I64(v) PUSH(v, VALUE_TYPE_I64)
- #define PUSH_F32(v) PUSH(v, VALUE_TYPE_F32)
- #define PUSH_F64(v) PUSH(v, VALUE_TYPE_F64)
- #define PUSH_FUNCREF(v) PUSH(v, VALUE_TYPE_FUNCREF)
- #define PUSH_EXTERNREF(v) PUSH(v, VALUE_TYPE_EXTERNREF)
- #ifdef __cplusplus
- }
- #endif
- #endif
|