diff --git a/docs/WritingAnLLVMBackend.html b/docs/WritingAnLLVMBackend.html new file mode 100644 index 00000000000..1fb88a36332 --- /dev/null +++ b/docs/WritingAnLLVMBackend.html @@ -0,0 +1,245 @@ + + +
+This document describes techniques for writing backends for LLVM which +convert the LLVM representation to machine assembly code or other languages.
+ +In general, you want to follow the format of X86 or PowerPC (in +lib/Target).
+ +To create a static compiler (one that emits text assembly), you need to +implement the following:
+ +Now, for static code generation you also need to write an instruction +selector for your platform: see lib/Target/*/*ISelSimple.cpp which +is no longer "simple" but it gives you the idea: you have to be able to create +MachineInstrs for any given LLVM instruction using the InstVisitor +pattern, and produce a MachineFunction with +MachineBasicBlocks full of MachineInstrs for a +corresponding LLVM Function. Creating an instruction selector is perhaps the +most time-consuming part of creating a back-end.
+ +To create a JIT for your platform:
+ +Note that lib/target/Skeleton is a clean skeleton for a new target, +so you might want to start with that and adapt it for your target, and if you +are wondering how things are done, peek in the X86 or PowerPC target.
+ +The Skeleton target is non-functional but provides the basic building blocks +you will need for your endeavor.
+ +TableGen register info description - describe a class which +will store the register's number in the binary encoding of the instruction +(e.g., for JIT purposes).
+ +You also need to define register classes to contain these registers, such as +the integer register class and floating-point register class, so that you can +allocate virtual registers to instructions from these sets, and let the +target-independent register allocator automatically choose the actual +architected registers.
+ ++// class Register is defined in Target.td +class TargetReg : Register { + let Namespace = "Target"; +} + +class IntReg<bits<5> num> : TargetReg { + field bits<5> Num = num; +} + +def R0 : IntReg<0>; +... + +// class RegisterClass is defined in Target.td +def IReg : RegisterClass<i64, 64, [R0, ... ]>; ++
TableGen instruction info description - break up instructions into +classes, usually that's already done by the manufacturer (see instruction +manual). Define a class for each instruction category. Define each opcode as a +subclass of the category, with appropriate parameters such as the fixed binary +encoding of opcodes and extended opcodes, and map the register bits to the bits +of the instruction which they are encoded in (for the JIT). Also specify how +the instruction should be printed so it can use the automatic assembly printer, +e.g.:
+ ++// class Instruction is defined in Target.td +class Form<bits<6> opcode, dag OL, string asmstr> : Instruction { + field bits<42> Inst; + + let Namespace = "Target"; + let Inst{0-6} = opcode; + let OperandList = OL; + let AsmString = asmstr; +} + +def ADD : Form<42, (ops IReg:$rD, IReg:$rA, IReg:$rB), "add $rD, $rA, $rB">; ++
For now, just take a look at lib/Target/CBackend for an example of +how the C backend is written.
+ +