<commit_before>package net.katsuster.ememu.riscv.core;

import net.katsuster.ememu.generic.*;

public class DecodeStageRVI extends Stage64 {
    /**
     * RVI 命令のデコードステージを生成します。
     *
     * @param c デコードステージの持ち主となる CPU コア
     */
    public DecodeStageRVI(RV64 c) {
        super(c);
    }

    /**
     * RVI 命令のデコードステージの持ち主となる CPU コアを取得します。
     *
     * @return デコードステージの持ち主となる CPU コア
     */
    @Override
    public RV64 getCore() {
        return (RV64)super.getCore();
    }

    /**
     * RISC-V アーキテクチャのビット数を返します。
     *
     * @return RV32 なら 32、RV64 なら 64
     */
    public int getRVBits() {
        return getCore().getRVBits();
    }

    /**
     * 32bit LOAD 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeLoad(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_LOAD_LB:
            return OpIndex.INS_RV32I_LB;
        case InstructionRV32.FUNC_LOAD_LH:
            return OpIndex.INS_RV32I_LH;
        case InstructionRV32.FUNC_LOAD_LW:
            return OpIndex.INS_RV32I_LW;
        case InstructionRV32.FUNC_LOAD_LD:
            if (getRVBits() == 64) {
                return OpIndex.INS_RV64I_LD;
            } else {
                throw new IllegalArgumentException("Unknown LOAD, LD " +
                        String.format("funct3 %d. RV%d", funct3, getRVBits()));
            }
        case InstructionRV32.FUNC_LOAD_LBU:
            return OpIndex.INS_RV32I_LBU;
        case InstructionRV32.FUNC_LOAD_LHU:
            return OpIndex.INS_RV32I_LHU;
        case InstructionRV32.FUNC_LOAD_LWU:
            if (getRVBits() == 64) {
                return OpIndex.INS_RV64I_LWU;
            } else {
                throw new IllegalArgumentException("Unknown LOAD, LWU " +
                        String.format("funct3 %d. RV%d", funct3, getRVBits()));
            }
        default:
            throw new IllegalArgumentException("Unknown LOAD " +
                    String.format("funct3 %d.", funct3));
        }
    }

    /**
     * 32bit MISC-MEM 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeMiscMem(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_MISC_MEM_FENCE:
            return OpIndex.INS_RV32I_FENCE;
        case InstructionRV32.FUNC_MISC_MEM_FENCE_I:
            return OpIndex.INS_RV32I_FENCE_I;
        default:
            throw new IllegalArgumentException("Unknown MISC-MEM " +
                    String.format("funct3 %d.", funct3));
        }
    }

    /**
     * 32bit OP-IMM 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeOpImm(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_OP_IMM_ADDI:
            return OpIndex.INS_RV32I_ADDI;
        case InstructionRV32.FUNC_OP_IMM_SLTI:
            return OpIndex.INS_RV32I_SLTI;
        case InstructionRV32.FUNC_OP_IMM_SLTIU:
            return OpIndex.INS_RV32I_SLTIU;
        case InstructionRV32.FUNC_OP_IMM_XORI:
            return OpIndex.INS_RV32I_XORI;
        case InstructionRV32.FUNC_OP_IMM_ORI:
            return OpIndex.INS_RV32I_ORI;
        case InstructionRV32.FUNC_OP_IMM_ANDI:
            return OpIndex.INS_RV32I_ANDI;
        case InstructionRV32.FUNC_OP_IMM_SLLI:
            if (getRVBits() == 64) {
                int imm6 = inst.getImm6I();

                if (imm6 == 0) {
                    //RV64I SLLI
                    return OpIndex.INS_RV64I_SLLI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SLI 64bit " +
                        String.format("imm6 0x%x.", imm6));
            } else if (getRVBits() == 32) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV32I SLLI
                    return OpIndex.INS_RV32I_SLLI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SLI 32bit " +
                        String.format("imm7 0x%x.", imm7));
            }

            throw new IllegalArgumentException("Unknown OP-IMM SLI " +
                    String.format("%dbit.", getRVBits()));
        case InstructionRV32.FUNC_OP_IMM_SRLI_SRAI:
            if (getCore().getRVBits() == 64) {
                int imm6 = inst.getImm6I();

                if (imm6 == 0) {
                    //RV64I SRLI (imm6 = 0b000000)
                    return OpIndex.INS_RV64I_SRLI;
                } else if (imm6 == 16) {
                    //RV64I SRAI (imm6 = 0b010000)
                    return OpIndex.INS_RV64I_SRAI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SRI 64bit " +
                        String.format("imm6 0x%x.", imm6));
            } else if (getRVBits() == 32) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV32I SRAI (imm7 = 0b0100000)
                    return OpIndex.INS_RV32I_SRLI;
                } else if (imm7 == 32) {
                    //RV32I SRAI (imm7 = 0b0100000)
                    return OpIndex.INS_RV32I_SRAI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SRI 32bit " +
                        String.format("imm7 0x%x.", imm7));
            }

            throw new IllegalArgumentException("Unknown OP-IMM SRI " +
                    String.format("%dbit.", getRVBits()));
        default:
            throw new IllegalArgumentException("Unknown OP-IMM " +
                    String.format("funct3 %d.", funct3));
        }
    }

    /**
     * OP-IMM-32 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeOpImm32(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_OP_IMM_32_ADDIW:
            return OpIndex.INS_RV64I_ADDIW;
        case InstructionRV32.FUNC_OP_IMM_32_SLLIW:
            if (getRVBits() == 64) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV64I SLLIW
                    return OpIndex.INS_RV64I_SLLI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM-32 SLLIW 64bit " +
                        String.format("imm7 0x%x.", imm7));
            }

            throw new IllegalArgumentException("Unknown OP-IMM-32 SLLIW " +
                    String.format("%dbit.", getRVBits()));
        case InstructionRV32.FUNC_OP_IMM_32_SRLIW_SRAIW:
            if (getRVBits() == 64) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV64I SRLIW
                    return OpIndex.INS_RV64I_SRLIW;
                } else if (imm7 == 32) {
                    //RV64I SRAIW (imm7 = 0b0100000)
                    return OpIndex.INS_RV64I_SRAIW;
                }

                throw new IllegalArgumentException("Unknown OP-IMM-32 SRLIW/SRAIW 64bit " +<commit_msg>riscv: fix decode of slliw instruction<commit_after>package net.katsuster.ememu.riscv.core;

import net.katsuster.ememu.generic.*;

public class DecodeStageRVI extends Stage64 {
    /**
     * RVI 命令のデコードステージを生成します。
     *
     * @param c デコードステージの持ち主となる CPU コア
     */
    public DecodeStageRVI(RV64 c) {
        super(c);
    }

