RISC-V C API Documentation

275 views
Skip to first unread message

Palmer Dabbelt

unread,
Jun 7, 2018, 8:00:41 PM6/7/18
to sw-...@groups.riscv.org, Alex Bradbury
Alex recently pointed out that some C API additions landed in GCC that he
hadn't noticed. We'd really like to maintain API compatibility between all
RISC-V compilers (GCC, LLVM, and the various commercial/internal compilers) and
the only way that's going to be feasible will be to document things outside of
the GCC source tree.

I've gone ahead and created a bare-bones document for this

https://github.com/riscv/riscv-c-api-doc/blob/master/riscv-c-api.md

It's meant to look just like the other docs that we have, the ones I can
remember are:

https://github.com/riscv/riscv-elf-psabi-doc
https://github.com/riscv/riscv-asm-manual
https://github.com/riscv/riscv-device-tree-doc

These documents are less formal the ISA specification as they're meant to deal
explicitly with various software implementation details. In general we try to
write up a description of any interface that gets added to the RISC-V software
stack around the same time as it's implemented the first time, but as you can
see the documentation is a bit lacking.

If you're interested in helping out the RISC-V software ecosystem then
documentation is a great way to get started!

Jim Wilson

unread,
Jun 7, 2018, 9:03:19 PM6/7/18
to Palmer Dabbelt, RISC-V SW Dev, Alex Bradbury
On Thu, Jun 7, 2018 at 5:00 PM, Palmer Dabbelt <pal...@sifive.com> wrote:
> Alex recently pointed out that some C API additions landed in GCC that he
> hadn't noticed. We'd really like to maintain API compatibility between all
> RISC-V compilers (GCC, LLVM, and the various commercial/internal compilers)
> and the only way that's going to be feasible will be to document things
> outside of the GCC source tree.
>
> I've gone ahead and created a bare-bones document for this
> https://github.com/riscv/riscv-c-api-doc/blob/master/riscv-c-api.md

As a practical matter, you won't get all other FSF developers to
maintain documents outside the FSF tree like this. But we can try to
do the work when others modify the RISC-V port.

This is effectively duplicating GCC docs. We have a section in the
gcc manual for RISC-V options, and another one for RISC-V Function
Attributes. There is also one for extended asm codes if we care about
documenting that. We are missing one for RISC-V builtin functions
which looks like a minor bug. So effectively this is an exercise in
trying to keep this doc in sync with the GCC docs, which looks like a
tractable amount of work.

Jim

Bruce Hoult

unread,
Jun 7, 2018, 9:17:03 PM6/7/18
to Jim Wilson, Palmer Dabbelt, RISC-V SW Dev, Alex Bradbury
At *present* it's duplicating gcc docs, because gcc has a head start.

It's not necessarily the case that gcc will always be the first to implement every feature.

It's even possible one day something might be spec'd before anyone implements it :-)

Jim Wilson

unread,
Jun 7, 2018, 9:40:23 PM6/7/18
to Bruce Hoult, Palmer Dabbelt, RISC-V SW Dev, Alex Bradbury
On Thu, Jun 7, 2018 at 6:17 PM, Bruce Hoult <bruce...@sifive.com> wrote:
> At *present* it's duplicating gcc docs, because gcc has a head start.

I think that is missing the point I'm trying to make. If you are
trying to keep up to date with RISC-V specific GCC features, one easy
way to do that is by checking for RISC-V specific GCC doc file
changes. This is actually a better place to look than this new
document, because GCC developers are required to update the GCC docs
when writing patches, which means it will likely always be more
up-to-date than this new document.

There is of course some value in this document. I'm not objecting to
it, and have already submitted a patch for it.

I wondering what happens if one compiler implements a feature and
another compiler chooses not to implement it. Do we not add it to the
document because it isn't a standard API? Or maybe we add it and list
it as specific to a particular compiler?

Jim

Michael Clark

unread,
Jun 8, 2018, 1:20:51 AM6/8/18
to Jim Wilson, Bruce Hoult, Palmer Dabbelt, RISC-V SW Dev, Alex Bradbury
I’ve changed the topic, but it is still related to toolchain specific features vs standard defined features... in this case the assembler.

