What about things like pre_store and post_store, though? If there was a pre_load and post_load this would largely solve the problem. Of course there are a wealth of addressing modes for the 68k, but they should be able to be dealt with like this I think? -----Original Message----- From: Dr D. Chisnall [mailto:dc552 at hermes.cam.ac.uk] On Behalf Of David Chisnall Sent: 09 July 2015 10:58 To: James Boulton Cc: llvmdev at cs.uiuc.edu Subject: Re: [LLVMdev] New backend help request. The simple answer is: not very easily. I’d be inclined to treat instructions like these as optimisations and ignore them (aside from integrated assembler support) until the rest of the back end is working. Once that’s working, take a look at how the ARM back end uses ldm and stm instructions - basically pattern matching on the MachineInstrs after code generation to fold them together. Your other alternative in this case is to model this as an instruction that does a gather load of a two-element vector and then two extract elements. You might be able to get the vectoriser to generate these sequences and then match them, but I suspect that you’ll then have to define a load of pseudos for vector ops (type legalisation happens before instruction selection, so it’s difficult to have types that are only valid for a few complex IR / DAG sequences). David
On 9 July 2015 at 13:00, James Boulton <eiconic at googlemail.com> wrote:> What about things like pre_store and post_store, though? If there was a pre_load and post_load this would largely solve the problem. Of course there are a wealth of addressing modes for the 68k, but they should be able to be dealt with like this I think?We do have write-back addressing modes in ARM, but IIRC, that's encoded in the instruction, not as a pattern. Ie. it won't generate (or collapse) additional write-back instructions, just choose the one that does write-back. --renato
Hmm, I'm getting nowhere pretty fast. It seems 68000 with its CISC nature is quite complex to implement for a novice. I can see how to implement simple stuff, like -- move dn, dn move dn, (an) As that just turns into stores, sets, etc. But how would you represent things like indexed access? move dn, (an,dn) move dn, offset(an) Can I only really define very simple operations for the main instruction info, and then the rest comes as optimisation? It sounds like that may not be very efficient?