<div dir="ltr">On Tue, Sep 2, 2014 at 3:38 PM, Tom Stellard <<a href="mailto:tom@stellard.net">tom@stellard.net</a>> wrote:<br><div class="gmail_extra"><div class="gmail_quote">><br>> On Tue, Sep 02, 2014 at 11:12:23AM +0100, Johnny Val wrote:<br>
> > Hi,<br>> ><br>> > I am working on a new back-end for LLVM. This architecture has two register<br>> > types, data(A) and accumulator(B).<br>> ><br>> > A registers are i32 where as B registers are i64. This is causing me some<br>
> > headaches, as far as I can tell, it's not really possible to mix the two<br>> > using tablegen?<br>> ><br>> > In the hardware, every instruction can either take an A register or a B<br>> > register, in tablegen (as far as I can understand) this is not possible.<br>
> ><br>> > I ended up creating instructions like<br>> ><br>> > MOV32ri (register immediate)<br>> > MOV32rr (register register)<br>> > MOV64rr, MOV64ri etc.<br>> ><br>> > I've done this for essentially every instruction. This kind of works, but<br>
> > there are issues.<br>> ><br>> > It results in unneeded copies between A registers and B registers. If a<br>> > value is in an A register and the other is in a B, LLVM will do a copy<br>> > between registers to make sure both registers are the same "type"(same<br>
> > bank) before doing the operation.<br>> ><br>><br>> Is it legal to have to mix register classes in an instruction? For example,<br>> ADD AReg, BReg?<br>><br>> If so you will need add more instruction variants e.g.<br>
> ADD3264rr, ADD6432rr.<br><br>This is what I attempted to do. I get errors such as:<br><br>"Type inference contradiction found, merging 'i32' into 'i64' "<br><br>Which is where I got the idea that mixing types in the tablegen instructions was not allowed.<br>
<br>> > Is there any way around this? Also is it really necessary to define a<br>> > different instruction for each register type (even though it's the same<br>> > instruction in hardware, with the same encoding etc).<br>
> ><br>><br>> There is not really a good way around this, but it is not so bad if<br>> you use multiclasses.<br>><br>> > Another issue is that when multiplying, the result must always be stored in<br>
> > a B (accumulator register). So I did some custom lowering for the MUL node,<br>> > and got the instruction to always write the result to a B register.<br>> ><br>><br>> How are you defining your MUL instruction? If you define the MUL<br>
> instruction in tablegen with a B register as destination register,<br>> then it should always output to a B register.<br>><br><br>I did do that, and that is indeed what happens. My C++ lowering code, quite literally, just replaces ISD::MUL nodes with my target specific MUL node. I leave the pattern empty in the tablegen description of the instruction to avoid the previously described error. Is this the correct way of solving this problem?<br>
<br>> -Tom<br>><br>> > The problem is that later on LLVM will move it from a B register to an A<br>> > register which means the result getting truncated (64 bit -> 32 bit). I am<br>> > also unsure how to deal with this.<br>
> ><br>> > I just want to confirm that I'm doing this somewhat correctly and there<br>> > isn't a much more obvious and better way of doing this.<br>> ><br>> > Kind Regards,<br>> ><br>
> > Jonathan<br>><br>> > _______________________________________________<br>> > LLVM Developers mailing list<br>> > <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu">http://llvm.cs.uiuc.edu</a><br>
> > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br><br></div>Thanks for the help!<br></div></div>