Do we have LP/SP (or LX/SX) pseudo instructions in gas, which expand to LW/SW on RV32 and LD/SD on RV64.

While not particularly useful for the compiler, they would be useful for hand written assembler. It’s one of the common macro definitions I see in RISC-V assembly code. Other platforms that have 32-bit and 64-bit variants are often too dissimilar to share the same assembly files, but this is not the case for RISC-V where the use of common assembly files for RV32 and RV64 is not infrequent.

__riscv_ptr_bytes would also be useful as often the right hand size has a variable address expression. A little cleaner than having a division by 8.
> --
> You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
> To post to this group, send email to sw-...@groups.riscv.org.
> Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/CAFyWVab1%2BrihJHcf4xofyno0gJBPH0xdPkaOygNPasfuuErJOA%40mail.gmail.com.

Bruce Hoult

unread,
Jun 8, 2018, 2:38:17 AM6/8/18
to Michael Clark, Jim Wilson, Palmer Dabbelt, RISC-V SW Dev, Alex Bradbury
Yes, and something short to write for calculating amounts to adjust the stack pointer by and calculating offsets to save/restore registers from the stack. Something like XLEN, except in bytes not bits.


On Fri, Jun 8, 2018 at 5:20 PM, Michael Clark <michae...@mac.com> wrote:
I’ve changed the topic, but it is still related to toolchain specific features vs standard defined features... in this case the assembler.

Do we have LP/SP (or LX/SX) pseudo instructions in gas, which expand to LW/SW on RV32 and LD/SD on RV64.

While not particularly useful for the compiler, they would be useful for hand written assembler. It’s one of the common macro definitions I see in RISC-V assembly code. Other platforms that have 32-bit and 64-bit variants are often too dissimilar to share the same assembly files, but this is not the case for RISC-V where the use of common assembly files for RV32 and RV64 is not infrequent.

__riscv_ptr_bytes would also be useful as often the right hand size has a variable address expression. A little cleaner than having a division by 8.

> On 8/06/2018, at 1:40 PM, Jim Wilson <ji...@sifive.com> wrote:
>
>> On Thu, Jun 7, 2018 at 6:17 PM, Bruce Hoult <bruce...@sifive.com> wrote:
>> At *present* it's duplicating gcc docs, because gcc has a head start.
>
> I think that is missing the point I'm trying to make.  If you are
> trying to keep up to date with RISC-V specific GCC features, one easy
> way to do that is by checking for RISC-V specific GCC doc file
> changes.  This is actually a better place to look than this new
> document, because GCC developers are required to update the GCC docs
> when writing patches, which means it will likely always be more
> up-to-date than this new document.
>
> There is of course some value in this document.  I'm not objecting to
> it, and have already submitted a patch for it.
>
> I wondering what happens if one compiler implements a feature and
> another compiler chooses not to implement it.  Do we not add it to the
> document because it isn't a standard API?  Or maybe we add it and list
> it as specific to a particular compiler?
>
> Jim
>
> --
> You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+unsubscribe@groups.riscv.org.

Liviu Ionescu

unread,
Jun 8, 2018, 2:45:45 AM6/8/18
to Michael Clark, Jim Wilson, Palmer Dabbelt, RISC-V SW Dev, Bruce Hoult, Alex Bradbury
On 8 June 2018 at 08:20:51, Michael Clark (michae...@mac.com) wrote:

> Do we have LP/SP (or LX/SX) pseudo instructions in gas, which
> expand to LW/SW on RV32 and LD/SD on RV64.

yes! useful in the context switch code.

for two letter names, my favourite pair is LX/SX, which seems more
generic, even for RV128.

for one letter names, if not already taken, L/S.


regards,

Liviu

Andrew Waterman

unread,
Jun 8, 2018, 3:06:03 AM6/8/18
to Michael Clark, Jim Wilson, Bruce Hoult, Palmer Dabbelt, RISC-V SW Dev, Alex Bradbury
On Thu, Jun 7, 2018 at 10:20 PM, Michael Clark <michae...@mac.com> wrote:
> I’ve changed the topic, but it is still related to toolchain specific features vs standard defined features... in this case the assembler.
>
> Do we have LP/SP (or LX/SX) pseudo instructions in gas, which expand to LW/SW on RV32 and LD/SD on RV64.

