gcc 参数_「博文精选」如何向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宏。

b988160eb9de9a7e2a171f200cfa1d6b.png

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/common/config/riscv/riscv-common.c文件。

在riscv_parse_arch_string函数中,就会分析传入的--march参数,然后设置flags,给flags加上对应的TARGET支持。

模仿c扩展的支持,增加p扩展的支持。

static void

riscv_parse_arch_string (const char *isa, int *flags, location_t loc)

{

riscv_subset_list *subset_list;

subset_list = riscv_subset_list::parse (isa, loc);

if (!subset_list)

return;

if (subset_list->xlen == 32)

*flags &= ~MASK_64BIT;

else if (subset_list->xlen == 64)

*flags |= MASK_64BIT;

*flags &= ~MASK_RVE;

if (subset_list->lookup ("e"))

*flags |= MASK_RVE;

*flags &= ~MASK_MUL;

if (subset_list->lookup ("m"))

*flags |= MASK_MUL;

*flags &= ~MASK_ATOMIC;

if (subset_list->lookup ("a"))

*flags |= MASK_ATOMIC;

*flags &= ~(MASK_HARD_FLOAT | MASK_DOUBLE_FLOAT);

if (subset_list->lookup ("f"))

*flags |= MASK_HARD_FLOAT;

if (subset_list->lookup ("d"))

*flags |= MASK_DOUBLE_FLOAT;

*flags &= ~MASK_RVC;

if (subset_list->lookup ("c"))

*flags |= MASK_RVC;

*flags &= ~MASK_DSP;

if (subset_list->lookup ("p"))

*flags |= MASK_DSP;

if (current_subset_list)

delete current_subset_list;

current_subset_list = subset_list;

}

通过调用subset_list的lookup函数,查看是否有传入对应的指令集架构。如果有的话,在flags中,将对应的MASK给设置上。

五、修改riscv-c.c

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

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

void

riscv_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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值