Cách Thêm Thanh Ghi Đặc Biệt vào ISA trong Gem5

Việc mở rộng tập lệnh (ISA) của RISC-V bằng cách thêm các lệnh tùy chỉnh có thể tăng hiệu suất và tối ưu hóa cho các ứng dụng cụ thể. Bài viết này hướng dẫn cách thêm một lệnh “modulo” vào RISC-V ISA, viết chương trình sử dụng lệnh này, tích hợp vào trình biên dịch RISC-V, và thực thi trên Gem5 và Spike, một trình mô phỏng ISA.

Đầu tiên, cần cài đặt riscv-tools:

$ git clone https://github.com/riscv/riscv-tools.git
$ git submodule update --init --recursive
$ export RISCV=/path/to/install/riscv/toolchain
$ ./build.sh

Lệnh này sẽ xây dựng toolchain RISC-V. Tiếp theo, chúng ta sẽ thêm lệnh “modulo” với cú pháp và ngữ nghĩa như sau:

mod r1, r2, r3 
Semantics: R[r1] = R[r2] % R[r3]

Mở file riscv-opcodes/opcodes và thêm định nghĩa cho lệnh mod:

sra rd rs1 rs2 31..25=32 14..12=5 6..2=0x0C 1..0=3
...
mod rd rs1 rs2 31..25=1 14..12=0 6..2=0x1A 1..0=3
...

Sau đó, chạy lệnh sau để tạo file temp.h:

cat opcodes-pseudo opcodes opcodes-rvc opcodes-rvc-pseudo opcodes-custom | ./parse-opcodes -c > ~/temp.h

Trong file temp.h, tìm hai dòng sau:

#define MATCH_MOD 0x200006b
#define MASK_MOD 0xfe00707f

Thêm hai dòng này vào riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h. Tiếp tục, sửa đổi file riscv-gnu-toolchain/riscv-binutils-gdb/opcodes/riscv-opc.c và thêm dòng sau vào mảng riscv_opcodes[]:

const struct riscv_opcode riscv_opcodes[] = {
    ...,
    {"mod", "I", "rd,rs1,rs2", MATCH_MOD, MASK_MOD, match_opcode, 0},
    ...
};

Biên dịch lại riscv-gnu-toolchain. Bây giờ, hãy viết một chương trình C để kiểm tra:

#include <stdio.h>

int main() {
    int a, b, c;
    a = 5;
    b = 2;
    asm volatile ("mod %[z], %[x], %[y]nt"
                 : [z] "=r" (c)
                 : [x] "r" (a), [y] "r" (b));
    if (c != 1) {
        printf("n[[FAILED]]n");
        return -1;
    }
    printf("n[[PASSED]]n");
    return 0;
}

Biên dịch chương trình bằng trình biên dịch RISC-V đã được sửa đổi:

$ riscv64-unknown-elf-gcc mod.c -o mod

Sử dụng objdump để kiểm tra lệnh mod:

$ riscv64-unknown-elf-objdump -dC mod > mod.dump

Để thêm lệnh vào Gem5, chỉnh sửa arch/riscv/decoder.isa:

0x33: decode FUNCT3 {
    format ROp {
        0x0: decode FUNCT7 {
            0x0: add({{ Rd = Rs1_sd + Rs2_sd; }});
            ...
            0x10: mod({{ Rd = Rs1_sd % Rs2_sd; }});
            ...
        }
       ...
    }
   ...
}

Việc khớp lệnh trong assembler được thực hiện như sau:

((insn ^ op->match) & op->mask) == 0;

Cuối cùng, để thêm lệnh vào trình mô phỏng Spike, sửa đổi riscv-isa-sim/riscv/encoding.h:

#define MATCH_MOD 0x200006b
#define MASK_MOD 0xfe00707f
...
DECLARE_INSN(mod, MATCH_MOD, MASK_MOD)

Tạo file riscv-isa-sim/riscv/insns/mod.h với nội dung:

WRITE_RD(sext_xlen(RS1 % RS2));

Thêm file này vào riscv-isa-sim/riscv/riscv.mk.in và thêm dòng DEFINE_RTYPE(mod); vào riscv-isa-sim/spike_main/disasm.cc. Sau đó, biên dịch lại riscv-tools. Lúc này, lệnh “mod” đã được thêm vào trình mô phỏng Spike.

Comments

No comments yet. Why don’t you start the discussion?

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *