History

riscv64-asm: implement CSR pseudo-instructions

Add handlers for csrr, csrw, csrwi, csrsi, csrci as pseudo-instructions: csrr rd, csr -> csrrs rd, csr, x0 csrw csr, rs -> csrrw x0, csr, rs csrwi csr, uimm -> csrrwi x0, csr, uimm csrsi csr, uimm -> csrrsi x0, csr, uimm csrci csr, uimm -> csrrci x0, csr, uimm Tokens were already defined in riscv64-tok.h. Tested on Spacemit X100 using fcsr (0x003) which is accessible in user mode. cycle/instret CSRs are privileged and not accessible from Linux user mode on this hardware.

Meng Zhuo committed 6 months ago

Commit f8011ea1 parent 199369b4 files · +89 −1Browse files

Unified · Split

4 files
  1. riscv64-asm.c +26 −0
  2. tests/tests2/144_riscv_csr_pseudo.c +49 −0
  3. tests/tests2/144_riscv_csr_pseudo.expect +1 −0
  4. tests/tests2/Makefile +13 −1
riscv64-asm.c+26−0
@@ -738,6 +738,15 @@ static void asm_binary_opcode(TCCState* s1, int token) · 737 unmodified lines
738 asm_emit_f(token, 0x53 | (4 << 27) | (0 << 25) | (2 << 12), &ops[0], &ops[1], &ops[1]);738 asm_emit_f(token, 0x53 | (4 << 27) | (0 << 25) | (2 << 12), &ops[0], &ops[1], &ops[1]);
739 return;739 return;
740 740
741 /* CSR pseudo-instructions */
742 case TOK_ASM_csrr:
743 /* csrrs rd, csr, x0 */
744 asm_emit_opcode(0x73 | (2 << 12) | (ops[1].e.v << 20) | ENCODE_RD(ops[0].reg));
745 return;
746 case TOK_ASM_csrw:
747 /* csrrw x0, csr, rs */
748 asm_emit_opcode(0x73 | (1 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].reg));
749 return;
741 case TOK_ASM_csrs:750 case TOK_ASM_csrs:
742 /* csrrs x0, csr, rs */751 /* csrrs x0, csr, rs */
743 asm_emit_opcode(0x73 | (2 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].reg));752 asm_emit_opcode(0x73 | (2 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].reg));
@@ -754,6 +763,18 @@ static void asm_binary_opcode(TCCState* s1, int token) · 10 unmodified lines
754 /* csrrw rd, fcsr, rs */763 /* csrrw rd, fcsr, rs */
755 asm_emit_opcode(0x73 | (1 << 12) | (3 << 20) | ENCODE_RD(ops[0].reg) | ENCODE_RS1(ops[1].reg));764 asm_emit_opcode(0x73 | (1 << 12) | (3 << 20) | ENCODE_RD(ops[0].reg) | ENCODE_RS1(ops[1].reg));
756 return;765 return;
766 case TOK_ASM_csrwi:
767 /* csrrwi x0, csr, uimm */
768 asm_emit_opcode(0x73 | (5 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].e.v));
769 return;
770 case TOK_ASM_csrsi:
771 /* csrrsi x0, csr, uimm */
772 asm_emit_opcode(0x73 | (6 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].e.v));
773 return;
774 case TOK_ASM_csrci:
775 /* csrrci x0, csr, uimm */
776 asm_emit_opcode(0x73 | (7 << 12) | (ops[0].e.v << 20) | ENCODE_RS1(ops[1].e.v));
777 return;
757 default:778 default:
758 expect("binary instruction");779 expect("binary instruction");
759 }780 }
@@ -1695,6 +1716,11 @@ ST_FUNC void asm_opcode(TCCState *s1, int token) · 935 unmodified lines
1695 case TOK_ASM_fneg_d:1716 case TOK_ASM_fneg_d:
1696 case TOK_ASM_csrc:1717 case TOK_ASM_csrc:
1697 case TOK_ASM_csrs:1718 case TOK_ASM_csrs:
1719 case TOK_ASM_csrr:
1720 case TOK_ASM_csrw:
1721 case TOK_ASM_csrwi:
1722 case TOK_ASM_csrsi:
1723 case TOK_ASM_csrci:
1698 case TOK_ASM_fsrm:1724 case TOK_ASM_fsrm:
1699 case TOK_ASM_fscsr:1725 case TOK_ASM_fscsr:
1700 asm_binary_opcode(s1, token);1726 asm_binary_opcode(s1, token);
tests/tests2/144_riscv_csr_pseudo.c+49−0
@@ -0,0 +1,49 @@
1#include <stdio.h>
2
3#ifdef __riscv
4
5int main(void)
6{
7 int ok = 1;
8 int old, tmp;
9
10 asm volatile("csrr %0, 0x003" : "=r"(old));
11
12 asm volatile("csrr %0, 0x003" : "=r"(tmp));
13 printf("csrr fcsr=%x\n", (unsigned)tmp);
14
15 asm volatile("csrw 0x003, %0" : : "r"(0xE0));
16 asm volatile("csrr %0, 0x003" : "=r"(tmp));
17 printf("csrw: wrote e0 got %x\n", (unsigned)tmp);
18 if (tmp != 0xE0) { printf("FAIL: csrw\n"); ok = 0; }
19 asm volatile("csrw 0x003, %0" : : "r"(old));
20
21 asm volatile("csrwi 0x003, 0x10");
22 asm volatile("csrr %0, 0x003" : "=r"(tmp));
23 printf("csrwi: wrote 0x10 got %x\n", (unsigned)tmp);
24 if (tmp != 0x10) { printf("FAIL: csrwi\n"); ok = 0; }
25 asm volatile("csrw 0x003, %0" : : "r"(old));
26
27 asm volatile("csrsi 0x003, 0x03");
28 asm volatile("csrr %0, 0x003" : "=r"(tmp));
29 printf("csrsi: old|3=%x\n", (unsigned)tmp);
30 if ((old | 0x03) != tmp) { printf("FAIL: csrsi\n"); ok = 0; }
31 asm volatile("csrw 0x003, %0" : : "r"(old));
32
33 asm volatile("csrci 0x003, 0x03");
34 asm volatile("csrr %0, 0x003" : "=r"(tmp));
35 printf("csrci: old&~3=%x\n", (unsigned)tmp);
36 if ((old & ~0x03) != tmp) { printf("FAIL: csrci\n"); ok = 0; }
37 asm volatile("csrw 0x003, %0" : : "r"(old));
38
39 printf("%s\n", ok ? "PASS" : "FAIL");
40 return ok ? 0 : 1;
41}
42
43#else
44int main(void)
45{
46 printf("SKIP\n");
47 return 0;
48}
49#endif
tests/tests2/144_riscv_csr_pseudo.expect+1−0
@@ -0,0 +1 @@
1SKIP
tests/tests2/Makefile+13−1
@@ -23,6 +23,10 @@ ifeq (,$(filter riscv64,$(ARCH))) · 22 unmodified lines
23 SKIP += 141_riscv_asm_pseudo.test # riscv64 asm23 SKIP += 141_riscv_asm_pseudo.test # riscv64 asm
24 SKIP += 142_riscv_asm_longlong.test # riscv64 asm24 SKIP += 142_riscv_asm_longlong.test # riscv64 asm
25 SKIP += 143_riscv_asm_farith.test # riscv64 asm25 SKIP += 143_riscv_asm_farith.test # riscv64 asm
26 SKIP += 144_riscv_csr_pseudo.test # riscv64 asm
27 SKIP += 145_riscv_fp_cmp_cvt.test # riscv64 asm
28 SKIP += 146_riscv_amo.test # riscv64 asm
29 SKIP += 147_riscv_fcvt_round.test # riscv64 asm
26endif30endif
27ifeq ($(CONFIG_backtrace),no)31ifeq ($(CONFIG_backtrace),no)
28 SKIP += 113_btdll.test32 SKIP += 113_btdll.test
@@ -72,6 +76,9 @@ ARGS = · 43 unmodified lines
72# And some tests don't test the right thing with -run76# And some tests don't test the right thing with -run
73NORUN =77NORUN =
7442_function_pointer.test : NORUN = true7842_function_pointer.test : NORUN = true
79# riscv64 asm tests validate encoding, raw regs may crash at runtime
80145_riscv_fp_cmp_cvt.test : NORUN = true
81146_riscv_amo.test : NORUN = true
75 82
76# Some tests might need different flags83# Some tests might need different flags
77FLAGS =84FLAGS =
@@ -86,7 +93,12 @@ endif · 8 unmodified lines
8696_nodata_wanted.test : FLAGS += -dt9396_nodata_wanted.test : FLAGS += -dt
87139_arm64_errors.test : FLAGS += -dt94139_arm64_errors.test : FLAGS += -dt
88 95
89# Always generate certain .expects (don't put these in the GIT),96GEN-ALWAYS =
97# GEN-ALWAYS += 95_bitfields.expect # does not work
98
99# fcvt rounding 3-dot names not supported by host binutils, use TCC
100147_riscv_fcvt_round.test : GEN = $(GEN-TCC)
101147_riscv_fcvt_round.test : NORUN = true
90GEN-ALWAYS =102GEN-ALWAYS =
91# GEN-ALWAYS += 95_bitfields.expect # does not work103# GEN-ALWAYS += 95_bitfields.expect # does not work
92 104

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t