riscv-collab / riscv-gnu-toolchain

GNU toolchain for RISC-V, including GCC
Other
3.56k stars 1.17k forks source link

Restriction of instructions during compilation #1581

Closed kowshik1234 closed 1 month ago

kowshik1234 commented 1 month ago

Hi everyone,

We're trying to build a custom risc-v based processor that's going to support only a subset of the original ISA.

As a part of this, we want the compiler to restrict the instructions to a particular count instead of letting it take the Full ISA into account.

For example, we want to remove MUL instruction and keep only ADD as multiplication is repeated addition. I want to remove MUL and have branch instructions and ADD, SUB instructions only. Is there a way to directly do it through arguments or do I have to change anything in the binutils and recompile the gcc? Can someone help me here please.

Thanks, G Kowshik

TommyMurphyTM1234 commented 1 month ago

You'll probably need to familiarise yourself with the GCC and Binutils internals documentation and understand how to customise the toolchain to use specific instructions and/or omit support for certain instructions.

This sort of stuff is way beyond the scope of the riscv-gnu-toolchain repo but you may find some useful information in the existing open and closed Issues and PRs:

Failing that you should probably ask questions upstream on the relevant GCC and Binutils forums - e.g.:

kowshik1234 commented 1 month ago

understood, I have another doubt, this might fairly be a high level query on compilers but asking it anyway. An instruction can be achieved by replacing it with various other instructions too. For example SUB can be replaced with Xori, ADDi and ADD instructions.

My question here is, if I remove SUB from the compiler set, are compilers intelligent enough to figure out that effect of SUB can be achieve from using the other instructions? Let me know if my question is confusing.

TommyMurphyTM1234 commented 1 month ago

For example, we want to remove MUL instruction and keep only ADD as multiplication is repeated addition.

In the case of multiply instructions you can specify, at compilation time, an architecture that doesn't encompass the M extension - e.g. -march=rv64iafdc instead of -march=rv64imafdc or -march=rv64gc. But this will disable all instructions provided by the M extension - e.g. multiple, divide and remainder instructions. The same general idea applies to all RISC-V extensions.

My question here is, if I remove SUB from the compiler set, are compilers intelligent enough to figure out that effect of SUB can be achieve from using the other instructions? Let me know if my question is confusing.

It really depends on what changes you make to the compiler to effect this change. And sub is part of the base RISC-V integer ISA so if you remove that then arguably (or actually?) your CPU is no longer actually a RISC-V!

What is the rationale/driver for removing base integer ISA instructions? It seems like an odd choice given that the base integer ISA was deliberately chosen to be generally useful and appropriate to most use cases.

kowshik1234 commented 1 month ago

What is the rationale/driver for removing base integer ISA instructions?

It's totally an example I was mentioning here. And the real use-case is that, we're making very application specific RISC cores that really don't need many of the integer ISA too. And also we observed that the die size of the IC is varying heavily if we omit some instructions. Performance is not a mandatory criteria for us, die size is the real trade-off hence the reason for removing the standard ISA too.

TommyMurphyTM1234 commented 1 month ago

Ok - so the idea is to create a custom non RISC-V RISC processor using RISC-V and associated tools as a starting point? This is even more outside the scope of this repo than I originally opined.

kowshik1234 commented 1 month ago

Yes pretty much, we already built a processor that supports full ISA and running benchmarks and stuff. But to cutdown the ISA and make it more custom we need to mess with the associated tools too. Any pointers to how I can start or look into doing stuff like these? Would LLVM be a potential path to explore? I know I'm asking more than the scope of this post or repo.

TommyMurphyTM1234 commented 1 month ago

Any pointers to how I can start or look into doing stuff like these?

I already provided some:

Would LLVM be a potential path to explore?

Well it's another toolchain and is open source so can be customised so, maybe. The same issue applies here as with GCC/Binutils though - you would need to study the relevant LLVM/Clang internals documentation, understand how it works internally, study the RISC-V or relevant other RISC CPU support that is implemented, and then figure out how you would need to modify this. I'm sure that the LLVM community can offer more specific assistance/advice.

kowshik1234 commented 1 month ago

Thanks @TommyMurphyTM1234 for all the info. I'll close the issue so the discussions don't deviate much.