全部 行业新闻 技术前沿 新品发布

riscv-gcc自定义编译器内置宏

oomdy
发表于 2020-05-12 21:19:33


如何向riscv-gcc中增加编译器内置宏





在学习riscv架构的过程中,riscv-gcc工具能给我们提供很多的帮助,其内置的一些宏参数。可以帮助我们判断编译器的行为。如何向riscv-gcc中增加编译器内置宏呢?


查看gcc内置宏参数




这里以芯来科技发布的riscv-nuclei-elf-gcc工具链为例。

使用以下命令,可以得到该工具的内置宏参数:

riscv-nuclei-elf-gcc -E -dM a.h | grep riscv


可以得到如下的一些宏参数


#define __riscv 1#define __riscv_atomic 1#define __riscv_cmodel_medlow 1#define __riscv_fdiv 1#define __riscv_float_abi_double 1#define __riscv_flen 64#define __riscv_compressed 1#define __riscv_mul 1#define __riscv_muldiv 1#define __riscv_xlen 32#define __riscv_fsqrt 1#define __riscv_div 1

从内置宏参数,可以看出编译器,默认支持RV64IMAFDC指令集架构。


如果使用以下命令:

riscv-nuclei-elf-gcc -march=rv32gc -mabi=ilp32 -E -dM a.h | grep riscv


得到如下结果:

#define __riscv 1#define __riscv_atomic 1#define __riscv_cmodel_medlow 1#define __riscv_float_abi_soft 1#define __riscv_fdiv 1#define __riscv_flen 64#define __riscv_compressed 1#define __riscv_mul 1#define __riscv_muldiv 1#define __riscv_xlen 32#define __riscv_fsqrt 1#define __riscv_div 1


从内置宏参数,可以看出编译器,支持RV32IMAFDC指令集架构。

增加内置宏参数




对于riscv,支持p扩展,该扩展,是针对于dsp应用。

如果我们想,当gcc的-march选项中,有指定p扩展指令集,那么编译器就内置__riscv_dsp宏。如果没有指定p扩展指令集,就不内置该__riscv_dsp宏。

这样的话,编写的dsp程序,就可以使用该宏判断,是否支持p扩展指令。

下面简述一下,如何实现该功能,也就是如何根据所传参指令集架构参数,增加内置宏参数。

这里,主要是参考riscv-gcc的如下commit:

https://github.com/riscv/riscv-gcc/commit/06ab742f982d23488ec2d8c0266cb720fe775f7c

该commit,是往riscv-gcc中增加RV32E的支持。


修改riscv.opt




首先是修改 gcc/config/riscv/riscv.opt文件,在其中,增加DSP宏。



gcc的脚本工具,会处理该文件,通过Mask展开,定义新的宏参数。


  • MASK_DSP

  • TARGET_DSP

在编译目录下的 gcc/options.h 文件中,有该宏参数定义。

TARGET和MASK宏的定义

#define MASK_DIV (1U << 0)#define MASK_EXPLICIT_RELOCS (1U << 1)#define MASK_FDIV (1U << 2)#define MASK_SAVE_RESTORE (1U << 3)#define MASK_STRICT_ALIGN (1U << 4)#define MASK_64BIT (1U << 5)#define MASK_ATOMIC (1U << 6)#define MASK_DOUBLE_FLOAT (1U << 7)#define MASK_DSP (1U << 8)#define MASK_HARD_FLOAT (1U << 9)#define MASK_MUL (1U << 10)#define MASK_RVC (1U << 11)#define MASK_RVE (1U << 12)
#define TARGET_DIV ((target_flags & MASK_DIV) != 0)#define TARGET_DIV_P(target_flags) (((target_flags) & MASK_DIV) != 0)#define TARGET_EXPLICIT_RELOCS ((target_flags & MASK_EXPLICIT_RELOCS) != 0)#define TARGET_EXPLICIT_RELOCS_P(target_flags) (((target_flags) & MASK_EXPLICIT_RELOCS) != 0)#define TARGET_FDIV ((target_flags & MASK_FDIV) != 0)#define TARGET_FDIV_P(target_flags) (((target_flags) & MASK_FDIV) != 0)#define TARGET_SAVE_RESTORE ((target_flags & MASK_SAVE_RESTORE) != 0)#define TARGET_SAVE_RESTORE_P(target_flags) (((target_flags) & MASK_SAVE_RESTORE) != 0)#define TARGET_STRICT_ALIGN ((target_flags & MASK_STRICT_ALIGN) != 0)#define TARGET_STRICT_ALIGN_P(target_flags) (((target_flags) & MASK_STRICT_ALIGN) != 0)#define TARGET_64BIT ((target_flags & MASK_64BIT) != 0)#define TARGET_ATOMIC ((target_flags & MASK_ATOMIC) != 0)#define TARGET_DOUBLE_FLOAT ((target_flags & MASK_DOUBLE_FLOAT) != 0)#define TARGET_DSP ((target_flags & MASK_DSP) != 0)#define TARGET_HARD_FLOAT ((target_flags & MASK_HARD_FLOAT) != 0)#define TARGET_MUL ((target_flags & MASK_MUL) != 0)#define TARGET_RVC ((target_flags & MASK_RVC) != 0)#define TARGET_RVE ((target_flags & MASK_RVE) != 0)

