diff options
-rw-r--r-- | sarcasm.asd | 12 | ||||
-rw-r--r-- | src/ast.lisp | 90 | ||||
-rw-r--r-- | src/instr.lisp | 49 | ||||
-rw-r--r-- | src/raw-instrs.lisp | 498 | ||||
-rw-r--r-- | src/util.lisp | 84 |
5 files changed, 733 insertions, 0 deletions
diff --git a/sarcasm.asd b/sarcasm.asd new file mode 100644 index 0000000..dc8b4e8 --- /dev/null +++ b/sarcasm.asd @@ -0,0 +1,12 @@ +;;;; sarcasm.asd + +(asdf:defsystem #:sarcasm + :description "WASM runtime in Common Lisp" + :author "Colin <colin@cicadas.surf>" + :license "GPL3" + :version "0.0.1" + :depends-on (#:alexandria #:yacc) + :pathname "src/" + :serial t + :components ((:file "util") + (:file "ast"))) diff --git a/src/ast.lisp b/src/ast.lisp new file mode 100644 index 0000000..eef5c05 --- /dev/null +++ b/src/ast.lisp @@ -0,0 +1,90 @@ +(defpackage #:sarcasm.ast + (:use #:cl) + (:import-from #:sarcasm.util #:def/class) + (:local-nicknames + (#:a #:alexandria-2) + (#:util #:sarcasm.util))) + +(in-package #:sarcasm.ast) + +;;; TYPES + + + +(deftype i32 () + '(integer 0 #.(expt 2 32))) + +(deftype i64 () + '(integer 0 #. (expt 2 64))) + +(deftype f32 () + 'single-float) + +(deftype f64 () + 'double-float) + +(deftype numtype () + '(or i32 i64 f32 f64)) + +(deftype typeidx () + 'i32) + +(deftype vectype () + '(bit-vector 128)) + +(deftype funcref () + 't) + +(deftype externref () + 't) + +(deftype reftype () + '(or funcref externref)) + +(deftype valtype () + '(or numtype vectype reftype)) + +(defun stack-effect-type-p (thing) + "A stack effect type is a two element list of lists of keywords. + +It describes the types of values consumed off the stack and returned +to the stack by instructions." + (and (listp thing) + (= 2 (length thing)) + (listp (first thing)) + (listp (second thing)) + (every #'keywordp (first thing)) + (every #'keywordp (second thing)))) + +(deftype stack-effect-type () + "This is not part of the standard grammar, but appears implicitly in +the WASM table of instructions found + + https://webassembly.github.io/spec/core/appendix/index-instructions.html + +In the `Type` column." + '(satisfies stack-effect-type-p)) + +;;; MODULE-STRUCTURES + +(def/class instr () + ((name :prefix :type keyword) + (code :prefix :type (vector byte)) + (type :prefix :type stack-effect-type))) + +(def/class numeric-instr (instr)) + +(def/class func () + (type :prefix :type typeidx) + (locals :type (vector valtype)) + (body :prefix :type expr)) + +;;; MODULES + +(def/class module () + (types funcs tables mems globals elems datas imports exports + :type vector :initform (vector)) + (start :type (or null t) ; TODO: what is this value type? + :initform nil)) + + diff --git a/src/instr.lisp b/src/instr.lisp new file mode 100644 index 0000000..a5c94c6 --- /dev/null +++ b/src/instr.lisp @@ -0,0 +1,49 @@ +(defpackage #:sarcasm.instr + (:use #:cl) + (:shadow cl:return cl:if cl:block cl:loop cl:t) + (:local-nicknames + (#:a #:alexandria-2))) + +(in-package #:sarcasm.instr) + +(defclass instr () ()) + +(eval-when (:compile-toplevel :load-toplevel :execute) + (defun expand-instr-plist (plist) + (destructuring-bind (&key instr code type) plist + (let* ((class-name + (intern (string-upcase (first instr)))) + (immediates + (cl:loop + :for arg :in (rest instr) + :for slot-name := (intern (string-upcase arg)) + :for reader := (intern (format nil "~a-~a" class-name slot-name)) + :for initarg := (a:make-keyword slot-name) + :collect `(,slot-name + :reader ,reader + :initarg ,initarg + :initform (error "~a required" ',slot-name))))) + `(defclass ,class-name (instr) + ((instr-name + :allocation :class + :type string + :initform ,(first instr) + :reader instr-name) + (instr-code + :allocation :class + :type (vector (unsigned-byte 8) ,(length code)) + :initform (make-array ,(length code) + :element-type '(unsigned-byte 8) + :initial-contents ',code)) + (instr-type + :allocation :class + :type t + :initform ',type) + ,@immediates)))))) + +(macrolet ((create-instr-classes (raw) + `(progn + ,@(mapcar #'expand-instr-plist raw)))) + (create-instr-classes #.sarcasm.raw-instrs:raw-instrs)) + + diff --git a/src/raw-instrs.lisp b/src/raw-instrs.lisp new file mode 100644 index 0000000..bdbde12 --- /dev/null +++ b/src/raw-instrs.lisp @@ -0,0 +1,498 @@ +(defpackage #:sarcasm.raw-instrs + (:use :cl) + (:export #:raw-instrs)) + +(in-package #:sarcasm.raw-instrs) +(defparameter raw-instrs + '((:INSTR ("unreachable") :CODE (0) :TYPE ((:|t1*|) (:|t2*|))) + (:INSTR ("nop") :CODE (1) :TYPE (NIL NIL)) + (:INSTR ("block" "Xbt") :CODE (2) :TYPE ((:|t1*|) (:|t2*|))) + (:INSTR ("loop" "Xbt") :CODE (3) :TYPE ((:|t1*|) (:|t2*|))) + (:INSTR ("if" "Xbt") :CODE (4) :TYPE ((:|t1*| :I32) (:|t2*|))) + (:INSTR ("else") :CODE NIL :TYPE NIL) (:INSTR ("end") :CODE NIL :TYPE NIL) + (:INSTR ("br" "l") :CODE (12) :TYPE ((:|t1*| :|t*|) (:|t2*|))) + (:INSTR ("brif" "l") :CODE (13) :TYPE ((:|t*| :I32) (:|t*|))) + (:INSTR ("brtable" "l^*" "l") :CODE (14) :TYPE ((:|t1*| :|t*| :I32) (:|t2*|))) + (:INSTR ("return") :CODE (15) :TYPE ((:|t1*| :|t*|) (:|t2*|))) + (:INSTR ("call" "x") :CODE (16) :TYPE ((:|t1*|) (:|t2*|))) + (:INSTR ("callindirect" "x" "y") :CODE (17) :TYPE ((:|t1*| :I32) (:|t2*|))) + (:INSTR ("drop") :CODE (26) :TYPE ((:|t|) NIL)) + (:INSTR ("select") :CODE (27) :TYPE ((:|t| :|t| :I32) (:|t|))) + (:INSTR ("select" "t") :CODE (28) :TYPE ((:|t| :|t| :I32) (:|t|))) + (:INSTR ("local.get" "x") :CODE (32) :TYPE (NIL (:|t|))) + (:INSTR ("local.set" "x") :CODE (33) :TYPE ((:|t|) NIL)) + (:INSTR ("local.tee" "x") :CODE (34) :TYPE ((:|t|) (:|t|))) + (:INSTR ("global.get" "x") :CODE (35) :TYPE (NIL (:|t|))) + (:INSTR ("global.set" "x") :CODE (36) :TYPE ((:|t|) NIL)) + (:INSTR ("table.get" "x") :CODE (37) :TYPE ((:I32) (:|t|))) + (:INSTR ("table.set" "x") :CODE (38) :TYPE ((:I32 :|t|) NIL)) + (:INSTR ("i32.load" "memarg") :CODE (40) :TYPE ((:I32) (:I32))) + (:INSTR ("i64.load" "memarg") :CODE (41) :TYPE ((:I32) (:I64))) + (:INSTR ("f32.load" "memarg") :CODE (42) :TYPE ((:I32) (:F32))) + (:INSTR ("f64.load" "memarg") :CODE (43) :TYPE ((:I32) (:F64))) + (:INSTR ("i32.load8_s" "memarg") :CODE (44) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.load8_u" "memarg") :CODE (45) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.load16_s" "memarg") :CODE (46) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.load16_u" "memarg") :CODE (47) :TYPE ((:I32) (:I32))) + (:INSTR ("i64.load8_s" "memarg") :CODE (48) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.load8_u" "memarg") :CODE (49) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.load16_s" "memarg") :CODE (50) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.load16_u" "memarg") :CODE (51) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.load32_s" "memarg") :CODE (52) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.load32_u" "memarg") :CODE (53) :TYPE ((:I32) (:I64))) + (:INSTR ("i32.store" "memarg") :CODE (54) :TYPE ((:I32 :I32) NIL)) + (:INSTR ("i64.store" "memarg") :CODE (55) :TYPE ((:I32 :I64) NIL)) + (:INSTR ("f32.store" "memarg") :CODE (56) :TYPE ((:I32 :F32) NIL)) + (:INSTR ("f64.store" "memarg") :CODE (57) :TYPE ((:I32 :F64) NIL)) + (:INSTR ("i32.store8" "memarg") :CODE (58) :TYPE ((:I32 :I32) NIL)) + (:INSTR ("i32.store16" "memarg") :CODE (59) :TYPE ((:I32 :I32) NIL)) + (:INSTR ("i64.store8" "memarg") :CODE (60) :TYPE ((:I32 :I64) NIL)) + (:INSTR ("i64.store16" "memarg") :CODE (61) :TYPE ((:I32 :I64) NIL)) + (:INSTR ("i64.store32" "memarg") :CODE (62) :TYPE ((:I32 :I64) NIL)) + (:INSTR ("memory.size") :CODE (63) :TYPE (NIL (:I32))) + (:INSTR ("memory.grow") :CODE (64) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.const" "i32") :CODE (65) :TYPE (NIL (:I32))) + (:INSTR ("i64.const" "i64") :CODE (66) :TYPE (NIL (:I64))) + (:INSTR ("f32.const" "f32") :CODE (67) :TYPE (NIL (:F32))) + (:INSTR ("f64.const" "f64") :CODE (68) :TYPE (NIL (:F64))) + (:INSTR ("i32.eqz") :CODE (69) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.eq") :CODE (70) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.ne") :CODE (71) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.lt_s") :CODE (72) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.lt_u") :CODE (73) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.gt_s") :CODE (74) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.gt_u") :CODE (75) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.le_s") :CODE (76) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.le_u") :CODE (77) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.ge_s") :CODE (78) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.ge_u") :CODE (79) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i64.eqz") :CODE (80) :TYPE ((:I64) (:I32))) + (:INSTR ("i64.eq") :CODE (81) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.ne") :CODE (82) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.lt_s") :CODE (83) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.lt_u") :CODE (84) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.gt_s") :CODE (85) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.gt_u") :CODE (86) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.le_s") :CODE (87) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.le_u") :CODE (88) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.ge_s") :CODE (89) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("i64.ge_u") :CODE (90) :TYPE ((:I64 :I64) (:I32))) + (:INSTR ("f32.eq") :CODE (91) :TYPE ((:F32 :F32) (:I32))) + (:INSTR ("f32.ne") :CODE (92) :TYPE ((:F32 :F32) (:I32))) + (:INSTR ("f32.lt") :CODE (93) :TYPE ((:F32 :F32) (:I32))) + (:INSTR ("f32.gt") :CODE (94) :TYPE ((:F32 :F32) (:I32))) + (:INSTR ("f32.le") :CODE (95) :TYPE ((:F32 :F32) (:I32))) + (:INSTR ("f32.ge") :CODE (96) :TYPE ((:F32 :F32) (:I32))) + (:INSTR ("f64.eq") :CODE (97) :TYPE ((:F64 :F64) (:I32))) + (:INSTR ("f64.ne") :CODE (98) :TYPE ((:F64 :F64) (:I32))) + (:INSTR ("f64.lt") :CODE (99) :TYPE ((:F64 :F64) (:I32))) + (:INSTR ("f64.gt") :CODE (100) :TYPE ((:F64 :F64) (:I32))) + (:INSTR ("f64.le") :CODE (101) :TYPE ((:F64 :F64) (:I32))) + (:INSTR ("f64.ge") :CODE (102) :TYPE ((:F64 :F64) (:I32))) + (:INSTR ("i32.clz") :CODE (103) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.ctz") :CODE (104) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.popcnt") :CODE (105) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.add") :CODE (106) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.sub") :CODE (107) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.mul") :CODE (108) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.div_s") :CODE (109) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.div_u") :CODE (110) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.rem_s") :CODE (111) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.rem_u") :CODE (112) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.and") :CODE (113) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.or") :CODE (114) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.xor") :CODE (115) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.shl") :CODE (116) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.shr_s") :CODE (117) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.shr_u") :CODE (118) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.rotl") :CODE (119) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i32.rotr") :CODE (120) :TYPE ((:I32 :I32) (:I32))) + (:INSTR ("i64.clz") :CODE (121) :TYPE ((:I64) (:I64))) + (:INSTR ("i64.ctz") :CODE (122) :TYPE ((:I64) (:I64))) + (:INSTR ("i64.popcnt") :CODE (123) :TYPE ((:I64) (:I64))) + (:INSTR ("i64.add") :CODE (124) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.sub") :CODE (125) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.mul") :CODE (126) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.div_s") :CODE (127) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.div_u") :CODE (128) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.rem_s") :CODE (129) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.rem_u") :CODE (130) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.and") :CODE (131) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.or") :CODE (132) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.xor") :CODE (133) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.shl") :CODE (134) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.shr_s") :CODE (135) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.shr_u") :CODE (136) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.rotl") :CODE (137) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("i64.rotr") :CODE (138) :TYPE ((:I64 :I64) (:I64))) + (:INSTR ("f32.abs") :CODE (139) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.neg") :CODE (140) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.ceil") :CODE (141) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.floor") :CODE (142) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.trunc") :CODE (143) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.nearest") :CODE (144) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.sqrt") :CODE (145) :TYPE ((:F32) (:F32))) + (:INSTR ("f32.add") :CODE (146) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f32.sub") :CODE (147) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f32.mul") :CODE (148) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f32.div") :CODE (149) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f32.fmin") :CODE (150) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f32.fmax") :CODE (151) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f32.copysign") :CODE (152) :TYPE ((:F32 :F32) (:F32))) + (:INSTR ("f64.abs") :CODE (153) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.neg") :CODE (154) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.ceil") :CODE (155) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.floor") :CODE (156) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.trunc") :CODE (157) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.nearest") :CODE (158) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.sqrt") :CODE (159) :TYPE ((:F64) (:F64))) + (:INSTR ("f64.add") :CODE (160) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("f64.sub") :CODE (161) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("f64.mul") :CODE (162) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("f64.div") :CODE (163) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("f64.fmin") :CODE (164) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("f64.fmax") :CODE (165) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("f64.copysign") :CODE (166) :TYPE ((:F64 :F64) (:F64))) + (:INSTR ("i32.wrap_i64") :CODE (167) :TYPE ((:I64) (:I32))) + (:INSTR ("i32.trunc_f32k_s") :CODE (168) :TYPE ((:F32) (:I32))) + (:INSTR ("i32.trunc_f32k_u") :CODE (169) :TYPE ((:F32) (:I32))) + (:INSTR ("i32.trunc_f64k_s") :CODE (170) :TYPE ((:F64) (:I32))) + (:INSTR ("i32.trunc_f64k_u") :CODE (171) :TYPE ((:F64) (:I32))) + (:INSTR ("i64.extend_i32k_s") :CODE (172) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.extend_i32k_u") :CODE (173) :TYPE ((:I32) (:I64))) + (:INSTR ("i64.trunc_f32k_s") :CODE (174) :TYPE ((:F32) (:I64))) + (:INSTR ("i64.trunc_f32k_u") :CODE (175) :TYPE ((:F32) (:I64))) + (:INSTR ("i64.trunc_f64k_s") :CODE (176) :TYPE ((:F64) (:I64))) + (:INSTR ("i64.trunc_f64k_u") :CODE (177) :TYPE ((:F64) (:I64))) + (:INSTR ("f32.convert_i32k_s") :CODE (178) :TYPE ((:I32) (:F32))) + (:INSTR ("f32.convert_i32k_u") :CODE (179) :TYPE ((:I32) (:F32))) + (:INSTR ("f32.convert_i64k_s") :CODE (180) :TYPE ((:I64) (:F32))) + (:INSTR ("f32.convert_i64k_u") :CODE (181) :TYPE ((:I64) (:F32))) + (:INSTR ("f32.demote_f64") :CODE (182) :TYPE ((:F64) (:F32))) + (:INSTR ("f64.convert_i32k_s") :CODE (183) :TYPE ((:I32) (:F64))) + (:INSTR ("f64.convert_i32k_u") :CODE (184) :TYPE ((:I32) (:F64))) + (:INSTR ("f64.convert_i64k_s") :CODE (185) :TYPE ((:I64) (:F64))) + (:INSTR ("f64.convert_i64k_u") :CODE (186) :TYPE ((:I64) (:F64))) + (:INSTR ("f64.promote_f32") :CODE (187) :TYPE ((:F32) (:F64))) + (:INSTR ("i32.reinterpret_f32") :CODE (188) :TYPE ((:F32) (:I32))) + (:INSTR ("i64.reinterpret_f64") :CODE (189) :TYPE ((:F64) (:I64))) + (:INSTR ("f32.reinterpret_i32") :CODE (190) :TYPE ((:I32) (:F32))) + (:INSTR ("f64.reinterpret_i64") :CODE (191) :TYPE ((:I64) (:F64))) + (:INSTR ("i32.extend8_s") :CODE (192) :TYPE ((:I32) (:I32))) + (:INSTR ("i32.extend16_s") :CODE (193) :TYPE ((:I32) (:I32))) + (:INSTR ("i64.extend8_s") :CODE (194) :TYPE ((:I64) (:I64))) + (:INSTR ("i64.extend16_s") :CODE (195) :TYPE ((:I64) (:I64))) + (:INSTR ("i64.extend32_s") :CODE (196) :TYPE ((:I64) (:I64))) + (:INSTR ("ref.null" "t") :CODE (208) :TYPE (NIL (:|t|))) + (:INSTR ("ref.isnull") :CODE (209) :TYPE ((:|t|) (:I32))) + (:INSTR ("ref.func" "x") :CODE (210) :TYPE (NIL (:FUNCREF))) + (:INSTR ("i32.trunc_sat_f32k_s") :CODE (252 0) :TYPE ((:F32) (:I32))) + (:INSTR ("i32.trunc_sat_f32k_u") :CODE (252 1) :TYPE ((:F32) (:I32))) + (:INSTR ("i32.trunc_sat_f64k_s") :CODE (252 2) :TYPE ((:F64) (:I32))) + (:INSTR ("i32.trunc_sat_f64k_u") :CODE (252 3) :TYPE ((:F64) (:I32))) + (:INSTR ("i64.trunc_sat_f32k_s") :CODE (252 4) :TYPE ((:F32) (:I64))) + (:INSTR ("i64.trunc_sat_f32k_u") :CODE (252 5) :TYPE ((:F32) (:I64))) + (:INSTR ("i64.trunc_sat_f64k_s") :CODE (252 6) :TYPE ((:F64) (:I64))) + (:INSTR ("i64.trunc_sat_f64k_u") :CODE (252 7) :TYPE ((:F64) (:I64))) + (:INSTR ("memory.init" "x") :CODE (252 8) :TYPE ((:I32 :I32 :I32) NIL)) + (:INSTR ("data.drop" "x") :CODE (252 9) :TYPE (NIL NIL)) + (:INSTR ("memory.copy") :CODE (252 10) :TYPE ((:I32 :I32 :I32) NIL)) + (:INSTR ("memory.fill") :CODE (252 11) :TYPE ((:I32 :I32 :I32) NIL)) + (:INSTR ("table.init" "x" "y") :CODE (252 12) :TYPE ((:I32 :I32 :I32) NIL)) + (:INSTR ("elem.drop" "x") :CODE (252 13) :TYPE (NIL NIL)) + (:INSTR ("table.copy" "x" "y") :CODE (252 14) :TYPE ((:I32 :I32 :I32) NIL)) + (:INSTR ("table.grow" "x") :CODE (252 15) :TYPE ((:|t| :I32) (:I32))) + (:INSTR ("table.size" "x") :CODE (252 16) :TYPE (NIL (:I32))) + (:INSTR ("table.fill" "x") :CODE (252 17) :TYPE ((:I32 :|t| :I32) NIL)) + (:INSTR ("v128.load" "memarg") :CODE (253 0) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load8x8_s" "memarg") :CODE (253 1) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load8x8_u" "memarg") :CODE (253 2) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load16x4_s" "memarg") :CODE (253 3) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load16x4_u" "memarg") :CODE (253 4) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load32x2_s" "memarg") :CODE (253 5) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load32x2_u" "memarg") :CODE (253 6) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load8_splat" "memarg") :CODE (253 7) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load16_splat" "memarg") :CODE (253 8) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load32_splat" "memarg") :CODE (253 9) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load64_splat" "memarg") :CODE (253 10) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.store" "memarg") :CODE (253 11) :TYPE ((:I32 :V128) NIL)) + (:INSTR ("v128.vconst" "i128") :CODE (253 12) :TYPE (NIL (:V128))) + (:INSTR ("i8x16.shuffle" "laneidx^16") :CODE (253 13) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.swizzle") :CODE (253 14) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.splat") :CODE (253 15) :TYPE ((:I32) (:V128))) + (:INSTR ("i16x8.splat") :CODE (253 16) :TYPE ((:I32) (:V128))) + (:INSTR ("i32x4.splat") :CODE (253 17) :TYPE ((:I32) (:V128))) + (:INSTR ("i64x2.splat") :CODE (253 18) :TYPE ((:I64) (:V128))) + (:INSTR ("f32x4.splat") :CODE (253 19) :TYPE ((:F32) (:V128))) + (:INSTR ("f64x2.splat") :CODE (253 20) :TYPE ((:F64) (:V128))) + (:INSTR ("i8x16.extractlane_s" "laneidx") :CODE (253 21) :TYPE + ((:V128) (:I32))) + (:INSTR ("i8x16.extractlane_u" "laneidx") :CODE (253 22) :TYPE + ((:V128) (:I32))) + (:INSTR ("i8x16.replacelane" "laneidx") :CODE (253 23) :TYPE + ((:V128 :I32) (:V128))) + (:INSTR ("i16x8.extractlane_s" "laneidx") :CODE (253 24) :TYPE + ((:V128) (:I32))) + (:INSTR ("i16x8.extractlane_u" "laneidx") :CODE (253 25) :TYPE + ((:V128) (:I32))) + (:INSTR ("i16x8.replacelane" "laneidx") :CODE (253 26) :TYPE + ((:V128 :I32) (:V128))) + (:INSTR ("i32x4.extractlane" "laneidx") :CODE (253 27) :TYPE ((:V128) (:I32))) + (:INSTR ("i32x4.replacelane" "laneidx") :CODE (253 28) :TYPE + ((:V128 :I32) (:V128))) + (:INSTR ("i64x2.extractlane" "laneidx") :CODE (253 29) :TYPE ((:V128) (:I64))) + (:INSTR ("i64x2.replacelane" "laneidx") :CODE (253 30) :TYPE + ((:V128 :I64) (:V128))) + (:INSTR ("f32x4.extractlane" "laneidx") :CODE (253 31) :TYPE ((:V128) (:F32))) + (:INSTR ("f32x4.replacelane" "laneidx") :CODE (253 32) :TYPE + ((:V128 :F32) (:V128))) + (:INSTR ("f64x2.extractlane" "laneidx") :CODE (253 33) :TYPE ((:V128) (:F64))) + (:INSTR ("f64x2.replacelane" "laneidx") :CODE (253 34) :TYPE + ((:V128 :F64) (:V128))) + (:INSTR ("i8x16.veq") :CODE (253 35) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vne") :CODE (253 36) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vlt_s") :CODE (253 37) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vlt_u") :CODE (253 38) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vgt_s") :CODE (253 39) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vgt_u") :CODE (253 40) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vle_s") :CODE (253 41) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vle_u") :CODE (253 42) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vge_s") :CODE (253 43) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vge_u") :CODE (253 44) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.veq") :CODE (253 45) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vne") :CODE (253 46) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vlt_s") :CODE (253 47) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vlt_u") :CODE (253 48) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vgt_s") :CODE (253 49) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vgt_u") :CODE (253 50) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vle_s") :CODE (253 51) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vle_u") :CODE (253 52) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vge_s") :CODE (253 53) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vge_u") :CODE (253 54) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.veq") :CODE (253 55) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vne") :CODE (253 56) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vlt_s") :CODE (253 57) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vlt_u") :CODE (253 58) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vgt_s") :CODE (253 59) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vgt_u") :CODE (253 60) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vle_s") :CODE (253 61) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vle_u") :CODE (253 62) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vge_s") :CODE (253 63) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vge_u") :CODE (253 64) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.veq") :CODE (253 65) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vne") :CODE (253 66) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vlt") :CODE (253 67) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vgt") :CODE (253 68) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vle") :CODE (253 69) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vge") :CODE (253 70) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.veq") :CODE (253 71) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vne") :CODE (253 72) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vlt") :CODE (253 73) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vgt") :CODE (253 74) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vle") :CODE (253 75) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vge") :CODE (253 76) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("v128.vnot") :CODE (253 77) :TYPE ((:V128) (:V128))) + (:INSTR ("v128.vand") :CODE (253 78) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("v128.vandnot") :CODE (253 79) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("v128.vor") :CODE (253 80) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("v128.vxor") :CODE (253 81) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("v128.bitselect") :CODE (253 82) :TYPE ((:V128 :V128 :V128) (:V128))) + (:INSTR ("v128.anytrue") :CODE (253 83) :TYPE ((:V128) (:I32))) + (:INSTR ("v128.load8_lane" "memarg" "laneidx") :CODE (253 84) :TYPE + ((:I32 :V128) (:V128))) + (:INSTR ("v128.load16_lane" "memarg" "laneidx") :CODE (253 85) :TYPE + ((:I32 :V128) (:V128))) + (:INSTR ("v128.load32_lane" "memarg" "laneidx") :CODE (253 86) :TYPE + ((:I32 :V128) (:V128))) + (:INSTR ("v128.load64_lane" "memarg" "laneidx") :CODE (253 87) :TYPE + ((:I32 :V128) (:V128))) + (:INSTR ("v128.store8_lane" "memarg" "laneidx") :CODE (253 88) :TYPE + ((:I32 :V128) NIL)) + (:INSTR ("v128.store16_lane" "memarg" "laneidx") :CODE (253 89) :TYPE + ((:I32 :V128) NIL)) + (:INSTR ("v128.store32_lane" "memarg" "laneidx") :CODE (253 90) :TYPE + ((:I32 :V128) NIL)) + (:INSTR ("v128.store64_lane" "memarg" "laneidx") :CODE (253 91) :TYPE + ((:I32 :V128) NIL)) + (:INSTR ("v128.load32_zero" "memarg") :CODE (253 92) :TYPE ((:I32) (:V128))) + (:INSTR ("v128.load64_zero" "memarg") :CODE (253 93) :TYPE ((:I32) (:V128))) + (:INSTR ("f32x4.vdemote_f64x2_zero") :CODE (253 94) :TYPE ((:V128) (:V128))) + (:INSTR ("f64x2.vpromote_low_f32x4") :CODE (253 95) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.vabs") :CODE (253 96) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.vneg") :CODE (253 97) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.vpopcnt") :CODE (253 98) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.alltrue") :CODE (253 99) :TYPE ((:V128) (:I32))) + (:INSTR ("i8x16.bitmask") :CODE (253 100) :TYPE ((:V128) (:I32))) + (:INSTR ("i8x16.narrow_i16x8_s") :CODE (253 101) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.narrow_i16x8_u") :CODE (253 102) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vceil") :CODE (253 103) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vfloor") :CODE (253 104) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vtrunc") :CODE (253 105) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vnearest") :CODE (253 106) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.vshl") :CODE (253 107) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i8x16.vshr_s") :CODE (253 108) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i8x16.vshr_u") :CODE (253 109) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i8x16.vadd") :CODE (253 110) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vadd_sat_s") :CODE (253 111) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vadd_sat_u") :CODE (253 112) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vsub") :CODE (253 113) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vsub_sat_s") :CODE (253 114) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vsub_sat_u") :CODE (253 115) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vceil") :CODE (253 116) :TYPE ((:V128) (:V128))) + (:INSTR ("f64x2.vfloor") :CODE (253 117) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.vmin_s") :CODE (253 118) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vmin_u") :CODE (253 119) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vmax_s") :CODE (253 120) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i8x16.vmax_u") :CODE (253 121) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vtrunc") :CODE (253 122) :TYPE ((:V128) (:V128))) + (:INSTR ("i8x16.avgr_u") :CODE (253 123) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.extaddpairwise_i8x16_s") :CODE (253 124) :TYPE + ((:V128) (:V128))) + (:INSTR ("i16x8.extaddpairwise_i8x16_u") :CODE (253 125) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.extaddpairwise_i16x8_s") :CODE (253 126) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.extaddpairwise_i16x8_u") :CODE (253 127) :TYPE + ((:V128) (:V128))) + (:INSTR ("i16x8.vabs") :CODE (253 128 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i16x8.vneg") :CODE (253 129 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i16x8.q15mulrsat_s") :CODE (253 130 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.alltrue") :CODE (253 131 1) :TYPE ((:V128) (:I32))) + (:INSTR ("i16x8.bitmask") :CODE (253 132 1) :TYPE ((:V128) (:I32))) + (:INSTR ("i16x8.narrow_i32x4_s") :CODE (253 133 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.narrow_i32x4_u") :CODE (253 134 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vextend_low_i8x16_s") :CODE (253 135 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i16x8.vextend_high_i8x16_s") :CODE (253 136 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i16x8.vextend_low_i8x16_u") :CODE (253 137 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i16x8.vextend_high_i8x16_u") :CODE (253 138 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i16x8.vshl") :CODE (253 139 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i16x8.vshr_s") :CODE (253 140 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i16x8.vshr_u") :CODE (253 141 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i16x8.vadd") :CODE (253 142 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vadd_sat_s") :CODE (253 143 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vadd_sat_u") :CODE (253 144 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vsub") :CODE (253 145 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vsub_sat_s") :CODE (253 146 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vsub_sat_u") :CODE (253 147 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vnearest") :CODE (253 148 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i16x8.vmul") :CODE (253 149 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vmin_s") :CODE (253 150 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vmin_u") :CODE (253 151 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vmax_s") :CODE (253 152 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.vmax_u") :CODE (253 153 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.avgr_u") :CODE (253 155 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.extmul_low_i8x16_s") :CODE (253 156 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.extmul_high_i8x16_s") :CODE (253 157 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.extmul_low_i8x16_u") :CODE (253 158 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i16x8.extmul_high_i8x16_u") :CODE (253 159 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vabs") :CODE (253 160 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i32x4.vneg") :CODE (253 161 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i32x4.alltrue") :CODE (253 163 1) :TYPE ((:V128) (:I32))) + (:INSTR ("i32x4.bitmask") :CODE (253 164 1) :TYPE ((:V128) (:I32))) + (:INSTR ("i32x4.vextend_low_i16x8_s") :CODE (253 167 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.vextend_high_i16x8_s") :CODE (253 168 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.vextend_low_i16x8_u") :CODE (253 169 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.vextend_high_i16x8_u") :CODE (253 170 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.vshl") :CODE (253 171 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i32x4.vshr_s") :CODE (253 172 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i32x4.vshr_u") :CODE (253 173 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i32x4.vadd") :CODE (253 174 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vsub") :CODE (253 177 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vmul") :CODE (253 181 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vmin_s") :CODE (253 182 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vmin_u") :CODE (253 183 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vmax_s") :CODE (253 184 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.vmax_u") :CODE (253 185 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.dot_i16x8_s") :CODE (253 186 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.extmul_low_i16x8_s") :CODE (253 188 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.extmul_high_i16x8_s") :CODE (253 189 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.extmul_low_i16x8_u") :CODE (253 190 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.extmul_high_i16x8_u") :CODE (253 191 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vabs") :CODE (253 192 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i64x2.vneg") :CODE (253 193 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i64x2.alltrue") :CODE (253 195 1) :TYPE ((:V128) (:I32))) + (:INSTR ("i64x2.bitmask") :CODE (253 196 1) :TYPE ((:V128) (:I32))) + (:INSTR ("i64x2.vextend_low_i32x4_s") :CODE (253 199 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i64x2.vextend_high_i32x4_s") :CODE (253 200 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i64x2.vextend_low_i32x4_u") :CODE (253 201 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i64x2.vextend_high_i32x4_u") :CODE (253 202 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i64x2.vshl") :CODE (253 203 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i64x2.vshr_s") :CODE (253 204 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i64x2.vshr_u") :CODE (253 205 1) :TYPE ((:V128 :I32) (:V128))) + (:INSTR ("i64x2.vadd") :CODE (253 206 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vsub") :CODE (253 209 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vmul") :CODE (253 213 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.veq") :CODE (253 214 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vne") :CODE (253 215 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vlt_s") :CODE (253 216 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vgt_s") :CODE (253 217 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vle_s") :CODE (253 218 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.vge_s") :CODE (253 219 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.extmul_low_i32x4_s") :CODE (253 220 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.extmul_high_i32x4_s") :CODE (253 221 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.extmul_low_i32x4_u") :CODE (253 222 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("i64x2.extmul_high_i32x4_u") :CODE (253 223 1) :TYPE + ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vabs") :CODE (253 224 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vneg") :CODE (253 225 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vsqrt") :CODE (253 227 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vadd") :CODE (253 228 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vsub") :CODE (253 229 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vmul") :CODE (253 230 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vdiv") :CODE (253 231 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vmin") :CODE (253 232 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vmax") :CODE (253 233 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vpmin") :CODE (253 234 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f32x4.vpmax") :CODE (253 235 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vabs") :CODE (253 236 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f64x2.vneg") :CODE (253 237 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f64x2.vsqrt") :CODE (253 239 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f64x2.vadd") :CODE (253 240 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vsub") :CODE (253 241 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vmul") :CODE (253 242 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vdiv") :CODE (253 243 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vmin") :CODE (253 244 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vmax") :CODE (253 245 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vpmin") :CODE (253 246 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("f64x2.vpmax") :CODE (253 247 1) :TYPE ((:V128 :V128) (:V128))) + (:INSTR ("i32x4.trunc_sat_f32x4_s") :CODE (253 248 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i32x4.trunc_sat_f32x4_u") :CODE (253 249 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vconvert_i32x4_s") :CODE (253 250 1) :TYPE ((:V128) (:V128))) + (:INSTR ("f32x4.vconvert_i32x4_u") :CODE (253 251 1) :TYPE ((:V128) (:V128))) + (:INSTR ("i32x4.vtrunc_sat_f64x2_s_zero") :CODE (253 252 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("i32x4.vtrunc_sat_f64x2_u_zero") :CODE (253 253 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("f64x2.vconvert_low_i32x4_s") :CODE (253 254 1) :TYPE + ((:V128) (:V128))) + (:INSTR ("f64x2.vconvert_low_i32x4_u") :CODE (253 255 1) :TYPE + ((:V128) (:V128))))) diff --git a/src/util.lisp b/src/util.lisp new file mode 100644 index 0000000..5899b36 --- /dev/null +++ b/src/util.lisp @@ -0,0 +1,84 @@ +(defpackage #:sarcasm.util + (:use #:cl) + (:export + #:take-until + #:def/class)) + +(in-package #:sarcasm.util) + +(defun take-until (pred list) + "Returns two values: FRONT BACK. + +FRONT contains the first N members X of LIST for which (PRED X) is NIL. +BACK contains everything after the members of FRONT. + +(EQUALP LIST + (MULTIPLE-VALUE-BIND (FRONT BACK) (TAKE-UNTIL PRED LIST) + (APPEND FRONT BACK)) + +Is always T." + (loop :for (x . back) :on list + :for fx? := (funcall pred x) + :until fx? + :collect x :into front + :finally (return (values front (if fx? (cons x back) nil))))) + +(defun partition (pred list) + "Returns two list values: YES NO. + +YES is everything for which PRED is T, NO is everything else." + (loop :for e :in list + :when (funcall pred e) + :collect e :into yes + :else + :collect e :into no + :finally (return (values yes no)))) + +(defmacro def/class (name (&rest supers) &body slots-and-options) + "Define a class. + +SLOTS-AND-OPTIONS := (SLOT-SPEC1 ... SLOT-SPECN . CLASS-OPTIONS) + +Each SLOT-SPEC is a list of slot names followed by keyword slot +options, E.g: + +(X Y Z :type integer :initarg 0) + +Would expand into three slot definitions +(X :accessor X :initarg :X :type integer :initarg 0) +(Y :accessor Y :initarg :Y :type integer :initarg 0) +(Z :accessor Z :initarg :Z :type integer :initarg 0) + +CLASS-OPTIONS is a PLIST of class options." + (labels + ((make-accessor-name (slot &optional prefix?) + (if prefix? + (intern (format nil "~a-~a" name slot)) + slot)) + (singlep (x) + (find x '(:prefix) :test #'eq)) + (parse-slot-spec-expr (expr) + " (names ... &key kwargs)" + (multiple-value-bind (slot-names kwargs) (take-until #'keywordp expr) + (multiple-value-bind (kwargs singles) (partition #'singlep kwargs) + (loop + :with prefix-accessor? := (find ':prefix singles :test #'eq) + :for slot :in slot-names + :collect `(,slot + :accessor ,(make-accessor-name slot prefix-accessor?) + :initarg ,(alexandria:make-keyword slot) + ,@kwargs))))) + + (parse-class-options (kwargs) + (loop :for (key val . more) :on kwargs :by #'cddr + :collect (list key val)))) + + (let* ((slot-defs (loop :for expr :in slots-and-options + :while (listp expr) + :append (parse-slot-spec-expr expr))) + (options (parse-class-options + (nth-value 1 (take-until #'keywordp slots-and-options))))) + + `(defclass ,name ,supers + (,@slot-defs) + ,@options)))) |