标签: riscv

如何仅为RV32I基本整数指令和扩展M编译C代码?

几天前我已经开始使用risc-v,但昨天我遇到了问题.问题如下:

我想为RV32I基本整数指令集编译代码,我想添加"M"标准扩展.

当我编译C代码时,我使用以下命令

riscv64-unknown-elf-gcc Program.c -o Program.o -m32 -march=RV32IM
Run Code Online (Sandbox Code Playgroud)

现在,如果我想看到汇编程序代码,我使用

riscv64-unknown-elf-objdump -d Program.c > Program.dump
Run Code Online (Sandbox Code Playgroud)

现在,如果我探索转储文件"Program.dump".我注意到有时会出现汇编指令:

   10c6c:   00a12427            fsw fa0,8(sp)
   10dd0:   00a42023            sd a0,8(sp)
Run Code Online (Sandbox Code Playgroud)

在许多其他情况下.

如果我在第52页看到"RISC-V指令集手册,第I卷:用户级ISA,版本2.0",我发现fsw指令属于RV32F标准扩展和sd指令,它属于RV64I.

出于这个原因,我很困惑,我不知道我的问题是我的编译不好.

我的问题是:如何仅为RV32I基本整数指令和扩展M编译C代码?

riscv

6
推荐指数
1
解决办法
3989
查看次数

实际的RISC-V指令代码在哪里?

我已经下载了最新的...

RISC-V指令集手册,第1卷:用户级ISA

...这很有趣,但是它实际上从未提供操作码/ funct3和其他指令格式的值。例如,按名称列出了LOAD / STORE / BRANCH操作码,但没有提供它们代表的实际位值。

实际列出的所有代码在哪里?

riscv

6
推荐指数
2
解决办法
5747
查看次数

为什么呼叫后GCC for Risc-V会产生nop指令

默认情况下,用于Risc-V的GCC会nop在生成指令后生成指令call

$ cat test.c
void g();
void f() {
        g();
}
$ riscv64-unknown-elf-gcc -S test.c -o -    
[...]
f:
        addi    sp,sp,-16
        sd      ra,8(sp)
        sd      s0,0(sp)
        addi    s0,sp,16
        call    g
        nop #### <-----------here
        ld      ra,8(sp)
        ld      s0,0(sp)
        addi    sp,sp,16
        jr      ra
        .size   f, .-f
        .ident  "GCC: (GNU) 8.3.0"
Run Code Online (Sandbox Code Playgroud)

我希望当针对具有分支延迟时隙的架构时,但是我的理解是Risc-V不是这样的架构。实际上,nop使用-O1或更高版本进行编译时消失。

只是GCC中的“错误”会nop从具有延迟插槽的体系结构中遗留下来,还是有此nop指令的实际原因?

gcc riscv

6
推荐指数
1
解决办法
132
查看次数

GD32VF103龙眼纳米中断不工作

简介:
我买了一块配备GD32VF103 Risc-V MCU的Longan Nano评估板。
我可以运行视频播放器演示,并使用 VS Code、PlatformIO 和 DFU 工具编译和加载工作代码。下面是电路板和演示运行的视频。
在此输入图像描述
https://www.youtube.com/watch?v=84_PzcNiJb4

我想做的
就是为机器人比赛建造一个机器人作为一种爱好。我使用 Microchip 4809 8 位 MCU 作为电机控制器,但在以 2KHz 运行 PID 控制器时达到了 MCU 的极限,而且我还没有添加电流环路。我想升级电机控制器,我决定选择 Longan Nano,因为它有 LCD 屏幕、优越的 CPU 马力以及学习 Risc-V。
https://www.youtube.com/watch?v=1dQMktoiuLg

问题
我可以在轮询中很好地运行 Longan Nano 的外围设备。我真的很努力地想让中断起作用,但没有成功。我尝试读取轮询中断标志,它们就是这样工作的,所以我认为这要么是 ISR 处理程序链接到 Start.s 中的中断向量表的链接器问题,要么是 ECLIC 的配置问题。

这是一个正确运行的轮询示例。红色 LED 以 2Hz 的频率闪烁,按下启动按钮将切换蓝色 LED。

#include <gd32vf103.h>

void init()
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOC);

    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_1);
    gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_2);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,GPIO_PIN_8);

    gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_13);

    gpio_bit_set(GPIOC,GPIO_PIN_13);
    gpio_bit_set(GPIOA,GPIO_PIN_1);
    gpio_bit_set(GPIOA,GPIO_PIN_2);

    rcu_periph_clock_enable(RCU_AF);
    
    eclic_init(ECLIC_NUM_INTERRUPTS);
    
    eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);
    eclic_irq_enable(EXTI5_9_IRQn, 1, 1);

    exti_deinit(); …
Run Code Online (Sandbox Code Playgroud)

c++ microcontroller interrupt interrupt-handling riscv

6
推荐指数
1
解决办法
872
查看次数

为什么 rv32gc 针对 RISC-V 优化带有分支的无分支代码?

让我们尝试定义一个返回两个值 x 和 y 中的最大值的函数。这些公式有效的充分条件是,对于有符号整数,\xe2\x80\x932^30 <= x, y <= 2^30 \xe2\x80\x93 1,对于无符号整数,0 <= x, y <= 2^31 \xe2\x80\x93 1即,只需要处理有效减少一位的缩小整数范围)。最通用(且最简单)的实现是:

