Decode an instruction.
(decode enc feat) → instr?
The first input is a 32-bit encoding of the instruction;
the second input consists of the features, which affect decoding.
If decoding is successful, we return the instruction.
If decoding is unsuccessful, we return
The values of the encoded fields, which we write in binary notation, are taken from the instruction listings in [ISA:34].
We retrieve the opcode, and we dispatch based on it. Each dispatch first retrieves the fields, based on the format, and then checks them to see whether they are valid, and to determine which instruction is encoded, if any.
With the
With the
Function:
(defun decode (enc feat) (declare (xargs :guard (and (ubyte32p enc) (featp feat)))) (let ((__function__ 'decode)) (declare (ignorable __function__)) (b* ((enc (ubyte32-fix enc))) (case (get-opcode enc) (3 (b* (((mv funct3 rd rs1 imm) (get-fields-itype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rd) (ubyte4p rs1)))) nil) (funct (case funct3 (0 (load-funct-lb)) (1 (load-funct-lh)) (2 (load-funct-lw)) (3 (if (feat-64p feat) (load-funct-ld) nil)) (4 (load-funct-lbu)) (5 (load-funct-lhu)) (6 (if (feat-64p feat) (load-funct-lwu) nil)) (7 nil))) ((unless funct) nil)) (instr-load funct rd rs1 imm))) (19 (b* (((mv funct3 rd rs1 imm) (get-fields-itype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rd) (ubyte4p rs1)))) nil) (funct (case funct3 (0 (op-imm-funct-addi)) (1 nil) (2 (op-imm-funct-slti)) (3 (op-imm-funct-sltiu)) (4 (op-imm-funct-xori)) (5 nil) (6 (op-imm-funct-ori)) (7 (op-imm-funct-andi)))) ((when funct) (instr-op-imm funct rd rs1 imm))) (if (feat-64p feat) (b* ((loimm (part-select imm :low 0 :high 5)) (hiimm (part-select imm :low 6 :high 11)) ((when (= funct3 1)) (if (= hiimm 0) (if (feat-64p feat) (instr-op-imms64 (op-imms-funct-slli) rd rs1 loimm) nil) nil))) (case hiimm (0 (if (feat-64p feat) (instr-op-imms64 (op-imms-funct-srli) rd rs1 loimm) nil)) (16 (if (feat-64p feat) (instr-op-imms64 (op-imms-funct-srai) rd rs1 loimm) nil)) (t nil))) (b* ((loimm (part-select imm :low 0 :high 4)) (hiimm (part-select imm :low 5 :high 11)) ((when (= funct3 1)) (if (= hiimm 0) (if (feat-32p feat) (instr-op-imms32 (op-imms-funct-slli) rd rs1 loimm) nil) nil))) (case hiimm (0 (if (feat-32p feat) (instr-op-imms32 (op-imms-funct-srli) rd rs1 loimm) nil)) (16 (if (feat-32p feat) (instr-op-imms32 (op-imms-funct-srai) rd rs1 loimm) nil)) (t nil)))))) (23 (b* (((mv rd imm) (get-fields-utype enc)) ((unless (or (not (feat-embedp feat)) (ubyte4p rd))) nil)) (instr-auipc rd imm))) (27 (b* (((unless (feat-64p feat)) nil) ((mv funct3 rd rs1 imm) (get-fields-itype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rd) (ubyte4p rs1)))) nil) ((when (= funct3 0)) (instr-op-imm-32 (op-imm-32-funct-addiw) rd rs1 imm)) (loimm (part-select imm :low 0 :high 4)) (hiimm (part-select imm :low 5 :high 11)) ((when (= funct3 1)) (if (= hiimm 0) (instr-op-imms-32 (op-imms-32-funct-slliw) rd rs1 loimm) nil)) ((when (= funct3 5)) (case hiimm (0 (instr-op-imms-32 (op-imms-32-funct-srliw) rd rs1 loimm)) (32 (instr-op-imms-32 (op-imms-32-funct-sraiw) rd rs1 loimm)) (t nil)))) nil)) (35 (b* (((mv funct3 rs1 rs2 imm) (get-fields-stype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rs1) (ubyte4p rs2)))) nil) (funct (case funct3 (0 (store-funct-sb)) (1 (store-funct-sh)) (2 (store-funct-sw)) (3 (if (feat-64p feat) (store-funct-sd) nil)) (t nil))) ((unless funct) nil)) (instr-store funct rs1 rs2 imm))) (51 (b* (((mv funct3 funct7 rd rs1 rs2) (get-fields-rtype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rd) (ubyte4p rs1) (ubyte4p rs2)))) nil) (funct (case funct3 (0 (case funct7 (0 (op-funct-add)) (1 (if (feat-mp feat) (op-funct-mul) nil)) (32 (op-funct-sub)) (t nil))) (1 (case funct7 (0 (op-funct-sll)) (1 (if (feat-mp feat) (op-funct-mulh) nil)) (t nil))) (2 (case funct7 (0 (op-funct-slt)) (1 (if (feat-mp feat) (op-funct-mulhsu) nil)) (t nil))) (3 (case funct7 (0 (op-funct-sltu)) (1 (if (feat-mp feat) (op-funct-mulhu) nil)) (t nil))) (4 (case funct7 (0 (op-funct-xor)) (1 (if (feat-mp feat) (op-funct-div) nil)) (t nil))) (5 (case funct7 (0 (op-funct-srl)) (1 (if (feat-mp feat) (op-funct-divu) nil)) (32 (op-funct-sra)) (t nil))) (6 (case funct7 (0 (op-funct-or)) (1 (if (feat-mp feat) (op-funct-rem) nil)) (t nil))) (7 (case funct7 (0 (op-funct-and)) (1 (if (feat-mp feat) (op-funct-remu) nil)) (t nil))))) ((unless funct) nil)) (instr-op funct rd rs1 rs2))) (55 (b* (((mv rd imm) (get-fields-utype enc)) ((unless (or (not (feat-embedp feat)) (ubyte4p rd))) nil)) (instr-lui rd imm))) (59 (b* (((unless (feat-64p feat)) nil) ((mv funct3 funct7 rd rs1 rs2) (get-fields-rtype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rd) (ubyte4p rs1) (ubyte4p rs2)))) nil) (funct (case funct3 (0 (case funct7 (0 (op-32-funct-addw)) (1 (if (feat-mp feat) (op-32-funct-mulw) nil)) (32 (op-32-funct-subw)) (t nil))) (1 (case funct7 (0 (op-32-funct-sllw)) (t nil))) (2 nil) (3 nil) (4 (case funct7 (1 (if (feat-mp feat) (op-32-funct-divw) nil)) (t nil))) (5 (case funct7 (0 (op-32-funct-srlw)) (1 (if (feat-mp feat) (op-32-funct-divuw) nil)) (32 (op-32-funct-sraw)) (t nil))) (6 (case funct7 (1 (if (feat-mp feat) (op-32-funct-remw) nil)) (t nil))) (7 (case funct7 (1 (if (feat-mp feat) (op-32-funct-remuw) nil)) (t nil))))) ((unless funct) nil)) (instr-op-32 funct rd rs1 rs2))) (99 (b* (((mv funct3 rs1 rs2 imm) (get-fields-btype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rs1) (ubyte4p rs2)))) nil) (funct (case funct3 (0 (branch-funct-beq)) (1 (branch-funct-bne)) (2 nil) (3 nil) (4 (branch-funct-blt)) (5 (branch-funct-bge)) (6 (branch-funct-bltu)) (7 (branch-funct-bgeu)))) ((unless funct) nil)) (instr-branch funct rs1 rs2 imm))) (103 (b* (((mv funct3 rd rs1 imm) (get-fields-itype enc)) ((unless (or (not (feat-embedp feat)) (and (ubyte4p rd) (ubyte4p rs1)))) nil) ((unless (= funct3 0)) nil)) (instr-jalr rd rs1 imm))) (111 (b* (((mv rd imm) (get-fields-jtype enc)) ((unless (or (not (feat-embedp feat)) (ubyte4p rd))) nil)) (instr-jal rd imm))) (t nil)))))
Theorem:
(defthm instr-optionp-of-decode (b* ((instr? (decode enc feat))) (instr-optionp instr?)) :rule-classes :rewrite)
Theorem:
(defthm instr-validp-of-decode (b* ((?instr? (decode enc feat))) (implies instr? (instr-validp instr? feat))))
Theorem:
(defthm decode-of-ubyte32-fix-enc (equal (decode (ubyte32-fix enc) feat) (decode enc feat)))
Theorem:
(defthm decode-ubyte32-equiv-congruence-on-enc (implies (acl2::ubyte32-equiv enc enc-equiv) (equal (decode enc feat) (decode enc-equiv feat))) :rule-classes :congruence)
Theorem:
(defthm decode-of-feat-fix-feat (equal (decode enc (feat-fix feat)) (decode enc feat)))
Theorem:
(defthm decode-feat-equiv-congruence-on-feat (implies (feat-equiv feat feat-equiv) (equal (decode enc feat) (decode enc feat-equiv))) :rule-classes :congruence)