Seems useful.

Note LP/SP and LX/SX might not mean the same thing for ABIs like RV64
ILP32, where pointers are fewer than XLEN bits wide.

>
> While not particularly useful for the compiler, they would be useful for hand written assembler. It’s one of the common macro definitions I see in RISC-V assembly code. Other platforms that have 32-bit and 64-bit variants are often too dissimilar to share the same assembly files, but this is not the case for RISC-V where the use of common assembly files for RV32 and RV64 is not infrequent.
>
> __riscv_ptr_bytes would also be useful as often the right hand size has a variable address expression. A little cleaner than having a division by 8.

Similarly, __riscv_ptr_bytes might not equal __riscv_xlen / 8.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/03A28A37-82D6-427A-BE79-245EB5F1F928%40mac.com.

Palmer Dabbelt

unread,
Jun 8, 2018, 6:33:47 PM6/8/18
to Jim Wilson, Bruce Hoult, sw-...@groups.riscv.org, Alex Bradbury
I think that's one of the points of having the document: we can all go argue
there and decide if it's meant to be part of the standard API or a
compiler-specific API. We could always have a list of compiler-specific things
in the doc (ie, GCC version 8 supports '-march=rv32e'), which would be a
natural place to put compiler-specific extensions.

I guess my hope would be that we don't end up with RISC-V-specific,
compiler-specific C API extensions.

Palmer Dabbelt

unread,
Jun 8, 2018, 6:33:49 PM6/8/18
to Michael Clark, Jim Wilson, Bruce Hoult, sw-...@groups.riscv.org, Alex Bradbury
On Thu, 07 Jun 2018 22:20:44 PDT (-0700), Michael Clark wrote:
> I’ve changed the topic, but it is still related to toolchain specific features vs standard defined features... in this case the assembler.
>
> Do we have LP/SP (or LX/SX) pseudo instructions in gas, which expand to LW/SW on RV32 and LD/SD on RV64.
>
> While not particularly useful for the compiler, they would be useful for hand written assembler. It’s one of the common macro definitions I see in RISC-V assembly code. Other platforms that have 32-bit and 64-bit variants are often too dissimilar to share the same assembly files, but this is not the case for RISC-V where the use of common assembly files for RV32 and RV64 is not infrequent.

We end up with one defined in every project, but AFAIK we don't have a pseudo
in GAS. I wouldn't be opposed to adding one... :)

> __riscv_ptr_bytes would also be useful as often the right hand size has a variable address expression. A little cleaner than having a division by 8.

Here I think we should just follow the standard definitions, things like
__LP64__. It looks like __SIZEOF_PTRDIFF_T__ is defined in GCC, so I don't see
any reason to add a RISC-V specific definition.

Contrast this with __riscv_xlen, where there's really no generic C construct
that corresponds to the length of an X register.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/03A28A37-82D6-427A-BE79-245EB5F1F928%40mac.com.

Jim Wilson

unread,
Jun 11, 2018, 8:10:19 PM6/11/18
to Palmer Dabbelt, Michael Clark, Bruce Hoult, RISC-V SW Dev, Alex Bradbury
On Fri, Jun 8, 2018 at 3:33 PM, Palmer Dabbelt <pal...@sifive.com> wrote:
> On Thu, 07 Jun 2018 22:20:44 PDT (-0700), Michael Clark wrote:
>>
>> I’ve changed the topic, but it is still related to toolchain specific
>> features vs standard defined features... in this case the assembler.
>>
>> Do we have LP/SP (or LX/SX) pseudo instructions in gas, which expand to
>> LW/SW on RV32 and LD/SD on RV64.

Pointer size and register size are not the same thing, as Andrew
pointed out. I found an easy way to implement LX/SX pseudo
instructions that depend on the register size (xlen). Something that
depends on pointer size would be a lot more complicated, as I'd have
to add new infrastructure to support that.