\n
int max(int x, int y) {\n    return (x > y) ? x : y\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 Pentium Pro 之前,这将是 x86 中生成的程序集:

\n
max:  # GCC -O3 -march=pentium -m32\n  mov eax, DWORD PTR [esp+8]\n  cmp eax, DWORD PTR [esp+4]\n  jge .L4\n  mov eax, DWORD PTR [esp+4]\n.L4:\n  ret\n
Run Code Online (Sandbox Code Playgroud)\n

但从 Pentium Pro 开始,CMOVcc r32,r/m引入了一条新指令,它根据某些指定的状态标志执行条件移动: …

gcc clang compiler-optimization branch-prediction riscv

6
推荐指数
1
解决办法
460
查看次数

在 RISC-V 中创建引导程序

我正在尝试为基于 RISC-V 的板创建一个引导程序。我正在遵循本指南,并将其调整为 riscv。 osdev

我遇到的问题是翻译这条指令。 times 510 -( $ - $$ ) db 0

我能想到的最好的方法是只填充 63 行,.8byte 0 但这似乎不太可行。

这是完整的代码。

#################################
########### Boot Init ###########
#################################

.section .text

start:                          # begins the program
    nop                         # the do nothing instruction
    j start                     # loops back to start

# Todo:: figure out the size of the np and j instruction
# The intent of this portion is to fill the remaning bin file with 0's up until the last two …
Run Code Online (Sandbox Code Playgroud)

assembly riscv

5
推荐指数
1
解决办法
3062
查看次数

为什么商店说明有自己的格式

加载和存储指令对编码有相同的要求:两个寄存器和一个 12 位立即数。然而,存储指令(sb、sh、sw)具有称为S 型的专用格式,而加载指令使用与 addi 指令相同的I 型格式。

我不明白为什么加载和存储不共享指令格式,但存储只有自己专用的指令格式(S-type)。

riscv

5
推荐指数
1
解决办法
182
查看次数

如何在 RISC-V 程序集中使用数组

我正在学习 RISC-V 汇编,我需要将数组用于我正在解决的练习;问题是我正在使用的模拟器(RARS)给了我一个错误:
Error in /home/username/file_name line 8: Runtime exception at 0x00400010: address out of range 0x000003e8.

这是我到目前为止编写的代码:

.data
arr: .word 1000
e0: .word 5

.text
lw t1, arr # load arr into t1
lw t2, e0 # Load e0 value into t2
sw t2, 0(t1) # save t2 value into arr[0]
Run Code Online (Sandbox Code Playgroud)

我在做什么错?

assembly riscv

5
推荐指数
1
解决办法
5365
查看次数

为什么在RISC-V中建议只使用寄存器a0和a1来传递返回值?

RISC-V 调用约定规定寄存器 a0 和 a1 可用于返回值,而不是所有 8 个寄存器 a0~a7。当需要“返回”两个以上的值时,我们可以使用堆栈。为什么?这样做有什么好处吗?

我正在学习 RISC-V 语言,作为计算机体系结构研究的一部分。我注意到我们可以使用所有八个 a0~a7 寄存器将参数传递给函数,但根据一些 RISC-V 调用约定,只有其中两个(a0 和 a1)可用于返回返回值,例如了解 RISC-V 调用约定RISC-V 调用约定。我很困惑为什么约定包含只有 a0 和 a1 应该用于返回的规则。我浏览了上面提到的两篇文章,但没有找到任何解释这一点的内容。在我看来,这些a0~a7寄存器在函数调用之间不被保留,这表明我们可以在函数中自由地使用它们。因此,如果需要,我们可以而且应该使用它们中的任何一个来传递返回值,以方便和高效。总之,有什么理由要求我们限制返回值到a0和a1寄存器吗?

PS我刚刚注意到这个问题Whytworeturnregisters(inmanyprocedurecallsconventions/ABIs),它告诉我连续的寄存器可以用于大数字。然而,我的观点是,为什么我们限制自己在a2~a7中放入更多的返回值,即使看起来没有明显的缺点?或者,如果我使用a2~a7作为返回值,违反约定,会不会很糟糕?

assembly calling-convention riscv

5
推荐指数
1
解决办法
1075
查看次数

RISC-V处理器中是否有CSR寄存器显示当前PC值?

我们正在做一个项目,其中arm64处理器是主处理器,加速器设备内部有RISC-V。并且可以从ARM64处理器访问RISC-V处理器的CSR寄存器(地址映射)。顺便说一句,我们的设计人员出于我们的目的定义并添加了一些 CSR 寄存器。

RISC-V处理器中是否有CSR寄存器显示当前PC值?或者只能从 RISC-V 内核内部使用auipc x1, 0设置 RISC-V 寄存器之类的指令来读取 PC?我发现一些CSR寄存器是为异常PC或陷阱向量定义的,但在CSR寄存器列表中找不到当前的真实PC值。

我想读取RISC-V内核的PC值,看看RISC-V指令是否正在处理。但是,如果 PC 值未反映在这些 CSR 寄存器之一中,我将无法从 arm64 处理器读取 PC 值。我的理解正确吗?

assembly riscv

5
推荐指数
0
解决办法
73
查看次数