[llvm-dev] Public review for RISC-V psABI v1.0-rc1

Kito Cheng via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 11 05:54:04 PST 2022


Hi Madhur:

Thanks for your review comment.

> 1. XLEN should be defined somewhere for the sake of completeness. The first occurrence of this word happens in "Integer Calling Convention" and the reader has no clue of what it means. If the reader is supposed to read some other manual (e.g. ISA manual) then it should be mentioned in a new prerequisites section.

That's a good catch, although that's a common term used in the RISC-V
world, but it definitely worth defining that clearly before use!

> 2. I feel the allocation of aggregates to registers/stack needs to be explained in detail in "Integer Register Convention". Specifically,
> "if only one register is available, the first half is passed in a register and the second half is passed on the stack."
> a. How is the first "half" supposed to be calculated? Size of an aggregate need not be an even value.

The size might not be even, and the first half might be imprecise
here, that should be first XLEN bits, given following (weird) case:

$ clang -target riscv64-elf x.c -O3 -o - -S -march=rv32gc -mabi=ilp32
```
struct X {
   short x;
   int y;
} __attribute__ ((packed));

int foo(int a0, int a1, int a2, int a3, int a4, int a5, int a6, struct X a7)
{
   return a7.y;
}
```
First 32 bits of struct X will hold in a7 registre and the remaining
16 bits will be put on stack.

I guess the wording should be revised to prevent confusion, thanks for
pointing out this!

> b. As one iterates over the fields of the aggregate, the fields will get allocated to the bits in the available register. What if at a given field there is no space in the current register? Would ABI > allocate the field to the next register?

Yes, the value will splitted into two registers, give an example to demo that:

$ clang -target riscv64-elf x.c -O3 -o - -S -march=rv32gc -mabi=ilp32
```
struct X {
   short x;
   int y;
} __attribute__ ((packed));

int bar(struct X a7)
{
   return a7.y;
}
```

The first argument register will hold `x` and the first half of `y`,
and the remaining half will hold in the second argument register.

> 3. Isn't there a need to standardize stack frame layout?

The ABI/calling convention only cares about the interface between
different functions, e.g. how to pass/return value, the stack point
must be aligned to N-bits, and the stack argument put in where.

So how stack frame layout isn't effect the interface except the stack
argument, we are trying to don't put too much strong rule here, that
give more freedom on hand-written assembly code to layout their own
stack, otherwise it would be easy to violate :P

Thanks again for giving that feedback!


More information about the llvm-dev mailing list