包含的文件

iterator.md
constraint.md
riscv-c.cc
riscv-protos.h
riscv-vector-builtins-bases.cc
riscv-vector-builtins-bases.h
riscv-vector-builtins-functions.def
riscv-vector-builtins-shapes.cc
riscv-vector-builtins-shapes.h
riscv-vector-builtins-types.def
riscv-vector-builtins.cc
riscv-vector-builtins.h
riscv.md
vector-iterators.md
vector.md

Acronyms

QI: 8 bits
HI: 16 bits
SI: 32 bits
DI: 64 bits
把一个word(即 32 bit 当成计量单位)四分之一(quarter)、二分之一(half)、双倍(double)。

iterator.md

constraint.md

在 match_operand 中,可以指定操作数约束(operand constraint)。
约束(constraint)对断言(predicate)所允许的操作数进行更详细的描述。

  1. 约束条件可以定义操作数是否可以使用寄存器以及使用何种寄存器。
  2. 说明操作数是否可以是一个内存引用以及其地址类型。
  3. 描述该操作数是都可以是一个立即数常量(immediate)以及其可能的值。
  • GCC 中的约束(constraint)使用字符串(string)表示。
    以下是常见用法(部分夹带RISC-V私货方便自己查询):
    >: memory operand, autoincrement addressing type, including preincrement and postincrement.
    f: floating-point register
    g: general register, memory or integer immediate constant.
    i: Integer immediate operand, sign constant when and after compilering.
    j: SIBCALL_REGS
    l: JALR_REGS
    n: known value integer immediate operand
    p: memory address operand
    x: all operand
    I: 12-bit integer signed immediate J: integer zero
    K: 5-bit unsigned immediate for CSR access instructions
    L: U-type 20-bit signed immediate
    Ds3: 1, 2 or 3 immediate
    DsS: 31 immediate
    DsD: 63 immediate
    DbS:
    DnS:
    D03: 0, 1, 2 or 3 immediate
    DsA: 0 - 10 immediate
    G:
    A: An address that is held in a general-purpose register.
    S: A constraint that matches an absolute symbolic address.
    U: A PLT-indirect call address.
    T:
    vr: vector register
    vd: vector register except mask register
    vm: vector mask register
    vp: poly int
    vu: undefined vector value
    vi: vector 5-bit signed immediate
    vj: vector negated 5-bit signed immediate
    vk: vector 5-bit unsigned immediate
    Wc0: vector of immediate all zeros
    Wc1: vector of immediate all ones
    Wb1: BOOL vector of {…,0,…0,1}
    Wdm: Vector duplicate memory operand
    th_f_fmv: floating-point register for XTheadFmv
    th_r_fmv: integer register for XTheadFmv
    vmWc1:
    vector mask register + a vector of immediate all ones
    rK:
    register operand using general register + 5-bit unsigned immediate for CSR access instructiosn
  • 约束修饰字符 (Constraint Modifier Characters)
    =:操作数只写
    +:操作可读可写
    &:在某些约束选择(constraint alternative)中,该操作数是前面某个clobber的操作数,作为指令的输入操作数,该操作数在指令结束之前它的值已经被修改,因此,该操作数可能不在原来使用的寄存器或内存地址中存储
    %:可交换,该操作数及其之后的操作数可以进行交换
    eg. 操作数1的约束为 ‘%0’,表示与操作数0的约束相同。
    #:直到逗号的所有字符在进行约束处理时将被忽略,这些字符只对寄存器选择起作用
    *: 直到逗号的所有字符在进行约束处理是将被忽略,这些字符在寄存器选择是也将被忽略。

riscv-c.cc

#define builtin_define(TXT) cpp_define (pfile, TXT) 定义 builtin_define 的宏,将其展开为 cpp_define(pfile, TXT)。其中 pfile 是指向文件的指针。 riscv_ext_version 函数,可以传一个最大值和一个最小值,返回 1000000倍的最大值和 1000倍的最小值。 riscv_cpu_cpp_builtins 函数,传入 pfile 指针,

riscv-vector-builtins-bases.h

包含所有向量操作的namespace,声明外部的常量指针。

riscv-vector-builtins-bases.cc

声明 load store 的 enum 类型,定义了 unit stride, strided 和 indexed 三种。indexed 没有跟着 spec 写 indexed-unordered 和 indexed-ordered。 定义了一个 vleff 和 vlsegff 的辅助函数去fold。调用 gcc/gimple.h 里面的 gimple_call_num_args.

/* Return the number of arguments used by call statement GS.  */
inline unsigned
gimple_call_num_args (const gcall *gs)
{
 return gimple_num_ops (gs) - 3;
}

inline unsigned
gimple_call_num_args (const gimple *gs)
{
 const gcall *gc = GIMPLE_CHECK2<const gcall *> (gs);
 return gimple_call_num_args (gc);
}

gcc/gimple.cc 里面的 gimple_build_call_vec 函数

/* Build a GIMPLE_CALL statement to function FN with the arguments
   specified in vector ARGS.  */

