123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- {
- Copyright (c) 2010-2013 by Jonas Maebe
- This unit implements the code generator for LLVM
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- unit cgllvm;
- {$i fpcdefs.inc}
- interface
- uses
- globtype,parabase,
- cgbase,cgutils,cgobj,cghlcpu,
- llvmbase,llvminfo,aasmbase,aasmtai,aasmdata,aasmllvm;
- type
- tcgllvm=class(thlbasecgcpu)
- public
- procedure a_label(list : TAsmList;l : tasmlabel);override;
- procedure a_jmp_always(list: TAsmList; l: tasmlabel); override;
- procedure init_register_allocators;override;
- procedure done_register_allocators;override;
- function getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
- function getfpuregister(list:TAsmList;size:Tcgsize):Tregister;override;
- end;
- procedure create_codegen;
- implementation
- uses
- globals,verbose,systems,cutils,
- paramgr,fmodule,
- tgobj,rgllvm,cpubase,
- procinfo,cpupi;
- {****************************************************************************
- Assembler code
- ****************************************************************************}
- procedure tcgllvm.a_label(list: TAsmList; l: tasmlabel);
- begin
- { in llvm, every block must end with a terminator instruction, such as
- a branch -> if the previous instruction is not a terminator instruction,
- add an unconditional branch to the next block (= the one starting with
- this label) }
- if not assigned(list.last) or
- (tai(list.Last).typ<>ait_llvmins) or
- not(taillvm(list.Last).llvmopcode in llvmterminatoropcodes) then
- a_jmp_always(list,l);
- inherited;
- end;
- procedure tcgllvm.a_jmp_always(list: TAsmList; l: tasmlabel);
- begin
- list.concat(taillvm.op_lab(la_br,l));
- end;
- procedure tcgllvm.init_register_allocators;
- begin
- inherited init_register_allocators;
- rg[R_INTREGISTER]:=Trgllvm.create(R_INTREGISTER,R_SUBWHOLE,
- [0],first_int_imreg,[]);
- rg[R_FPUREGISTER]:=Trgllvm.create(R_FPUREGISTER,R_SUBWHOLE,
- [0],first_fpu_imreg,[]);
- rg[R_MMREGISTER]:=Trgllvm.create(R_MMREGISTER,R_SUBWHOLE,
- [0],first_mm_imreg,[]);
- { every temp gets its own "base register" to uniquely identify it }
- rg[R_TEMPREGISTER]:=trgllvm.Create(R_TEMPREGISTER,R_SUBWHOLE,
- [0],1,[]);
- end;
- procedure tcgllvm.done_register_allocators;
- begin
- rg[R_INTREGISTER].free;
- rg[R_FPUREGISTER].free;
- rg[R_MMREGISTER].free;
- rg[R_TEMPREGISTER].free;
- inherited done_register_allocators;
- end;
- function tcgllvm.getintregister(list:TAsmList;size:Tcgsize):Tregister;
- begin
- { all size determinations are based on tdef, subregisters are
- irrelevant }
- result:=rg[R_INTREGISTER].getregister(list,R_SUBWHOLE)
- end;
- function tcgllvm.getfpuregister(list:TAsmList;size:Tcgsize):Tregister;
- begin
- { all size determinations are based on tdef, subregisters are
- irrelevant }
- result:=rg[R_FPUREGISTER].getregister(list,R_SUBWHOLE);
- end;
- procedure create_codegen;
- begin
- cg:=tcgllvm.Create;
- end;
- end.
|