    /**
     * RVI 命令のデコードステージの持ち主となる CPU コアを取得します。
     *
     * @return デコードステージの持ち主となる CPU コア
     */
    @Override
    public RV64 getCore() {
        return (RV64)super.getCore();
    }

    /**
     * RISC-V アーキテクチャのビット数を返します。
     *
     * @return RV32 なら 32、RV64 なら 64
     */
    public int getRVBits() {
        return getCore().getRVBits();
    }

    /**
     * 32bit LOAD 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeLoad(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_LOAD_LB:
            return OpIndex.INS_RV32I_LB;
        case InstructionRV32.FUNC_LOAD_LH:
            return OpIndex.INS_RV32I_LH;
        case InstructionRV32.FUNC_LOAD_LW:
            return OpIndex.INS_RV32I_LW;
        case InstructionRV32.FUNC_LOAD_LD:
            if (getRVBits() == 64) {
                return OpIndex.INS_RV64I_LD;
            } else {
                throw new IllegalArgumentException("Unknown LOAD, LD " +
                        String.format("funct3 %d. RV%d", funct3, getRVBits()));
            }
        case InstructionRV32.FUNC_LOAD_LBU:
            return OpIndex.INS_RV32I_LBU;
        case InstructionRV32.FUNC_LOAD_LHU:
            return OpIndex.INS_RV32I_LHU;
        case InstructionRV32.FUNC_LOAD_LWU:
            if (getRVBits() == 64) {
                return OpIndex.INS_RV64I_LWU;
            } else {
                throw new IllegalArgumentException("Unknown LOAD, LWU " +
                        String.format("funct3 %d. RV%d", funct3, getRVBits()));
            }
        default:
            throw new IllegalArgumentException("Unknown LOAD " +
                    String.format("funct3 %d.", funct3));
        }
    }

    /**
     * 32bit MISC-MEM 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeMiscMem(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_MISC_MEM_FENCE:
            return OpIndex.INS_RV32I_FENCE;
        case InstructionRV32.FUNC_MISC_MEM_FENCE_I:
            return OpIndex.INS_RV32I_FENCE_I;
        default:
            throw new IllegalArgumentException("Unknown MISC-MEM " +
                    String.format("funct3 %d.", funct3));
        }
    }

    /**
     * 32bit OP-IMM 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeOpImm(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_OP_IMM_ADDI:
            return OpIndex.INS_RV32I_ADDI;
        case InstructionRV32.FUNC_OP_IMM_SLTI:
            return OpIndex.INS_RV32I_SLTI;
        case InstructionRV32.FUNC_OP_IMM_SLTIU:
            return OpIndex.INS_RV32I_SLTIU;
        case InstructionRV32.FUNC_OP_IMM_XORI:
            return OpIndex.INS_RV32I_XORI;
        case InstructionRV32.FUNC_OP_IMM_ORI:
            return OpIndex.INS_RV32I_ORI;
        case InstructionRV32.FUNC_OP_IMM_ANDI:
            return OpIndex.INS_RV32I_ANDI;
        case InstructionRV32.FUNC_OP_IMM_SLLI:
            if (getRVBits() == 64) {
                int imm6 = inst.getImm6I();

                if (imm6 == 0) {
                    //RV64I SLLI
                    return OpIndex.INS_RV64I_SLLI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SLI 64bit " +
                        String.format("imm6 0x%x.", imm6));
            } else if (getRVBits() == 32) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV32I SLLI
                    return OpIndex.INS_RV32I_SLLI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SLI 32bit " +
                        String.format("imm7 0x%x.", imm7));
            }

            throw new IllegalArgumentException("Unknown OP-IMM SLI " +
                    String.format("%dbit.", getRVBits()));
        case InstructionRV32.FUNC_OP_IMM_SRLI_SRAI:
            if (getCore().getRVBits() == 64) {
                int imm6 = inst.getImm6I();

                if (imm6 == 0) {
                    //RV64I SRLI (imm6 = 0b000000)
                    return OpIndex.INS_RV64I_SRLI;
                } else if (imm6 == 16) {
                    //RV64I SRAI (imm6 = 0b010000)
                    return OpIndex.INS_RV64I_SRAI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SRI 64bit " +
                        String.format("imm6 0x%x.", imm6));
            } else if (getRVBits() == 32) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV32I SRAI (imm7 = 0b0100000)
                    return OpIndex.INS_RV32I_SRLI;
                } else if (imm7 == 32) {
                    //RV32I SRAI (imm7 = 0b0100000)
                    return OpIndex.INS_RV32I_SRAI;
                }

                throw new IllegalArgumentException("Unknown OP-IMM SRI 32bit " +
                        String.format("imm7 0x%x.", imm7));
            }

            throw new IllegalArgumentException("Unknown OP-IMM SRI " +
                    String.format("%dbit.", getRVBits()));
        default:
            throw new IllegalArgumentException("Unknown OP-IMM " +
                    String.format("funct3 %d.", funct3));
        }
    }

    /**
     * OP-IMM-32 命令をデコードします。
     *
     * @param inst 32bit 命令
     * @return 命令の種類
     */
    public OpIndex decodeOpImm32(InstructionRV32 inst) {
        int funct3 = inst.getFunct3();

        switch (funct3) {
        case InstructionRV32.FUNC_OP_IMM_32_ADDIW:
            return OpIndex.INS_RV64I_ADDIW;
        case InstructionRV32.FUNC_OP_IMM_32_SLLIW:
            if (getRVBits() == 64) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV64I SLLIW
                    return OpIndex.INS_RV64I_SLLIW;
                }

                throw new IllegalArgumentException("Unknown OP-IMM-32 SLLIW 64bit " +
                        String.format("imm7 0x%x.", imm7));
            }

            throw new IllegalArgumentException("Unknown OP-IMM-32 SLLIW " +
                    String.format("%dbit.", getRVBits()));
        case InstructionRV32.FUNC_OP_IMM_32_SRLIW_SRAIW:
            if (getRVBits() == 64) {
                int imm7 = inst.getImm7I();

                if (imm7 == 0) {
                    //RV64I SRLIW
                    return OpIndex.INS_RV64I_SRLIW;
                } else if (imm7 == 32) {
                    //RV64I SRAIW (imm7 = 0b0100000)
                    return OpIndex.INS_RV64I_SRAIW;
                }

                throw new IllegalArgumentException("Unknown OP-IMM-32 SRLIW/SRAIW 64bit " +
{'fraction_non_alphanumeric': 0.09383695047301058, 'fraction_numerical': 0.042153589315525875, 'mean_word_length': 1.511705101327743, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2139868', 'n_tokens_mistral': 5227, 'n_tokens_neox': 4691, 'n_words': 861}