gcall *
gimple_build_call_vec (tree fn, const vec<tree> &args)
{
  unsigned i;
  unsigned nargs = args.length ();
  gcall *call = gimple_build_call_1 (fn, nargs);

  for (i = 0; i < nargs; i++)
    gimple_call_set_arg (call, i, args[i]);

  return call;
}

gcc/gimple.h 里的 gimple_call_arg 函数

/* Return the argument at position INDEX for call statement GS.  */

inline tree
gimple_call_arg (const gcall *gs, unsigned index)
{
  gcc_gimple_checking_assert (gimple_num_ops (gs) > index + 3);
  return gs->op[index + 3];
}

实现 vsetvl 和 vsetvlmax

实现运算的操作看起来都是根据操作数类型转到对应的rtl.

riscv-vector-builtins-functions.def

写 RVV intrinsic function 的名称,是否mask, 操作数符号和类型之类的。

riscv-vector-builtins-shapes.cc

定义函数 shape NAME, 指向类<NAME>_def实例。
存在 rvv 0.7 的类定义,但是继承自 misc_def 结构体,misc_def 结构体继承自 build_base 结构体, build_base 结构体继承自 function_shape 类。

function_shape 类
/* vget_def class.  */
struct vget_def : public misc_def
{
 bool check (function_checker &c) const override
 {
   poly_int64 outer_size = GET_MODE_SIZE (c.arg_mode (0));
   poly_int64 inner_size = GET_MODE_SIZE (c.ret_mode ());
   unsigned int nvecs = exact_div (outer_size, inner_size).to_constant ();
   return c.require_immediate (1, 0, nvecs - 1);
 }
};

写intrinsic function的格式

/* Declare the function shape NAME, pointing it to an instance
  of class <NAME>_def.  */
#define SHAPE(DEF, VAR) \
 static CONSTEXPR const DEF##_def VAR##_obj; \
 namespace shapes { const function_shape *const VAR = &VAR##_obj; }

riscv-vector-builtins-shapes.h

在 riscv_vector 的命名空间里声明 shapes 的命名空间

riscv-vector-builtins-types.def

定义数据类型的宏

riscv-vector-builtins.cc

看起来是在写intrinsic格式。

riscv-vector-builtins.h

riscv_vector 这个命名空间包括:
1.描述函数做什么的标识和读函数参数返回结果
2.定义用来识别RVV intrinsic需要的拓展的位值的宏
3.枚举 RVV 操作类型
4. 声明 intrinsic 用到的数据类型,后缀的结构体。
function_base 类的定义
function_checker 类的定义
function_shape 类的定义
machine mode
规定 intrinsic 特殊要求的bit表示
bit values 是哪里规定的呢?Full ‘V’ extension是什么呢?
inline machine_mode 是什么呢?之前看《编译原理》还有有个inline相关的参数,但是太久没继续看,已经忘得只剩下inline这个单词了。vector type 和 index type 跟 machine_mode 有什么关系呢?

/* Bit values used to identify required extensions for RVV intrinsics.  */
#define RVV_REQUIRE_RV64BIT (1 << 0)	/* Require RV64.  */
#define RVV_REQUIRE_ELEN_64 (1 << 1)	/* Require TARGET_VECTOR_ELEN_64.  */
#define RVV_REQUIRE_ELEN_FP_32 (1 << 2) /* Require FP ELEN >= 32.  */
#define RVV_REQUIRE_ELEN_FP_64 (1 << 3) /* Require FP ELEN >= 64.  */
#define RVV_REQUIRE_FULL_V (1 << 4) /* Require Full 'V' extension.  */
#define RVV_REQUIRE_MIN_VLEN_64 (1 << 5)	/* Require TARGET_MIN_VLEN >= 64.  */
#define RVV_REQUIRE_ELEN_FP_16 (1 << 6) /* Require FP ELEN >= 32.  */
用到的 rtx 种类

use_exact_ins
use_contiguous_load_insn use_contiguous_store_insn
use_compare_insn
use_ternop_ins
use_widen_ternop_insn
use_scalar_move_insn
generate_insn

machine mode

vector mode
index mode
arg mode
mask mode
ret mode

riscv.md

写 vector 相关的 rtl

attribute

has_vtype_op
在 gcc/config/riscv/riscv-vsetvl.cc 里定义的 bool 值。判断RVV指令是否会用到 VTYPE 全局状态寄存器。
(define_attr "has_vtype_op" "false,true" 表示 rtl 里面的 has_vtype_op 可以取到 false 或者 true。

vector-iterators.md

define_mode_iterator rtl
define_code_attr

vector.md

  • 属性(Attribute)定义:
    has_vtype_op
    has_vl_op
    sew
    lmul
    ratio:sew/lmul
    merge_op_idx: “The index of operand[] to get the merge op.”
    vl_op_idx: “The index of operand[] to get the avl op.”
    ta: tail agnostic
    ma: mask agnostic
    avl_type
    vxrm_mode: fix-point. rnu,rne,rdn,rod,none
    frm_mode: float-point.
  • 指令模板(Insn Pattern)定义: vlmax_avl
    vxrmsi
    fsrmsi_backup
    fsrmsi_restore