这里的options.h文件,是gcc的内置脚本生成的,目前我还没有研究清楚该脚本是如何工作生成的。

修改riscv-common.c



修改 gcc/config/riscv/riscv-c.c 文件。增加内置宏。

该文件中的riscv_cpu_cpp_builtins函数,就是增加内置宏参数的函数。

voidriscv_cpu_cpp_builtins (cpp_reader *pfile){ builtin_define ("__riscv");
if (TARGET_RVC) builtin_define ("__riscv_compressed");
if (TARGET_RVE) builtin_define ("__riscv_32e");
if (TARGET_ATOMIC) builtin_define ("__riscv_atomic");
if (TARGET_MUL) builtin_define ("__riscv_mul");if (TARGET_DIV) builtin_define ("__riscv_div");if (TARGET_DIV && TARGET_MUL) builtin_define ("__riscv_muldiv");
if (TARGET_DSP) builtin_define ("__riscv_dsp");
builtin_define_with_int_value ("__riscv_xlen", UNITS_PER_WORD * 8);if (TARGET_HARD_FLOAT) builtin_define_with_int_value ("__riscv_flen", UNITS_PER_FP_REG * 8);
if (TARGET_HARD_FLOAT && TARGET_FDIV) { builtin_define ("__riscv_fdiv"); builtin_define ("__riscv_fsqrt"); }
switch (riscv_abi) {case ABI_ILP32E: builtin_define ("__riscv_abi_rve"); gcc_fallthrough ();
case ABI_ILP32:case ABI_LP64: builtin_define ("__riscv_float_abi_soft");break;
case ABI_ILP32F:case ABI_LP64F: builtin_define ("__riscv_float_abi_single");break;
case ABI_ILP32D:case ABI_LP64D: builtin_define ("__riscv_float_abi_double");break; }
switch (riscv_cmodel) {case CM_MEDLOW: builtin_define ("__riscv_cmodel_medlow");break;
case CM_MEDANY: builtin_define ("__riscv_cmodel_medany");break;
case CM_PIC: builtin_define ("__riscv_cmodel_pic");break; }}

在其中加上我们要加的代码:


if (TARGET_DSP)   builtin_define ("__riscv_dsp");

因为之前flags,已经设置了MASK_DSP,而TARGET_DSP宏定义如下:

#define TARGET_DSP ((target_flags & MASK_DSP) != 0)

如果该宏的返回值不为0,表示-march有传入p扩展指令集,因此就会调用builtin_define函数,定义__riscv_dsp宏。


如果该宏的返回值为0,表示-march没有传入p扩展指令集,因此就不会调用builtin_define函数,定义__riscv_dsp宏。

测试




重新编译riscv-gcc工具链。然后进行测试,使用如下命令:

riscv-nuclei-elf-gcc -march=rv64gcp -mabi=lp64 -E -dM a.h  | grep riscv

得到:

#define __riscv 1#define __riscv_atomic 1#define __riscv_cmodel_medlow 1#define __riscv_float_abi_soft 1#define __riscv_fdiv 1#define __riscv_flen 64#define __riscv_compressed 1#define __riscv_mul 1#define __riscv_muldiv 1#define __riscv_xlen 64#define __riscv_fsqrt 1#define __riscv_div 1#define __riscv_dsp 1

从结果可以看出,有__riscv_dsp宏,使用如下命令:

riscv-nuclei-elf-gcc -march=rv64gc -mabi=lp64 -E -dM a.h  | grep riscv

得到:


#define __riscv 1#define __riscv_atomic 1#define __riscv_cmodel_medlow 1#define __riscv_float_abi_soft 1#define __riscv_fdiv 1#define __riscv_flen 64#define __riscv_compressed 1#define __riscv_mul 1#define __riscv_muldiv 1#define __riscv_xlen 64#define __riscv_fsqrt 1#define __riscv_div 1

从结果可以看出,没有__riscv_dsp宏

总结



以上就完成了向riscv-gcc中增加编译器自带宏。如果单纯加一个宏,和任何参数没有关系,那么直接修改riscv-common.c文件,在riscv_cpu_cpp_builtins函数中,直接调用builtin_define函数,定义内置宏。如果加的宏,和-march参数有关系,那么可以按照上述的流程,进行修改,增加内置宏。

RISC-V中文社区致力于RISC-V技术的推广

为广大RISC-V爱好者提供一个交流学习的开放平台

社区长期欢迎您以各种方式来与我们互动

社区网址:www.rvmcu.com

往期精彩回顾




国产RISC-V开发板RV-STAR初体验
放假不忘学习--蜂鸟E203开发实战
RISC-V处理器设计课程(7)低功耗机制与可扩展协处理器
RISC-V处理器设计系列课程(6)蜂鸟E203异常与中断
RISC-V处理器设计系列课程(5)蜂鸟E203存储器架构
RISC-V处理器设计课程(4)蜂鸟E203指令流水线设计
RISC-V处理器设计系列课程(3)蜂鸟E203设计概况
RISC-V处理器设计系列课程(2)RISC-V架构基础
RISC-V处理器设计系列课程(1)CPU基础知识


点击”阅读原文”获取更多信息



546 0

你的回应

关注我们

微信扫码登录 点击刷新二维码