There are a few things I'm concerned about. Claiming LX/SX for the
assembler means we can't use them for any proposed extensions. I
don't have visibility into all of the proposals, so I don't know if
this would conflict with any. We don't have very good assembler
documentation, so it isn't clear where to document this, or how
effective such documentation would be for new people to find and read.
I can add this extension upstream, but it could be a while before it
propagates everywhere, which means it won't be safe to use this
extension in portable assembly code for a while.

Palmer pointed out that there are alternatives to __riscv_xlen. I
haven't seen a convincing argument for a gcc change here.

But the gas LX/SX change sounds reasonable, and I have an untested
patch I can finish and push upstream if people think this is a good
idea.

Jim

Liviu Ionescu

unread,
Jun 12, 2018, 1:40:36 AM6/12/18
to Palmer Dabbelt, Jim Wilson, RISC-V SW Dev, Bruce Hoult, Alex Bradbury, Michael Clark
On 12 June 2018 at 03:10:19, Jim Wilson (ji...@sifive.com) wrote:

> ... Claiming LX/SX for the assembler ...

Did you also consider the single letter L/S?

Regards,

Liviu

Jim Wilson

unread,
Jun 12, 2018, 1:16:53 PM6/12/18
to Liviu Ionescu, Palmer Dabbelt, RISC-V SW Dev, Bruce Hoult, Alex Bradbury, Michael Clark
On Mon, Jun 11, 2018 at 10:40 PM, Liviu Ionescu <i...@livius.net> wrote:
> On 12 June 2018 at 03:10:19, Jim Wilson (ji...@sifive.com) wrote:
>
>> ... Claiming LX/SX for the assembler ...
>
> Did you also consider the single letter L/S?

I like the LX/SX suggestion because it makes it clear that we are
loading/storing an entire X reg, regardless of the size of an X reg.

Jim

Palmer Dabbelt

unread,
Jun 12, 2018, 3:38:09 PM6/12/18
to Jim Wilson, i...@livius.net, sw-...@groups.riscv.org, Bruce Hoult, Alex Bradbury, Michael Clark
I agree. If we add these, we should probably also add:

* LF/SF for floating-point, swapping between flw/fsw and fld/fsd depending on
the presence of the D extension. These will be illegal without F or D.
* LP/SP for pointers, swapping between lw/sw and ld/sd depending on ilp32 vs
lp64.

I'm OK with these names or the longer names (LXREG, LFREG, LPTR), but I don't
think just "L" and "S" sane names.

As Jim has mentioned before, it'll take a while for these to filter through the
various releases. For example, binutils-2.30 is pretty stable so people
probably won't update for a bit. As such, I'm also OK doing nothing here:
portable assembly will still need the various macros for a long time, and I
don't think we'll deprecate support for old binutils in any of the projects I
maintain just for this.

There's also the issue where just having the instructions pseudos will
frequently be insufficient. For example, most of the time I end up writing
this is when I'm saving/restoring registers to some buffer, where I currently
do something like

S_REG x1, 0*SZREG(base)
S_REG x2, 1*SZREG(base)
...
L_REG x1, 0*SZREG(base)
L_REG x2, 1*SZREG(base)

This would eliminate the L_REG/S_REG macros, but wouldn't help any with the
offsets. The pseudos also don't help much for C code, where it's simpler to
just let the complier propagate type sizes -- for example, here's the Linux
code

#define __get_user(x, ptr) \
({ \
register long __gu_err = 0; \
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
__chk_user_ptr(__gu_ptr); \
switch (sizeof(*__gu_ptr)) { \
case 1: \
__get_user_asm("lb", (x), __gu_ptr, __gu_err); \
break; \
case 2: \
__get_user_asm("lh", (x), __gu_ptr, __gu_err); \
break; \
case 4: \
__get_user_asm("lw", (x), __gu_ptr, __gu_err); \
break; \
case 8: \
__get_user_8((x), __gu_ptr, __gu_err); \
break; \
default: \
BUILD_BUG(); \
} \
__gu_err; \
})

That said, I'm not opposed to doing something here as the cost (particularly of
something like 'lxreg') is pretty low. This is at a point where someone should
propose a concrete extension to the RISC-V assembly manual so we can go
implement it :).
Reply all
Reply to author
Forward
0 new messages