From 7d16c07f1da35e9b2524e53f537fdc34c1957b97 Mon Sep 17 00:00:00 2001 From: Matt Griffin Date: Wed, 5 Jun 2024 14:34:43 +0100 Subject: [PATCH 1/2] Add MSP430 lifter. --- bap-msp430.opam | 42 +++++ dune-project | 17 +++ lib/bap_msp430/bap_msp430_target.ml | 77 ++++++++++ lib/bap_msp430/bap_msp430_target.mli | 9 ++ lib/bap_msp430/dune | 6 + plugins/msp430/dune | 22 +++ plugins/msp430/msp430_main.ml | 144 ++++++++++++++++++ plugins/msp430/msp430_main.mli | 0 plugins/msp430/semantics/dune | 4 + plugins/msp430/semantics/msp430.lisp | 219 +++++++++++++++++++++++++++ tools/bapdoc.ml | 1 + 11 files changed, 541 insertions(+) create mode 100644 bap-msp430.opam create mode 100644 lib/bap_msp430/bap_msp430_target.ml create mode 100644 lib/bap_msp430/bap_msp430_target.mli create mode 100644 lib/bap_msp430/dune create mode 100644 plugins/msp430/dune create mode 100644 plugins/msp430/msp430_main.ml create mode 100644 plugins/msp430/msp430_main.mli create mode 100644 plugins/msp430/semantics/dune create mode 100644 plugins/msp430/semantics/msp430.lisp diff --git a/bap-msp430.opam b/bap-msp430.opam new file mode 100644 index 000000000..4cf9ee7e0 --- /dev/null +++ b/bap-msp430.opam @@ -0,0 +1,42 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +version: "dev" +synopsis: "BAP MSP430 support package" +maintainer: ["Ivan Gotovchits "] +authors: ["The BAP Team"] +license: "MIT" +tags: ["bap" "bap-plugin" "msp430"] +homepage: "https://github.com/BinaryAnalysisPlatform/bap" +bug-reports: "https://github.com/BinaryAnalysisPlatform/bap/issues" +depends: [ + "dune" {>= "3.1"} + "bap-abi" {= version} + "bap-api" {= version} + "bap-common" {= version} + "bap-core-theory" {= version} + "bap-c" {= version} + "bap-knowledge" {= version} + "bap-std" {= version} + "core_kernel" {>= "v0.14" & < "v0.16"} + "monads" {= version} + "ogre" {= version} + "ppx_bap" {= version} + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "--promote-install-files=false" + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] + ["dune" "install" "-p" name "--create-install-files" name] +] +dev-repo: "git+https://github.com/BinaryAnalysisPlatform/bap.git" diff --git a/dune-project b/dune-project index a9132b891..c964e8031 100644 --- a/dune-project +++ b/dune-project @@ -1211,6 +1211,23 @@ between the sets.") (ogre (= :version)) (ppx_bap (= :version)))) +(package + (name bap-msp430) + (synopsis "BAP MSP430 support package") + (tags (bap bap-plugin msp430)) + (depends + (bap-abi (= :version)) + (bap-api (= :version)) + (bap-common (= :version)) + (bap-core-theory (= :version)) + (bap-c (= :version)) + (bap-knowledge (= :version)) + (bap-std (= :version)) + (core_kernel (and (>= v0.14) (< v0.16))) + (monads (= :version)) + (ogre (= :version)) + (ppx_bap (= :version)))) + (package (name bap-run) (synopsis "BAP Primus Framework frontend") diff --git a/lib/bap_msp430/bap_msp430_target.ml b/lib/bap_msp430/bap_msp430_target.ml new file mode 100644 index 000000000..7b5c12369 --- /dev/null +++ b/lib/bap_msp430/bap_msp430_target.ml @@ -0,0 +1,77 @@ +open Core_kernel[@@warning "-D"] +open Bap_core_theory + +let package = "bap" + +type r16 and r8 + +type 'a bitv = 'a Theory.Bitv.t Theory.Value.sort + +let r16 : r16 bitv = Theory.Bitv.define 16 +let r8 : r8 bitv = Theory.Bitv.define 8 +let bool = Theory.Bool.t + +let reg t n = Theory.Var.define t n +let untyped = List.map ~f:Theory.Var.forget +let (@<) xs ys = untyped xs @ untyped ys + + +let regs = [ + "r0"; "r1"; "r2"; "r3"; "r4"; "r5"; "r6"; "r7"; "r8"; "r9"; + "r10"; "r11"; "r12"; "r13"; "r14"; "r15" +] + +let cf = reg bool "C" +let zf = reg bool "Z" +let nf = reg bool "N" +let vf = reg bool "V" + +let status_reg = [nf; zf; cf; vf] + +let array t = List.map regs ~f:(reg t) +let vars p t = List.init 16 ~f:(fun i -> reg t (sprintf "%c%d" p i)) + +(* +let parent = Theory.Target.declare ~package "msp430" + ~endianness:Theory.Endianness.le *) + +let select xs ~mask = + let mask = Set.of_list (module Int) mask in + List.filteri xs ~f:(fun i _ -> Set.mem mask i) + +let msp430 = + let mems = Theory.Mem.define r16 r8 in + let mem = reg mems "mem" in + (*let pc = reg r16 "PC" in *PC is at r0 *) + let ints = untyped@@vars 'R' r16 in + let vars = ints (*@< flts @< [pc]*) @< status_reg @< [mem] in + let bits = Theory.Bitv.size r16 in + let r i = select ints ~mask:i in + Theory.Target.declare ~package "msp430" (*~parent*) + ~endianness:Theory.Endianness.le + ~bits + ~code:mem + ~data:mem + ~vars + ~regs:Theory.Role.Register.[ + [general; integer], ints; + (*[general; floating], flts;*) + (*[constant; zero; pseudo], x[0];*) + (*[pseudo], untyped@@[pc];*) + (*[function_argument], x(10--17) @ f(10--17); + [function_return], x(10--12) @ f(10--12); + [link], x[1];*) + [stack_pointer], r[1]; + (*[thread], x[3];*) + (*[caller_saved], x[1] @ x(5--7) @ x(10--17) @ x(28--31) @ + f(0--7) @ f(10--17) @ f(28--31); + [callee_saved], x[2] @ x(8--9) @ x(18--27) @ + f(8--9) @ f(18--27);*) + [status; integer], untyped status_reg; + [carry_flag], untyped [cf]; + [sign_flag], untyped [nf]; + [zero_flag], untyped [zf]; + [overflow_flag], untyped [vf]; + ] + +let llvm16 = Theory.Language.declare ~package "llvm-msp430" diff --git a/lib/bap_msp430/bap_msp430_target.mli b/lib/bap_msp430/bap_msp430_target.mli new file mode 100644 index 000000000..243162612 --- /dev/null +++ b/lib/bap_msp430/bap_msp430_target.mli @@ -0,0 +1,9 @@ +open Bap_core_theory + + +type r16 and r8 + +type 'a bitv = 'a Theory.Bitv.t Theory.Value.sort + +val msp430 : Theory.Target.t +val llvm16 : Theory.Language.t diff --git a/lib/bap_msp430/dune b/lib/bap_msp430/dune new file mode 100644 index 000000000..e99874622 --- /dev/null +++ b/lib/bap_msp430/dune @@ -0,0 +1,6 @@ +(library + (name bap_msp430) + (public_name bap-msp430) + (preprocess (pps ppx_bap)) + (wrapped false) + (libraries bap-core-theory bap-knowledge core_kernel )) diff --git a/plugins/msp430/dune b/plugins/msp430/dune new file mode 100644 index 000000000..1d650031a --- /dev/null +++ b/plugins/msp430/dune @@ -0,0 +1,22 @@ +(library + (name bap_msp430_plugin) + (public_name bap-msp430.plugin) + (preprocess (pps ppx_bap)) + (libraries + bap + bap-abi + bap-api + bap-c + bap-core-theory + bap-knowledge + bap-main + bap-msp430 + core_kernel + monads + ogre)) + +(plugin + (name msp430) + (package bap-msp430) + (libraries bap-msp430.plugin) + (site (bap-common plugins))) diff --git a/plugins/msp430/msp430_main.ml b/plugins/msp430/msp430_main.ml new file mode 100644 index 000000000..971ae9a82 --- /dev/null +++ b/plugins/msp430/msp430_main.ml @@ -0,0 +1,144 @@ +open Core_kernel[@@warning "-D"] +open Bap_main +open Bap.Std +open Bap_core_theory +open KB.Syntax +module CT = Theory + +include Bap_main.Loggers() + +module Target = Bap_msp430_target +module Dis = Disasm_expert.Basic + +type Extension.Error.t += Unknown_backend of string + +let provides = [ + "semantics"; + "lifter"; + "msp430"; +] + +let use_llvm_decoding () = + KB.promise CT.Label.encoding @@ fun label -> + CT.Label.target label >>| fun t -> + if CT.Target.belongs Target.msp430 t + then Target.llvm16 + else CT.Language.unknown + + +let enable_llvm () = + Dis.register Target.llvm16 @@ fun _ -> + Dis.create (*TODO - find these out ~attrs:"+a,+c,+d,+m"*) ~backend:"llvm" "msp430" + +(* +let pcode = Theory.Language.declare ~package:"bap" "pcode-msp430" + +let enable_pcode () = + Dis.register pcode @@begin fun t -> + Dis.create ~backend:"ghidra" @@ sprintf "msp430:LE:%d:default" + (Theory.Target.bits t) + end; + KB.promise Theory.Label.encoding @@begin fun label -> + Theory.Label.target label >>| fun t -> + if Theory.Target.belongs Target.parent t + then pcode + else Theory.Language.unknown + end +*) + +let enable_loader () = + let request_arch doc = + let open Ogre.Syntax in + match Ogre.eval (Ogre.request Image.Scheme.arch) doc with + | Error _ -> assert false + | Ok arch -> arch in + KB.promise CT.Unit.target @@ fun unit -> + KB.collect Image.Spec.slot unit >>| request_arch >>| function + | Some "msp430" -> Target.msp430 + | _ -> CT.Target.unknown + +module Abi = struct + open Bap_c.Std + open Bap.Std + + module Arg = C.Abi.Arg + open Arg.Let + open Arg.Syntax + + let is_floating = function + | `Basic {C.Type.Spec.t=#C.Type.real} -> true + | _ -> false + + let data_model t = + let bits = Theory.Target.bits t in + new C.Size.base (if bits = 32 then `ILP32 else `LP64) + + let define t = + let model = data_model t in + C.Abi.define t model @@ fun _ {C.Type.Proto.return=r; args} -> + let* iargs = Arg.Arena.iargs t in + let* irets = Arg.Arena.irets t in + let* fargs = Arg.Arena.fargs t in + let* frets = Arg.Arena.frets t in + + (* integer calling convention *) + let integer regs t = + Arg.count regs t >>= function + | None -> Arg.reject () + | Some 1 -> Arg.choice [ + Arg.register regs t; + Arg.memory t; + ] + | Some 2 -> Arg.choice [ + Arg.sequence [ + Arg.align_even regs; + Arg.registers ~limit:2 regs t; + ]; + Arg.split_with_memory regs t; + Arg.memory t; + ] + | Some _ -> Arg.reference regs t in + + (* floating-point calling convention *) + let float iregs fregs t = + Arg.count fregs t >>= function + | Some 1 -> Arg.choice [ + Arg.register fregs t; + Arg.register iregs t; + Arg.memory t; + ] + | _ -> integer iregs t in + + let arg iregs fregs r = + if is_floating r + then float iregs fregs r + else integer iregs r in + + Arg.define ?return:(match r with + | `Void -> None + | r -> Some (arg irets frets r)) + (Arg.List.iter args ~f:(fun (_,t) -> + arg iargs fargs t)); +end + + +let backend = + let open Extension in + Configuration.parameter Type.(some string) "backend" + +let main ctxt = + enable_loader (); + Abi.define Target.msp430; + match Extension.Configuration.get ctxt backend with + | Some "llvm" | None -> + use_llvm_decoding (); + enable_llvm (); + Ok () +(*| Some "ghidra" -> + enable_pcode (); + Ok ()*) + | Some s -> Error (Unknown_backend s) + +let () = Bap_main.Extension.declare main + ~doc:"provides msp430 semantics" + ~provides diff --git a/plugins/msp430/msp430_main.mli b/plugins/msp430/msp430_main.mli new file mode 100644 index 000000000..e69de29bb diff --git a/plugins/msp430/semantics/dune b/plugins/msp430/semantics/dune new file mode 100644 index 000000000..c791b796e --- /dev/null +++ b/plugins/msp430/semantics/dune @@ -0,0 +1,4 @@ +(install + (files msp430.lisp) + (package bap-msp430) + (section (site (bap-common semantics)))) diff --git a/plugins/msp430/semantics/msp430.lisp b/plugins/msp430/semantics/msp430.lisp new file mode 100644 index 000000000..5ddcc2ab2 --- /dev/null +++ b/plugins/msp430/semantics/msp430.lisp @@ -0,0 +1,219 @@ +(declare (context (target msp430))) +(defpackage msp430 (:use core target program)) +(defpackage llvm-msp430 (:use msp430)) +(in-package msp430) + +;;; Core Arithmetic + +(defun is-set (x) + (declare (visibility :private)) + (not (is-zero x))) + +(defun ADC (dst) + (set$ dst (+ dst C))) +;x x x x + +(defun ADD (dst src) + (set$ dst (+ src dst))) +;x x x x + +(defun ADDC (dst src) + (set$ dst (+ C (+ src dst)))) +;x x x x + +(defun AND (dst src) + (set$ dst (logand src dst))) +;0 x x x + +(defun BIC (dst src) + (set$ dst (logand (not src) dst))) + +;(*BIS*) +;(*BIT*) +;0 x x x + +;(*BR*) +;(*CALL*) + +(defun CLR (dst) + (set$ dst 0)) + +(defun CLRC (dst) + (set C 0)) + +(defun CLRN (dst) + (set N 0)) + +(defun CLRZ (dst) + (set Z 0)) + +(defun CMP (dst src) + (set V (- dst src))) +;xxxx +;0x38: 0c 93 +; tst r12 ; +(defun llvm-msp430:CMP16rc (dst src) + (set V (- dst src))) + +;(defun DADC(.B) dst dst + C → dst (decimal) xxxx + +;(defun DADD(.B) dst src src + dst + C → dst (decimal) xxxx +(defun DEC (dst) + (set dst (- 1 dst))) +; x x x x + +(defun DECD (dst) + (set dst (- 2 dst))) +; x x x x + +;(defun DINT () +; (special "DINT")) +;(defun EINT () +; (special "EINT")) + +(defun INC (dst) + (set dst (+ 1 dst))) + +(defun INCD (dst) + (set dst (+ 2 dst))) +; x x x x + +;(defun INV(.B) dst Invert destination xxxx) + +(defun conditional-jump (cmp off) + (declare (visibility :private)) + (let ((pc (get-program-counter))) + (when cmp + (exec-addr (+ pc off))))) + +(defun JC (label) + (conditional-jump (is-set C) label)) + + +;0x3a: f6 23 ; jne $-18 ; +;(defun llvm-msp430:JCC +;-0xa 0x1 + + +(defun JHS (label) (JC label)) + +(defun JZ (label) + (conditional-jump (is-set Z) label)) + +(defun JEQ (label) (JZ label)) + +(defun JGE (label) + (conditional-jump (is-zero (logxor N V)) label)) + +(defun JL (label) + (conditional-jump (is-zero (logxor N V)) label)) + +(defun JMP (label) + (exec-addr label)) + +(defun JN (label) + (conditional-jump (is-set N) label)) + +(defun JNC (label) + (conditional-jump (is-zero C) label)) + +(defun JLO (label) (JNC label)) + +(defun JNE (label) + (conditional-jump (is-zero Z) label)) + +(defun JNZ (label) (JNE label)) + +(defun MOV (src dst) + (set$ dst src)) + +;0x34: 1c 41 00 00 +;mov off(reg), dst +(defun llvm-msp430:MOV16rm (dst reg off) + (set$ dst (core:load-word (+ reg off)))) + +;0x2e: 81 4c 00 00 +;mov reg, off(dst) +;(llvm-msp430:MOV16mr SP 0x0 R12) +(defun llvm-msp430:MOV16mr (dst off reg) + (store-word (+ dst off) reg)) + + +;0x4: b2 40 80 5a 00 00 +;mov #23168, &0 +;(defun llvm-msp430:MOV16mi (ERROR addr val) +; (store-word addr val)) + +;0x20: b1 40 10 27 00 00 +;mov #10000, 0(r1) + +;(defmacro is-error (sym) (= sym "ERROR")) +(defun llvm-msp430:MOV16mi (reg off val) +; (if (is-error reg) +; (store-word off val) + (store-word (+ reg off) val)) +;) + +;0x16: 5c 42 00 00 ; mov.b &0, r12 ; (llvm-msp430:MOV8rm R12B ERROR 0x0) +;0xa: 5c 42 00 00 ; mov.b &0, r12 ; (llvm-msp430:MOV8rm R12B ERROR 0x0) +;0x1c: c2 4c 00 00 ; mov.b r12, &0 ; (llvm-msp430:MOV8mr ERROR 0x0 R12B) +;0x10: c2 4c 00 00 ; mov.b r12, &0 ; (llvm-msp430:MOV8mr ERROR 0x0 R12B) + + + +(defun NOP () + (empty)) + +;(defun POP (dst) (set$ sp (+ 2 sp)) +;Item from stack, SP+2 → SP) +;(defun PUSH (src) SP - 2 → SP, src → @SP - - - - + + +;(defun RETI Return from interrupt xxxx +;TOS → SR, SP + 2 → SP +;TOS → PC, SP + 2 → SZP +;(defun RET Return from subroutine ---- +;TOS → PC, SP + 2 → SP +;(defun RLA(.B) dst Rotate left arithmetically xxxx +;(defun RLC(.B) dst Rotate left through carry xxxx +;(defun RRA(.B) dst MSB → MSB ....LSB → C 0xxx +;(defun RRC(.B) dst C → MSB .........LSB → C xxxx +;(defun SBC(.B) dst Subtract carry from destination xxxx + +(defun SETC () + (set C 1)) + +(defun SETN () + (set N 1)) + +(defun SETZ () + (set Z 1)) + +(defun SUB (src dst) + (set dst (+ dst (+ (not src) 1)))); x x x x + +(defun SUBC (src dst) + (set dst (+ dst (+ (not src) C)))); x x x x + +;(defun SWPB dst swap bytes ---- +;(defun SXT dst Bit7 → Bit8 ........ Bit15 0 x x x +;(defun TST(.B) dst Test destination xxxx + +(defun XOR (src dst) + (declare (visibility :private)) + (set dst (logxor src dst))); x x x x + +; xor.b #X, rY +; llvm-msp430:XOR8rc +;(defun XOR8rc (dst _ imm) +; (set Z 1)) + + + + + + +;0x2c: 3c 53 ; add #-1, r12 ; (llvm-msp430:ADD16rc R12 R12 -0x1) +;0xe: 6c d2 ; bis.b #4, r12 ; (llvm-msp430:BIS8rc R12B R12B 0x4) + +;0x0: 31 80 02 00 ; sub #2, r1 ; (llvm-msp430:SUB16ri SP SP 0x2) diff --git a/tools/bapdoc.ml b/tools/bapdoc.ml index 791f9785d..c2919e505 100644 --- a/tools/bapdoc.ml +++ b/tools/bapdoc.ml @@ -39,6 +39,7 @@ let libraries = [ "bap-mips", "Bap_mips_target", "", "MIPS definitions"; "bap-powerpc", "Bap_powerpc_target", "", "PowerPC definitions"; "bap-riscv", "Bap_riscv_target", "", "RISCV definitions"; + "bap-msp430", "Bap_msp430_target", "", "MSP430 definitions"; "bap-systemz", "Bap_systemz_target", "", "SystemZ definitions"; ]; From 8853bfe86d5ab74b8449ea668c5f71624c52081a Mon Sep 17 00:00:00 2001 From: Matt Griffin Date: Tue, 30 Jul 2024 17:16:24 +0100 Subject: [PATCH 2/2] Add more semantics --- plugins/riscv/semantics/riscv.lisp | 104 ++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 3 deletions(-) diff --git a/plugins/riscv/semantics/riscv.lisp b/plugins/riscv/semantics/riscv.lisp index f5c497249..3915ac060 100644 --- a/plugins/riscv/semantics/riscv.lisp +++ b/plugins/riscv/semantics/riscv.lisp @@ -6,6 +6,9 @@ ;;; Core Arithmetic +(defun ADD (rd r1 r2) + (set$ rd (+ r1 r2))) + (defun ADDI (dst src off) (set$ dst (+ src off))) @@ -31,8 +34,23 @@ (defun C_ADDW (rd r1 r2) (add3 rd r1 r2)) +(defun DIV (rd r1 r2) + (set$ rd (/ r1 r2))) + +(defun DIVU (rd r1 r2) + (set$ rd (/ r1 r2))) + +(defun DIVW (rd r1 r2) + (set$ rd (/ r1 r2))) + +(defun MUL (rd r1 r2) + (set$ rd (* r1 r2))) + +(defun MULW (rd r1 r2) + (set$ rd (* r1 r2))) + (defun C_ADD (rd r1 r2) - (set$ rd (+ r1 r2))) + (set$ rd (+ r1 r2))) (defun C_ADDI4SPN (dst src off) (set$ dst (+ src off))) @@ -43,9 +61,24 @@ (defun SUB (rd r1 r2) (set$ rd (- r1 r2))) +(defun SUBW (rd r1 r2) + (set$ rd (- r1 r2))) + +(defun C_SUBW (rd r1 r2) + (set$ rd (- r1 r2))) + (defun C_SUB (rd r1 r2) (set$ rd (- r1 r2))) +(defun REM (rd r1 r2) + (set$ rd (mod r1 r2))) + +(defun REMU (rd r1 r2) + (set$ rd (mod r1 r2))) + +(defun REMW (rd r1 r2) + (set$ rd (mod r1 r2))) + ;;; Moves @@ -86,6 +119,9 @@ (defun C_LW (dst reg off) (load-word cast-signed 2 dst reg off)) +(defun C_LWSP (dst reg off) + (load-word cast-signed 2 dst reg off)) + (defun LH (dst reg off) (load-word cast-signed 4 dst reg off)) @@ -119,6 +155,12 @@ (defun SW (val reg imm) (store-word (+ reg imm) (cast-low (/ (word-width) 2) val))) +(defun C_SW (val reg imm) + (store-word (+ reg imm) (cast-low (/ (word-width) 2) val))) + +(defun C_SWSP (val reg imm) + (store-word (+ reg imm) (cast-low (/ (word-width) 2) val))) + (defun SH (val reg imm) (store-word (+ reg imm) (cast-low (/ (word-width) 4) val))) @@ -127,37 +169,88 @@ ;;; Bitwise Operations +(defun AND (rd r1 r2) + (set$ rd (logand r1 r2))) + +(defun C_AND (rd r1 r2) + (set$ rd (logand r1 r2))) + (defun ANDI (dst src off) (set$ dst (logand src off))) +(defun C_ANDI (dst src off) + (set$ dst (logand src off))) + +(defun OR (rd r1 r2) + (set$ rd (logor r1 r2))) + +(defun C_OR (rd r1 r2) + (set$ rd (logor r1 r2))) + (defun ORI (dst src off) (set$ dst (logor src off))) +(defun XOR (rd r1 r2) + (set$ rd (logxor r1 r2))) + +(defun C_XOR (rd r1 r2) + (set$ rd (logxor r1 r2))) + (defun XORI (dst src off) (set$ dst (logxor src off))) +(defun SRL (dst reg off) + (set$ dst (rshift reg off))) + (defun SRLI (dst reg off) (set$ dst (rshift reg off))) +(defun SRLIW (dst reg off) + (set$ dst (rshift reg off))) + (defun C_SRLI (dst reg off) (set$ dst (rshift reg off))) (defun C_SRAI (dst src imm) (set$ dst (arshift src imm))) +(defun SRA (dst src imm) + (set$ dst (arshift src imm))) + (defun SRAI (dst src imm) (set$ dst (arshift src imm))) +(defun SRAIW (dst src imm) + (set$ dst (arshift src imm))) + +(defun SLL (dst reg off) + (set$ dst (lshift reg off))) + (defun SLLI (dst reg off) (set$ dst (lshift reg off))) (defun C_SLLI (dst reg off) (set$ dst (lshift reg off))) +(defun SLLW (dst reg off) + (set$ dst (lshift reg off))) + +(defun SLLIW (dst reg off) + (set$ dst (lshift reg off))) + ;;; Comparison +(defun SLT (dst src off) + (set$ dst (< dst src off))) + +(defun SLTU (dst src off) + (set$ dst (< dst src off))) + (defun SLTI (dst src off) (set$ dst (< dst src off))) +(defun SLTIU (dst src off) + (set$ dst (< dst src off))) + ;;; Jumps (defun JAL (lr off) (let ((pc (get-program-counter))) @@ -197,6 +290,9 @@ (defun BGE (rs1 rs2 off) (conditional-jump (>= rs1 rs2) off)) +(defun BGEU (rs1 rs2 off) + (conditional-jump (>= rs1 rs2) off)) + (defun C_BEQ (rs1 rs2 off) (conditional-jump (= rs1 rs2) off)) @@ -216,11 +312,13 @@ (conditional-jump (is-zero rs1) off)) (defun BNEZ (rs1 off) - (conditional-jump (not (is-zero rs1)) off)) + (conditional-jump (non-zero rs1) off)) (defun C_BNEZ (rs1 off) - (conditional-jump (not (is-zero rs1)) off)) + (conditional-jump (non-zero rs1) off)) +(defun BLTU(rs1 rs2 off) + (conditional-jump (< rs1 rs2) off)) (defun C_NOP () (empty))