RISC-V निर्देश सेट आर्किटेक्चर (ISA) को कस्टम निर्देशों के साथ विस्तारित करने से विशिष्ट अनुप्रयोगों के लिए प्रदर्शन और अनुकूलन बढ़ सकता है। यह लेख 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
यह कमांड RISC-V टूलचेन का निर्माण करेगा। इसके बाद, हम निम्नलिखित सिंटैक्स और अर्थशास्त्र के साथ “मॉड्यूलो” निर्देश जोड़ेंगे:
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
mod
निर्देश की जांच के लिए objdump
का उपयोग करें:
$ 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;
अंत में, स्पाइक सिम्युलेटर में निर्देश जोड़ने के लिए, 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
में जोड़ें और riscv-isa-sim/spike_main/disasm.cc
में DEFINE_RTYPE(mod);
पंक्ति जोड़ें। फिर, riscv-tools
को फिर से कंपाइल करें। अब, “mod” निर्देश स्पाइक सिम्युलेटर में जोड़ दिया गया है।