#lang rosette

(require "model.rkt")
(require "util.rkt")
(require "verify.rkt")
(require "compliant.rkt")

(output-smt #f)

(require rosette/solver/smt/boolector)
(require rosette/solver/smt/cvc4)
(require rosette/solver/smt/z3)

(rv-verify
 #:name "ADDI"
 #:init-pc ADDI-PC
 #:fuel 5
 #:microcode microcode
 #:solver (boolector)
 #:spec (λ (res)
          (and (eq? (list-ref res 1) (bvadd val-rvpc (bv 4 XLEN)))
               (eq? (list-ref res 4) (bvadd val-immi val-src2))))
 #:assumptions #f)

;; (rv-verify
;;  #:name "SUB"
;;  #:init-pc SUB-PC
   # : fuel 9
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " AUIPC "
;;  #:init-pc AUIPC-PC
   # : fuel 10
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " LUI "
;;  #:init-pc LUI-PC
   # : fuel 10
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " JAL "
   # : init - pc JAL - PC
   # : fuel 20
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (        ) )
                 ( eq ? ( list - ref res 4 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions (λ (res)
                   ( assume ( eq ? ( bv 0 2 ) ( extract 1 0 ( list - ref res 1 ) ) ) ) ) )

;; (rv-verify
   # : name " JALR "
;;  #:init-pc JALR-PC
   # : fuel 20
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (        ) )
                 ; ; ( bveq ( lsb ( list - ref res 1 ) ) ( bv 0 1 ) )
                 ( eq ? ( bv 0 2 ) ( extract 1 0 ( list - ref res 1 ) ) )
                 ( eq ? ( list - ref res 4 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " BEQ "
   # : init - pc BEQ - PC
   # : fuel 20
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( if (    src1 val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
;;  #:name "BNE"
;;  #:init-pc BNE-PC
   # : fuel 20
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( if (    src1 val - src2 )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                ( eq ? ( list - ref res 1 ) (        ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name "  "
;;  #:init-pc BLT-PC
   # : fuel 20
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
;;           (if (bvslt val-src1 val-src2)
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " BLTU "
;;  #:init-pc BLTU-PC
   # : fuel ( + 10 ( * 19 XLEN ) )
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( if (    src1 val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " BGE "
;;  #:init-pc BGE-PC
   # : fuel 20
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( if (     val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
;;  #:name "BGEU"
;;  #:init-pc BGEU-PC
   # : fuel 30
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( if (     val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " SLTI "
   # : init - pc SLTI - PC
   # : fuel 10
;;  #:microcode microcode
;;  #:solver (z3)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) ( if ( bvslt val - src1 val - src2 ) ( bv 1 XLEN ) ( bv 0 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
   # : name " SLTIU "
   # : init - pc SLTIU - PC
   # : fuel 200
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) ( if (    src1 val - src2 ) ( bv 1 XLEN ) ( bv 0 XLEN ) ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
;;  #:name "SLLI"
;;  #:init-pc SLLI-PC
   # : fuel ( + ( * 4 XLEN ) 3 )
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
   # : assumptions ( λ ( mem ) ; ; restrict shift amount for sll / slli / srl / srli
;;                  (assume
                    ( bvult ( list - ref mem 2 ) ( bv   ) ) ) ) )

;; (rv-verify
   # : name " SRLI "
   # : init - pc SRLI - PC
   # : fuel 150
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) ( bvlshr val - src1 val - immi ) ) ) )
   # : assumptions ( λ ( mem ) ; ; restrict shift amount for sll / slli / srl / srli
;;                  (assume
                    ( bvult ( list - ref mem 8) ( bv ( - XLEN 1 )  ) ) ) ) )

;; (rv-verify
;;  #:name "SRAI"
;;  #:init-pc SRAI-PC
   # : fuel 150
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (   - src1 val - immi ) ) ) )
   # : assumptions ( λ ( mem ) ; ; restrict shift amount for sll / slli / srl / srli
;;                  (assume
                    ( bvult ( list - ref mem 8) ( bv ( - XLEN 1 )  ) ) ) ) )

;; (rv-verify
   # : name " XORI "
   # : init - pc XORI - PC
   # : fuel ( + 15 ( * 18 XLEN ) )
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (         ) ) ) )
;;  #:assumptions #f)

;; (rv-verify
;;  #:name "ANDI"
;;  #:init-pc ANDI-PC
   # : fuel ( + 15 ( * 15 XLEN ) )
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
;;                (eq? (list-ref res 4) (bvand val-src2 val-immi))))
;;  #:assumptions #f)

;; (rv-verify
   # : name " ORI "
   # : init - pc ORI - PC
   # : fuel ( + 15 ( * 17 XLEN ) )
;;  #:microcode microcode
;;  #:solver (boolector)
;;  #:spec (λ (res)
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
;;  #:assumptions #f)

 (rv-verify
  #:name "SUB"
  #:init-pc SUB-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:init-pc AUIPC-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:init-pc LUI-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions (λ (res)
 (rv-verify
  #:init-pc JALR-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
 ; ( bveq ( lsb ( list - ref res 1 ) ) ( bv 0 1 ) )
  #:assumptions #f)
 (rv-verify
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:name "BNE"
  #:init-pc BNE-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:init-pc BLT-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
           (if (bvslt val-src1 val-src2)
  #:assumptions #f)
 (rv-verify
  #:init-pc BLTU-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:init-pc BGE-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:name "BGEU"
  #:init-pc BGEU-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:microcode microcode
  #:solver (z3)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:name "SLLI"
  #:init-pc SLLI-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
 ; restrict shift amount for sll / slli / srl / srli
                  (assume
 (rv-verify
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
 ; restrict shift amount for sll / slli / srl / srli
                  (assume
 (rv-verify
  #:name "SRAI"
  #:init-pc SRAI-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
 ; restrict shift amount for sll / slli / srl / srli
                  (assume
 (rv-verify
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
 (rv-verify
  #:name "ANDI"
  #:init-pc ANDI-PC
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
                (eq? (list-ref res 4) (bvand val-src2 val-immi))))
  #:assumptions #f)
 (rv-verify
  #:microcode microcode
  #:solver (boolector)
  #:spec (λ (res)
  #:assumptions #f)
#lang rosette

(require "model.rkt")
(require "util.rkt")
(require "verify.rkt")
(require "compliant.rkt")

(output-smt #f)

(require rosette/solver/smt/boolector)
(require rosette/solver/smt/cvc4)
(require rosette/solver/smt/z3)

(rv-verify
 #:name "ADDI"
 #:init-pc ADDI-PC
 #:fuel 5
 #:microcode microcode
 #:solver (boolector)
 #:spec (λ (res)
          (and (eq? (list-ref res 1) (bvadd val-rvpc (bv 4 XLEN)))
               (eq? (list-ref res 4) (bvadd val-immi val-src2))))
 #:assumptions #f)

   # : fuel 9
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )

   # : name " AUIPC "
   # : fuel 10
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )

   # : name " LUI "
   # : fuel 10
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )

   # : name " JAL "
   # : init - pc JAL - PC
   # : fuel 20
            ( and ( eq ? ( list - ref res 1 ) (        ) )
                 ( eq ? ( list - ref res 4 ) (     ( bv 4 XLEN ) ) ) ) )
                   ( assume ( eq ? ( bv 0 2 ) ( extract 1 0 ( list - ref res 1 ) ) ) ) ) )

   # : name " JALR "
   # : fuel 20
            ( and ( eq ? ( list - ref res 1 ) (        ) )
                 ( eq ? ( bv 0 2 ) ( extract 1 0 ( list - ref res 1 ) ) )
                 ( eq ? ( list - ref res 4 ) (     ( bv 4 XLEN ) ) ) ) )

   # : name " BEQ "
   # : init - pc BEQ - PC
   # : fuel 20
            ( if (    src1 val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )

   # : fuel 20
            ( if (    src1 val - src2 )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                ( eq ? ( list - ref res 1 ) (        ) ) ) )

   # : name "  "
   # : fuel 20
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )

   # : name " BLTU "
   # : fuel ( + 10 ( * 19 XLEN ) )
            ( if (    src1 val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )

   # : name " BGE "
   # : fuel 20
            ( if (     val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )

   # : fuel 30
            ( if (     val - src2 )
                ( eq ? ( list - ref res 1 ) (        ) )
                ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) ) ) )

   # : name " SLTI "
   # : init - pc SLTI - PC
   # : fuel 10
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) ( if ( bvslt val - src1 val - src2 ) ( bv 1 XLEN ) ( bv 0 XLEN ) ) ) ) )

   # : name " SLTIU "
   # : init - pc SLTIU - PC
   # : fuel 200
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) ( if (    src1 val - src2 ) ( bv 1 XLEN ) ( bv 0 XLEN ) ) ) ) )

   # : fuel ( + ( * 4 XLEN ) 3 )
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
                    ( bvult ( list - ref mem 2 ) ( bv   ) ) ) ) )

   # : name " SRLI "
   # : init - pc SRLI - PC
   # : fuel 150
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) ( bvlshr val - src1 val - immi ) ) ) )
                    ( bvult ( list - ref mem 8) ( bv ( - XLEN 1 )  ) ) ) ) )

   # : fuel 150
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (   - src1 val - immi ) ) ) )
                    ( bvult ( list - ref mem 8) ( bv ( - XLEN 1 )  ) ) ) ) )

   # : name " XORI "
   # : init - pc XORI - PC
   # : fuel ( + 15 ( * 18 XLEN ) )
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (         ) ) ) )

   # : fuel ( + 15 ( * 15 XLEN ) )
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )

   # : name " ORI "
   # : init - pc ORI - PC
   # : fuel ( + 15 ( * 17 XLEN ) )
            ( and ( eq ? ( list - ref res 1 ) (     ( bv 4 XLEN ) ) )
                 ( eq ? ( list - ref res 4 ) (        ) ) ) )
