riscv / riscv-p-spec

RISC-V Packed SIMD Extension
https://jira.riscv.org/browse/RVG-129
Creative Commons Attribution 4.0 International
138 stars 38 forks source link

Problems with parameter type int16_t #141

Open anderslindgren-iar opened 2 years ago

anderslindgren-iar commented 2 years ago

I noticed that the parameter type of instructions like KADDH now is int16_t. In the earlier version of the specification (and in the original AndesDsp specification) this was a 32 bit type.

From the perspective of a compiler it would be better if the type of the parameters were intXLEN_t and the return type correspond to the result, in the case of KADDH, int16_t.

If I understand correctly, in GCC builtin functions doesn't really have a concrete type. However, other compiler provide builtin functions (a.k.a. intrinsic functions) with a type, so it is important that the specification gets this right.

Problem 1 -- More code is emitted

When an argument is specified as, say, int16_t, the compiler will emit code to perform a sign extension of the arguments, unless it can prove that they already are sign extended. For instructions like KADDH this is unnecessary since they only use the lower 16 bits of the input value.

The fact that the intrinsic functions that do return a value is in the correct int16_t range are declared as returning a larger type like int32_t makes it even harder for the compiler.

In this example the result of one kaddh is passed to another kaddh:

res = __rv_kaddh(__rv_kaddh(a, b), c);

Ideally, we would like the generated code to be:

kaddh   t0, a0, a1
kaddh   a0, t0, a2

However, since the inner __rv_kaddh returns a __int32_t and the outer expect an __int16_t, the compiler will emit the following:

kaddh   t0, a0, a1
slli    t0, t0, 0x10        ;; Sign extend
srai    t0, t0, 0x10        ;; ----"----
kaddh   a0, t0, a2

Of course, it is possible design a compiler so that it has more knowledge than the signatures provides, but this would require a lot of additional work.

Problem 2 -- Hard to test out-of-range values

When testing an implementation -- either a device or a simulator, it is important to test all possible values, even the values that are out of range. Unfortunately, since the parameter type is int16_t, the compiler will sign-extend the arguments before the instruction sees them, so this can't be tested.

Of course, tests can be written using other mechanisms, like inline assembler.

Background

I'm currently in the process of adding support for the P extension to IAR Embedded Workbench for RISC-V. This includes support in the assembler, compiler, and simulator. The tools already have support for the original Andes-specific DSP extension.

-- Anders Lindgren, IAR Systems
anderslindgren-iar commented 2 years ago

I have given this some more thought. We will run into other problems is we specify the arguments to be intXLEN_t, so please disregard the idea to change the parameter types.

However, I still think it's a good idea to change the return type of the intrinsic functions.