Ivan Llopard
2012-Aug-22 07:39 UTC
[LLVMdev] Passing return values on the stack & storing arbitrary sized integers
Hi Fabian, Anton, On 22/08/2012 08:25, Fabian Scheler wrote:>>> here are the definitions of these register classes: >>> >>> // Data register class >>> def DR : RegisterClass<"TriCore", [i32], 32, >>> (add D0, D1, D2, D3, D4, D5, D6, D7, >>> D8, D9, D10, D11, D12, D13, D14, D15)>; >>> >>> // Extended-size data register class >>> def ER : RegisterClass<"TriCore", [i64], 32, >>> (add E0, E2, E4, E6, E8, E10, E12, E14)> { >>> let SubRegClasses = [(DR sub_even, sub_odd)]; >>> } >>> >>> And the DX and EX registers are defined this way: >> The regclasses look fine... So, you need to figure out why >> getRepRegClassFor() returns NULL in this case. > Well, that's rather easy :-) The register class is not registered in > the constructor of TriCoreTargetLowering. Maybe, some background is > missing here: > > - I added the ER register class for MVT::i64 and I had to take care of > quite a lot of stuff as the TriCore does not really support 64-bit > operations (it just offers these register pairs but almost no > operations working on them). > > - Eli mentioned that is a quite common mistake to register such > register classes although the processor does not support many > operations on the according value types. It causes much more work in > the specific back-end as type legalization no longer takes care of > such nodes. It definitely would be much easier if I just had to take > care of some special instructions on the TriCore that involve ER > registers (like multiplication/division).That's *a lot* of work as your processor does not support any operation other than mul/div in 64 bit. Did you try to create a pseudo div/mul instruction and expand it after the isel pass ? Or you may even go further in the pipeline and expand it just before the RA with a custom pass. Not sure if that hook is called again at the RA pass or later on. Ivan> > - However, the segfault caused by the NULL-pointer returned by > getRepRegClassFor() is the reason why I added this register class and > used a lot of setOperationActions, setLoadExtAction, ... or lowered > some thins manually. > >> Side note: you can autogenerate register names :) > Nice, saves typing. Is there an example I can have a look at. Most > targets I examined seem to do this explicitly. > > Ciao, Fabian > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Fabian Scheler
2012-Aug-23 09:06 UTC
[LLVMdev] Passing return values on the stack & storing arbitrary sized integers
2012/8/22 Ivan Llopard <ivanllopard at gmail.com>:> Hi Fabian, Anton, > > > On 22/08/2012 08:25, Fabian Scheler wrote: >>>> >>>> here are the definitions of these register classes: >>>> >>>> // Data register class >>>> def DR : RegisterClass<"TriCore", [i32], 32, >>>> (add D0, D1, D2, D3, D4, D5, D6, D7, >>>> D8, D9, D10, D11, D12, D13, D14, D15)>; >>>> >>>> // Extended-size data register class >>>> def ER : RegisterClass<"TriCore", [i64], 32, >>>> (add E0, E2, E4, E6, E8, E10, E12, E14)> { >>>> let SubRegClasses = [(DR sub_even, sub_odd)]; >>>> } >>>> >>>> And the DX and EX registers are defined this way: >>> >>> The regclasses look fine... So, you need to figure out why >>> getRepRegClassFor() returns NULL in this case. >> >> Well, that's rather easy :-) The register class is not registered in >> the constructor of TriCoreTargetLowering. Maybe, some background is >> missing here: >> >> - I added the ER register class for MVT::i64 and I had to take care of >> quite a lot of stuff as the TriCore does not really support 64-bit >> operations (it just offers these register pairs but almost no >> operations working on them). >> >> - Eli mentioned that is a quite common mistake to register such >> register classes although the processor does not support many >> operations on the according value types. It causes much more work in >> the specific back-end as type legalization no longer takes care of >> such nodes. It definitely would be much easier if I just had to take >> care of some special instructions on the TriCore that involve ER >> registers (like multiplication/division). > > > That's *a lot* of work as your processor does not support any operation > other than mul/div in 64 bit. > > Did you try to create a pseudo div/mul instruction and expand it after the > isel pass ? > Or you may even go further in the pipeline and expand it just before the RA > with a custom pass. > Not sure if that hook is called again at the RA pass or later on.OK, the might be a solution, I did not try this yet. Is EmitInstrWithCustomInserter the right point to start? When emitting a bunch of target specific instructions there, I will still need some virtual registers of the ER register class there. Is this possible without adding the register class? Ciao, Fabian
Ivan Llopard
2012-Aug-23 11:58 UTC
[LLVMdev] Passing return values on the stack & storing arbitrary sized integers
On 23/08/2012 11:06, Fabian Scheler wrote:> 2012/8/22 Ivan Llopard<ivanllopard at gmail.com>: >> Hi Fabian, Anton, >> >> >> On 22/08/2012 08:25, Fabian Scheler wrote: >>>>> here are the definitions of these register classes: >>>>> >>>>> // Data register class >>>>> def DR : RegisterClass<"TriCore", [i32], 32, >>>>> (add D0, D1, D2, D3, D4, D5, D6, D7, >>>>> D8, D9, D10, D11, D12, D13, D14, D15)>; >>>>> >>>>> // Extended-size data register class >>>>> def ER : RegisterClass<"TriCore", [i64], 32, >>>>> (add E0, E2, E4, E6, E8, E10, E12, E14)> { >>>>> let SubRegClasses = [(DR sub_even, sub_odd)]; >>>>> } >>>>> >>>>> And the DX and EX registers are defined this way: >>>> The regclasses look fine... So, you need to figure out why >>>> getRepRegClassFor() returns NULL in this case. >>> Well, that's rather easy :-) The register class is not registered in >>> the constructor of TriCoreTargetLowering. Maybe, some background is >>> missing here: >>> >>> - I added the ER register class for MVT::i64 and I had to take care of >>> quite a lot of stuff as the TriCore does not really support 64-bit >>> operations (it just offers these register pairs but almost no >>> operations working on them). >>> >>> - Eli mentioned that is a quite common mistake to register such >>> register classes although the processor does not support many >>> operations on the according value types. It causes much more work in >>> the specific back-end as type legalization no longer takes care of >>> such nodes. It definitely would be much easier if I just had to take >>> care of some special instructions on the TriCore that involve ER >>> registers (like multiplication/division). >> That's *a lot* of work as your processor does not support any operation >> other than mul/div in 64 bit. >> >> Did you try to create a pseudo div/mul instruction and expand it after the >> isel pass ? >> Or you may even go further in the pipeline and expand it just before the RA >> with a custom pass. >> Not sure if that hook is called again at the RA pass or later on. > OK, the might be a solution, I did not try this yet. Is > EmitInstrWithCustomInserter the right point to start?Yes.> When emitting a > bunch of target specific instructions there, I will still need some > virtual registers of the ER register class there. Is this possible > without adding the register class?Yes as long as you have the regclass defined in the td file. MachineRegisterInfo doesn't seem to use TargetLowering information. Ivan> Ciao, Fabian
Apparently Analagous Threads
- [LLVMdev] Passing return values on the stack & storing arbitrary sized integers
- [LLVMdev] Passing return values on the stack & storing arbitrary sized integers
- [LLVMdev] Passing return values on the stack & storing arbitrary sized integers
- [LLVMdev] Passing return values on the stack & storing arbitrary sized integers
- [LLVMdev] Passing return values on the stack & storing arbitrary sized integers