| open Types |
| open Values |
| |
| |
| (* Int operators *) |
| |
| module IntOp (IXX : Ixx.S) (Num : NumType with type t = IXX.t) = |
| struct |
| open Ast.IntOp |
| open Num |
| |
| let unop op = |
| let f = match op with |
| | Clz -> IXX.clz |
| | Ctz -> IXX.ctz |
| | Popcnt -> IXX.popcnt |
| | ExtendS sz -> IXX.extend_s (8 * packed_size sz) |
| in fun v -> to_num (f (of_num 1 v)) |
| |
| let binop op = |
| let f = match op with |
| | Add -> IXX.add |
| | Sub -> IXX.sub |
| | Mul -> IXX.mul |
| | DivS -> IXX.div_s |
| | DivU -> IXX.div_u |
| | RemS -> IXX.rem_s |
| | RemU -> IXX.rem_u |
| | And -> IXX.and_ |
| | Or -> IXX.or_ |
| | Xor -> IXX.xor |
| | Shl -> IXX.shl |
| | ShrU -> IXX.shr_u |
| | ShrS -> IXX.shr_s |
| | Rotl -> IXX.rotl |
| | Rotr -> IXX.rotr |
| in fun v1 v2 -> to_num (f (of_num 1 v1) (of_num 2 v2)) |
| |
| let testop op = |
| let f = match op with |
| | Eqz -> IXX.eqz |
| in fun v -> f (of_num 1 v) |
| |
| let relop op = |
| let f = match op with |
| | Eq -> IXX.eq |
| | Ne -> IXX.ne |
| | LtS -> IXX.lt_s |
| | LtU -> IXX.lt_u |
| | LeS -> IXX.le_s |
| | LeU -> IXX.le_u |
| | GtS -> IXX.gt_s |
| | GtU -> IXX.gt_u |
| | GeS -> IXX.ge_s |
| | GeU -> IXX.ge_u |
| in fun v1 v2 -> f (of_num 1 v1) (of_num 2 v2) |
| end |
| |
| module I32Op = IntOp (I32) (I32Num) |
| module I64Op = IntOp (I64) (I64Num) |
| |
| |
| (* Float operators *) |
| |
| module FloatOp (FXX : Fxx.S) (Num : NumType with type t = FXX.t) = |
| struct |
| open Ast.FloatOp |
| open Num |
| |
| let unop op = |
| let f = match op with |
| | Neg -> FXX.neg |
| | Abs -> FXX.abs |
| | Sqrt -> FXX.sqrt |
| | Ceil -> FXX.ceil |
| | Floor -> FXX.floor |
| | Trunc -> FXX.trunc |
| | Nearest -> FXX.nearest |
| in fun v -> to_num (f (of_num 1 v)) |
| |
| let binop op = |
| let f = match op with |
| | Add -> FXX.add |
| | Sub -> FXX.sub |
| | Mul -> FXX.mul |
| | Div -> FXX.div |
| | Min -> FXX.min |
| | Max -> FXX.max |
| | CopySign -> FXX.copysign |
| in fun v1 v2 -> to_num (f (of_num 1 v1) (of_num 2 v2)) |
| |
| let testop op = assert false |
| |
| let relop op = |
| let f = match op with |
| | Eq -> FXX.eq |
| | Ne -> FXX.ne |
| | Lt -> FXX.lt |
| | Le -> FXX.le |
| | Gt -> FXX.gt |
| | Ge -> FXX.ge |
| in fun v1 v2 -> f (of_num 1 v1) (of_num 2 v2) |
| end |
| |
| module F32Op = FloatOp (F32) (F32Num) |
| module F64Op = FloatOp (F64) (F64Num) |
| |
| |
| (* Conversion operators *) |
| |
| module I32CvtOp = |
| struct |
| open Ast.IntOp |
| |
| let cvtop op v = |
| let i = match op with |
| | WrapI64 -> I32_convert.wrap_i64 (I64Num.of_num 1 v) |
| | TruncUF32 -> I32_convert.trunc_f32_u (F32Num.of_num 1 v) |
| | TruncSF32 -> I32_convert.trunc_f32_s (F32Num.of_num 1 v) |
| | TruncUF64 -> I32_convert.trunc_f64_u (F64Num.of_num 1 v) |
| | TruncSF64 -> I32_convert.trunc_f64_s (F64Num.of_num 1 v) |
| | TruncSatUF32 -> I32_convert.trunc_sat_f32_u (F32Num.of_num 1 v) |
| | TruncSatSF32 -> I32_convert.trunc_sat_f32_s (F32Num.of_num 1 v) |
| | TruncSatUF64 -> I32_convert.trunc_sat_f64_u (F64Num.of_num 1 v) |
| | TruncSatSF64 -> I32_convert.trunc_sat_f64_s (F64Num.of_num 1 v) |
| | ReinterpretFloat -> I32_convert.reinterpret_f32 (F32Num.of_num 1 v) |
| | ExtendUI32 -> raise (TypeError (1, v, I32Type)) |
| | ExtendSI32 -> raise (TypeError (1, v, I32Type)) |
| in I32Num.to_num i |
| end |
| |
| module I64CvtOp = |
| struct |
| open Ast.IntOp |
| |
| let cvtop op v = |
| let i = match op with |
| | ExtendUI32 -> I64_convert.extend_i32_u (I32Num.of_num 1 v) |
| | ExtendSI32 -> I64_convert.extend_i32_s (I32Num.of_num 1 v) |
| | TruncUF32 -> I64_convert.trunc_f32_u (F32Num.of_num 1 v) |
| | TruncSF32 -> I64_convert.trunc_f32_s (F32Num.of_num 1 v) |
| | TruncUF64 -> I64_convert.trunc_f64_u (F64Num.of_num 1 v) |
| | TruncSF64 -> I64_convert.trunc_f64_s (F64Num.of_num 1 v) |
| | TruncSatUF32 -> I64_convert.trunc_sat_f32_u (F32Num.of_num 1 v) |
| | TruncSatSF32 -> I64_convert.trunc_sat_f32_s (F32Num.of_num 1 v) |
| | TruncSatUF64 -> I64_convert.trunc_sat_f64_u (F64Num.of_num 1 v) |
| | TruncSatSF64 -> I64_convert.trunc_sat_f64_s (F64Num.of_num 1 v) |
| | ReinterpretFloat -> I64_convert.reinterpret_f64 (F64Num.of_num 1 v) |
| | WrapI64 -> raise (TypeError (1, v, I64Type)) |
| in I64Num.to_num i |
| end |
| |
| module F32CvtOp = |
| struct |
| open Ast.FloatOp |
| |
| let cvtop op v = |
| let z = match op with |
| | DemoteF64 -> F32_convert.demote_f64 (F64Num.of_num 1 v) |
| | ConvertSI32 -> F32_convert.convert_i32_s (I32Num.of_num 1 v) |
| | ConvertUI32 -> F32_convert.convert_i32_u (I32Num.of_num 1 v) |
| | ConvertSI64 -> F32_convert.convert_i64_s (I64Num.of_num 1 v) |
| | ConvertUI64 -> F32_convert.convert_i64_u (I64Num.of_num 1 v) |
| | ReinterpretInt -> F32_convert.reinterpret_i32 (I32Num.of_num 1 v) |
| | PromoteF32 -> raise (TypeError (1, v, F32Type)) |
| in F32Num.to_num z |
| end |
| |
| module F64CvtOp = |
| struct |
| open Ast.FloatOp |
| |
| let cvtop op v = |
| let z = match op with |
| | PromoteF32 -> F64_convert.promote_f32 (F32Num.of_num 1 v) |
| | ConvertSI32 -> F64_convert.convert_i32_s (I32Num.of_num 1 v) |
| | ConvertUI32 -> F64_convert.convert_i32_u (I32Num.of_num 1 v) |
| | ConvertSI64 -> F64_convert.convert_i64_s (I64Num.of_num 1 v) |
| | ConvertUI64 -> F64_convert.convert_i64_u (I64Num.of_num 1 v) |
| | ReinterpretInt -> F64_convert.reinterpret_i64 (I64Num.of_num 1 v) |
| | DemoteF64 -> raise (TypeError (1, v, F64Type)) |
| in F64Num.to_num z |
| end |
| |
| (* Dispatch *) |
| |
| let op i32 i64 f32 f64 = function |
| | I32 x -> i32 x |
| | I64 x -> i64 x |
| | F32 x -> f32 x |
| | F64 x -> f64 x |
| |
| let eval_unop = op I32Op.unop I64Op.unop F32Op.unop F64Op.unop |
| let eval_binop = op I32Op.binop I64Op.binop F32Op.binop F64Op.binop |
| let eval_testop = op I32Op.testop I64Op.testop F32Op.testop F64Op.testop |
| let eval_relop = op I32Op.relop I64Op.relop F32Op.relop F64Op.relop |
| let eval_cvtop = op I32CvtOp.cvtop I64CvtOp.cvtop F32CvtOp.cvtop F64CvtOp.cvtop |
| |