إضافة تعليمة خاصة إلى ISA في Gem5

يمكن لتوسيع مجموعة تعليمات RISC-V عن طريق إضافة تعليمات مخصصة أن يزيد من الأداء ويحسّن التطبيقات الخاصة. يوضح هذا المقال كيفية إضافة تعليمة “modulo” إلى RISC-V ISA، وكتابة برنامج يستخدم هذه التعليمة، ودمجها في مترجم RISC-V، وتنفيذها على Gem5 و Spike، وهو مُحاكي ISA.

أولاً، يجب تثبيت 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

ستقوم هذه الأوامر ببناء toolchain RISC-V. بعد ذلك، سنضيف تعليمة “modulo” بالصياغة والدلالات التالية:

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

افتح ملف riscv-opcodes/opcodes وأضف تعريفًا لتعليمة 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
...

بعد ذلك، قم بتشغيل الأمر التالي لإنشاء ملف temp.h:

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

في ملف temp.h، ابحث عن السطرين التاليين:

#define MATCH_MOD 0x200006b
#define MASK_MOD 0xfe00707f

أضف هذين السطرين إلى riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h. تابع، وقم بتعديل ملف riscv-gnu-toolchain/riscv-binutils-gdb/opcodes/riscv-opc.c وأضف السطر التالي إلى مصفوفة riscv_opcodes[]:

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

قم بإعادة ترجمة riscv-gnu-toolchain. الآن، لنكتب برنامج C للاختبار:

#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;
}

قم بترجمة البرنامج باستخدام مترجم RISC-V الذي تم تعديله:

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

استخدم objdump للتحقق من تعليمة mod:

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

لإضافة التعليمة إلى Gem5، قم بتحرير 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; }});
            ...
        }
       ...
    }
   ...
}

يتم مطابقة التعليمة في المُجمّع كما يلي:

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

أخيرًا، لإضافة التعليمة إلى مُحاكي Spike، قم بتعديل riscv-isa-sim/riscv/encoding.h:

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

أنشئ ملف riscv-isa-sim/riscv/insns/mod.h بالمحتوى التالي:

WRITE_RD(sext_xlen(RS1 % RS2));

أضف هذا الملف إلى riscv-isa-sim/riscv/riscv.mk.in وأضف السطر DEFINE_RTYPE(mod); إلى riscv-isa-sim/spike_main/disasm.cc. بعد ذلك، أعد ترجمة riscv-tools. الآن، تمت إضافة تعليمة “mod” إلى مُحاكي Spike.

Comments

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *