Hi, I am trying to do a backend to a very simple microcontroller. I have some questions. 1) I have instruction which do "r1 <- r1 op r2", from what I have ssen I must declare them like: let isTwoAddress = 1 in def ADD : FopRR< 0b01010, (outs CPURegs:$sX), (ins CPURegs:$isX, CPURegs:$sY), "ADD $sX, $sY"), [(set CPURegs:$sX, (add CPURegs:$isX, CPURegs:$sY))]>; Where CPURegs is my class of register. I suppose that the pass TwoAddressInstructionPass will make the $sX and $isX register the same (it unify the out reg and the first in reg?) ? When should I set isConvertibleToThreeAddress to 1? When I have another form of the instruction which take a three addresses? 2) Instr class contain the following properties. I suppose they must be set correctly for? I have some question on them. If only '?' I don't understand at all, if no comment then I think I understand. int CodeSize = 0; // in bits? Or bytes? int AddedComplexity = 0; // ? bit isReturn = 0; bit isBranch = 0; bit isIndirectBranch = 0; bit isBarrier = 0; // ? memory barrier? bit isCall = 0; bit isSimpleLoad = 0; // simple? bit mayLoad = 0; bit mayStore = 0; bit isTwoAddress = 0; // see question 1 bit isConvertibleToThreeAddress = 0; // see question 1 bit isCommutable = 0; // see rq1 below bit isTerminator = 0; // terminate what? A BB, A function, or the program bit isReMaterializable = 0; // ? bit isPredicable = 0; bit hasDelaySlot = 0; bit usesCustomDAGSchedInserter = 0; bit hasCtrlDep = 0; // ? bit isNotDuplicable = 0; // ? bit hasSideEffects = 0; bit mayHaveSideEffects = 0; // how is this different from has side effect? bit neverHasSideEffects = 1; Rq1: If I have a instruction 'add reg, imm' and don't have 'add imm, reg' I suppose the instruction isn't commutable? 3) For conditional jump: the architecture use the flags carry and zero to do conditional jump (ex: jump if carry set) and most arithmetic operation set these flags. I was wondering how to handle this. I have seen some CC (condition code) in some backend but it is not clear. Or I could model precisely the flag but then the operations would have more than on output and it seems this isn't supported at least in the tablegen? Could you give me some pointer 4) IO: on this µC, the IO aren't mapped in the main address space and use a separate set of load/store. I was thinking of using the new functionality of multiple address space. But should the separation be done in the legalization phase or in the instruction selection phase? This is all for the moment ;) Regards, -- Cédric Ps: the µC I target is Picoblaze of xilinx: http://www.xilinx.com/support/documentation/user_guides/ug129.pdf I know that having a compiler for a µC this small isn't useful (asm is better in this case) but my goal is more too learn how to do a backend that to really do it. And I know there is no indirect jump on this architecture so not all llvm code can be legalized. In fact I would like to have a template backend for small 8/16 bits µC to be able to target custom FPGA embedded µC really easily.
On Apr 27, 2008, at 7:37 AM, Cédric Venet wrote:> Hi, > > I am trying to do a backend to a very simple microcontroller. I have > some > questions.Ok.> 1) I have instruction which do "r1 <- r1 op r2", from what I have > ssen I > must declare them like: > > let isTwoAddress = 1 in > def ADD : FopRR< 0b01010, > (outs CPURegs:$sX), (ins CPURegs:$isX, CPURegs:$sY), > "ADD $sX, $sY"), > [(set CPURegs:$sX, (add CPURegs:$isX, CPURegs: > $sY))]>; > > Where CPURegs is my class of register. I suppose that the pass > TwoAddressInstructionPass will make the $sX and $isX register the > same (it > unify the out reg and the first in reg?) ?Yes. 'isTwoAddress' is just shorthand for saying that Xs and isX are constrainted to be tied together. You can constrain any two registers of the same class with 'Constraints = "$src = $dst"'.> When should I set isConvertibleToThreeAddress to 1? When I have > another form > of the instruction which take a three addresses?Yes. This is useful when the two address form is more efficient than the three address form in some way. This will cause the codegen to prefer the two address form, but fall back to the 3-addr one when it would otherwise have to insert a copy.> 2) Instr class contain the following properties. I suppose they must > be set > correctly for? I have some question on them. If only '?' I don't > understand > at all, if no comment then I think I understand.Take a look at lib/Target/*.td for comments on each of these fields.> int AddedComplexity = 0; // ?This is optional, used to tweak instruction selection priority.> bit isReMaterializable = 0; // ?Conservatively safe to leave as zero. This will hopefully go away in the future.> Rq1: If I have a instruction 'add reg, imm' and don't have 'add imm, > reg' I > suppose the instruction isn't commutable?'add' (in the target independent sense) is a commutable operation, so the code generator will always canonicalize the immediate to the RHS of the operator. Commutative *instruction* must have two input register operands, so 'reg,imm' doesn't make sense to be commutative.> 3) For conditional jump: > the architecture use the flags carry and zero to do conditional jump > (ex: > jump if carry set) and most arithmetic operation set these flags. I > was > wondering how to handle this. I have seen some CC (condition code) > in some > backend but it is not clear. Or I could model precisely the flag but > then > the operations would have more than on output and it seems this isn't > supported at least in the tablegen? Could you give me some pointerWe don't have wonderful ways of modeling this (i.e. taking advantage of flags set by random operations) yet, but X86 works the same way. I'd look at how its backend works.> 4) IO: on this µC, the IO aren't mapped in the main address space > and use a > separate set of load/store. I was thinking of using the new > functionality of > multiple address space. But should the separation be done in the > legalization phase or in the instruction selection phase?Instruction selection should match on the address space qualifier of the pointer value in the SrcValue for the load or store.> Ps: the µC I target is Picoblaze of xilinx: > http://www.xilinx.com/support/documentation/user_guides/ug129.pdf > I know that having a compiler for a µC this small isn't useful (asm is > better in this case) but my goal is more too learn how to do a > backend that > to really do it. > And I know there is no indirect jump on this architecture so not all > llvm > code can be legalized. > In fact I would like to have a template backend for small 8/16 bits > µC to be > able to target custom FPGA embedded µC really easily.This would be an interesting target to add to mainline llvm. It seems like a great example of a small architecture. We don't have any 8/16 bit arch's and nothing that uses ASI's in mainline yet. It would be great to have an example. -Chris
Hi Cedric, Chris, I had a similar thought, namely that having a simple 16/8-bit arch in clang+LLVM would be a great instructional tool. I'm currently whipping up a quick back end for the 16-bit LC-3 instructional architecture (http://en.wikipedia.org/wiki/LC-3). I thought it'd be a good example because it is both extremely simple, but also quite functionally complete, and it has free assemblers and simulators available (not to mention that it's used to teach basic architecture and tools at a number of universities). If you think this would be useful let me know and I can commit back to the repo sooner rather than later. On Apr 27, 2008, at 12:48 PM, Chris Lattner wrote:> This would be an interesting target to add to mainline llvm. It seems > like a great example of a small architecture. We don't have any 8/16 > bit arch's and nothing that uses ASI's in mainline yet. It would be > great to have an example.-- Christopher Lamb -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080427/4065e1fc/attachment.html>