View unanswered posts | View active topics It is currently Thu Mar 28, 2024 6:52 pm



Reply to topic  [ 5 posts ] 
 Constant Registers 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
I’m wondering how many registers are required when encoding large constants ? For RiSC-V for instance there is the LUI and AUIPC instructions. These instructions allow any general purpose register to be loaded with constant data.
I’m wondering if it’s possible to get away with being able to load fewer registers ? The reason being I’m stuck with an instruction set that is just a couple of bits shy of being able to load the upper constant into a register with a single instruction. If I can reduce the number of registers that are loadable I can get the three bits that are needed. This would however leave only four registers to be loadable with constants.
It seems to me that since these are constant values in use there’s no need to spill and refill the registers used to contain constants. It looks like there’s only one register really required. I’m wondering how many registers a compiler actually uses for this purpose in practice ? The one caveat I can see is if the same upper constant is required for multiple instructions then one would not want to reload the constant all the time. So are four registers enough to get the job done 90+% of the time ?
I think multiple registers do need to be available so that the processor can work on more than one instruction constant at a time, just supporting the full register set maybe isn't required.

_________________
Robert Finch http://www.finitron.ca


Sat Aug 19, 2017 11:40 pm
Profile WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1780
It really is a question about easy it is to build a compiler for a machine with some asymmetry about the register file. (I'm sure you already know more than I do in that area)

I was reminded of the 68k's separation of Address and Data registers, and whether that might help pack in the instruction encoding. We do know the 68k was a popular machine with several C compilers.


Sun Aug 20, 2017 6:58 pm
Profile

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
BigEd wrote:
It really is a question about easy it is to build a compiler for a machine with some asymmetry about the register file. (I'm sure you already know more than I do in that area)

I was reminded of the 68k's separation of Address and Data registers, and whether that might help pack in the instruction encoding. We do know the 68k was a popular machine with several C compilers.

Yeah, the 68k gained a bit or two in the instruction encoding by separating data and address registers. It's tempting to do since about a half-dozen registers are fixed pointer type registers. (stack pointer, frame pointer, global pointer, return address, xhandler address, class pointer, thread pointer). But it adds to the compiler's complexity as you mention.

Since I'm building a compiler too I've decided to leave the large constants up to the assembler. In that case the compiler should never use the asymmetrical lui instruction. The compiler will assume it can use constants of any size with an instruction, then the assembler will patch up the code to use registers if the constant is too large for the instruction.
It makes the assembler more complex because it has to test for constant ranges.

My next question is what to do about calls to other functions where the function call might exceed the default number of bits available. It's easy enough to generate code to call a function that's further away but an issue is when to do this. It's wasteful of code space and performance to generate a "far" call for every function, but the compiler / assembler doesn't know in advance what needs to be encoded. I'm led to the ugly "far" / "near" routine designator which would have to be specified by the programmer. Or perhaps a "using far code;"

_________________
Robert Finch http://www.finitron.ca


Mon Aug 21, 2017 2:45 am
Profile WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1780
It feels it's almost a job for a linker. If all calls are near calls, then the ones which need to be converted to far calls can indirect via a trampoline just after the end of the function. You could even leave padding space for all possibly necessary trampolines - but with a linker, you don't need the padding because it fixes everything up as it links.


Mon Aug 21, 2017 4:58 am
Profile

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2095
Location: Canada
Just reading up on linkers in Wikipedia. It seems they expect the compiler to produce the worst case call instructions then the linker shortens the instructions if possible. I had been wondering how the linker would expand the code to accommodate larger calls, which then might break some relative branches because of the increased code size. If the linker is only shrinking code then the relative branches should be okay.

I've only written a really simple linker which didn't modify the size of the code. One thought I had was to include a nop operation before every call so the linker has a place to fix up the address. I guess it makes more sense to output longer code then have the linker nop out what's not needed. I'll leave compressing the code to another day. I'd like to try and keep the software simple. An issue is how to progress from the basic to the more involved without breaking things along the way. Preferable is some sort of stepwise refinement rather than doing everything at once.

I like the trampoline idea.

_________________
Robert Finch http://www.finitron.ca


Mon Aug 21, 2017 12:58 pm
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 5 posts ] 

Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software