+ support for instruction operands that are tai themselves in the llvm

backend (required for inserting bitcasts/ptrtoint/... operations inside
    typed constant declarations)
   o taillvm constructors for creating bitcast-style and getlementptr
     operations that accept a tai as their source/base operand

git-svn-id: branches/hlcgllvm@28112 -
This commit is contained in:
Jonas Maebe 2014-07-01 16:30:22 +00:00
parent 7ebb1b813f
commit 1e7d9c9f0e
3 changed files with 125 additions and 50 deletions

View File

@ -262,6 +262,7 @@ interface
{$ifdef cpuextended} {$ifdef cpuextended}
,top_extended80 ,top_extended80
{$endif cpuextended} {$endif cpuextended}
,top_tai
,top_def ,top_def
,top_fpcond ,top_fpcond
,top_cond ,top_cond
@ -283,49 +284,6 @@ interface
end; end;
plocaloper = ^tlocaloper; plocaloper = ^tlocaloper;
{ please keep the size of this record <=12 bytes and keep it properly aligned }
toper = record
ot : longint;
case typ : toptype of
top_none : ();
top_reg : (reg:tregister);
top_ref : (ref:preference);
top_const : (val:tcgint);
top_bool : (b:boolean);
{ local varsym that will be inserted in pass_generate_code }
top_local : (localoper:plocaloper);
{$ifdef arm}
top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister; usermode: boolean);
top_conditioncode : (cc : TAsmCond);
top_modeflags : (modeflags : tcpumodeflags);
top_specialreg : (specialreg:tregister; specialflags:tspecialregflags);
{$endif arm}
{$if defined(arm) or defined(aarch64)}
top_shifterop : (shifterop : pshifterop);
{$endif defined(arm) or defined(aarch64)}
{$ifdef m68k}
top_regset : (dataregset,addrregset:^tcpuregisterset);
{$endif m68k}
{$ifdef jvm}
top_single : (sval:single);
top_double : (dval:double);
top_string : (pcvallen: aint; pcval: pchar);
top_wstring : (pwstrval: pcompilerwidestring);
{$endif jvm}
{$ifdef llvm}
top_single : (sval:single);
top_double : (dval:double);
{$ifdef cpuextended}
top_extended80 : (eval:extended);
{$endif cpuextended}
top_def : (def: tdef);
top_cond : (cond: topcmp);
top_fpcond : (fpcond: tllvmfpcmp);
top_para : (paras: tfplist);
{$endif llvm}
end;
poper=^toper;
const const
{ ait_* types which don't result in executable code or which don't influence { ait_* types which don't result in executable code or which don't influence
the way the program runs/behaves, but which may be encountered by the the way the program runs/behaves, but which may be encountered by the
@ -438,6 +396,52 @@ interface
); );
type type
tai = class;
{ please keep the size of this record <=12 bytes and keep it properly aligned }
toper = record
ot : longint;
case typ : toptype of
top_none : ();
top_reg : (reg:tregister);
top_ref : (ref:preference);
top_const : (val:tcgint);
top_bool : (b:boolean);
{ local varsym that will be inserted in pass_generate_code }
top_local : (localoper:plocaloper);
{$ifdef arm}
top_regset : (regset:^tcpuregisterset; regtyp: tregistertype; subreg: tsubregister; usermode: boolean);
top_conditioncode : (cc : TAsmCond);
top_modeflags : (modeflags : tcpumodeflags);
top_specialreg : (specialreg:tregister; specialflags:tspecialregflags);
{$endif arm}
{$if defined(arm) or defined(aarch64)}
top_shifterop : (shifterop : pshifterop);
{$endif defined(arm) or defined(aarch64)}
{$ifdef m68k}
top_regset : (dataregset,addrregset:^tcpuregisterset);
{$endif m68k}
{$ifdef jvm}
top_single : (sval:single);
top_double : (dval:double);
top_string : (pcvallen: aint; pcval: pchar);
top_wstring : (pwstrval: pcompilerwidestring);
{$endif jvm}
{$ifdef llvm}
top_single : (sval:single);
top_double : (dval:double);
{$ifdef cpuextended}
top_extended80 : (eval:extended);
{$endif cpuextended}
top_tai : (ai: tai);
top_def : (def: tdef);
top_cond : (cond: topcmp);
top_fpcond : (fpcond: tllvmfpcmp);
top_para : (paras: tfplist);
{$endif llvm}
end;
poper=^toper;
{ abstract assembler item } { abstract assembler item }
tai = class(TLinkedListItem) tai = class(TLinkedListItem)
{$ifndef NOOPT} {$ifndef NOOPT}
@ -2807,6 +2811,8 @@ implementation
{$ifdef llvm} {$ifdef llvm}
top_para: top_para:
paras.free; paras.free;
top_tai:
ai.free;
{$endif llvm} {$endif llvm}
end; end;
typ:=top_none; typ:=top_none;

View File

@ -68,6 +68,8 @@ interface
{$endif cpuextended} {$endif cpuextended}
{ e.g. dst = bitcast fromsize @globalvar to tosize } { e.g. dst = bitcast fromsize @globalvar to tosize }
constructor op_reg_size_sym_size(op:tllvmop;dst:tregister;fromsize:tdef;src:TAsmSymbol;tosize:tdef); constructor op_reg_size_sym_size(op:tllvmop;dst:tregister;fromsize:tdef;src:TAsmSymbol;tosize:tdef);
{ e.g. dst = bitcast fromsize <abstracttaidata> to tosize }
constructor op_reg_size_tai_size(op:tllvmop;dst:tregister;fromsize:tdef;src:tai;tosize:tdef);
{ e.g. dst = bitcast fromsize src to tosize } { e.g. dst = bitcast fromsize src to tosize }
constructor op_reg_size_ref_size(op:tllvmop;dst:tregister;fromsize:tdef;const src:treference;tosize:tdef); constructor op_reg_size_ref_size(op:tllvmop;dst:tregister;fromsize:tdef;const src:treference;tosize:tdef);
@ -97,10 +99,12 @@ interface
{ e.g. dst = getelementptr ptrsize ref, i32 0 (if indirect), index1type index1 } { e.g. dst = getelementptr ptrsize ref, i32 0 (if indirect), index1type index1 }
constructor getelementptr_reg_size_ref_size_reg(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:tregister;indirect:boolean); constructor getelementptr_reg_size_ref_size_reg(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:tregister;indirect:boolean);
constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean); constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean);
constructor getelementptr_reg_tai_size_const(dst:tregister;const ai:taillvm;indextype:tdef;index1:ptrint;indirect:boolean);
{ e.g. dst = call retsize (paras) } { e.g. dst = call retsize (paras) }
constructor call_size_name_paras(dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist); constructor call_size_name_paras(dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
procedure loadtai(opidx: longint; _ai: tai);
procedure loaddef(opidx: longint; _def: tdef); procedure loaddef(opidx: longint; _def: tdef);
procedure loadsingle(opidx: longint; _sval: single); procedure loadsingle(opidx: longint; _sval: single);
procedure loaddouble(opidx: longint; _dval: double); procedure loaddouble(opidx: longint; _dval: double);
@ -232,6 +236,19 @@ uses
end; end;
procedure taillvm.loadtai(opidx: longint; _ai: tai);
begin
allocate_oper(opidx+1);
with oper[opidx]^ do
begin
if typ<>top_tai then
clearop(opidx);
ai:=_ai;
typ:=top_tai;
end;
end;
procedure taillvm.loaddef(opidx:longint;_def: tdef); procedure taillvm.loaddef(opidx:longint;_def: tdef);
begin begin
allocate_oper(opidx+1); allocate_oper(opidx+1);
@ -605,6 +622,17 @@ uses
end; end;
constructor taillvm.op_reg_size_tai_size(op:tllvmop;dst:tregister;fromsize:tdef;src:tai;tosize:tdef);
begin
create_llvm(op);
ops:=4;
loadreg(0,dst);
loaddef(1,fromsize);
loadtai(2,src);
loaddef(3,tosize);
end;
constructor taillvm.op_reg_size_ref_size(op: tllvmop; dst: tregister; fromsize: tdef; const src: treference; tosize: tdef); constructor taillvm.op_reg_size_ref_size(op: tllvmop; dst: tregister; fromsize: tdef; const src: treference; tosize: tdef);
begin begin
create_llvm(op); create_llvm(op);
@ -779,6 +807,31 @@ uses
loadconst(index+1,index1); loadconst(index+1,index1);
end; end;
constructor taillvm.getelementptr_reg_tai_size_const(dst: tregister; const ai: taillvm; indextype: tdef; index1: ptrint; indirect: boolean);
var
index: longint;
begin
create_llvm(la_getelementptr);
if indirect then
ops:=6
else
ops:=4;
loadreg(0,dst);
loadtai(1,ai);
if indirect then
begin
loaddef(2,s32inttype);
loadconst(3,0);
index:=4;
end
else
index:=2;
loaddef(index,indextype);
loadconst(index+1,index1);
end;
constructor taillvm.call_size_name_paras(dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist); constructor taillvm.call_size_name_paras(dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist);
begin begin
create_llvm(la_call); create_llvm(la_call);

View File

@ -71,6 +71,9 @@ interface
procedure WriteInstruction(hp : tai); procedure WriteInstruction(hp : tai);
protected protected
owner: TLLVMAssember; owner: TLLVMAssember;
function InstructionToString(hp : tai): TSymStr;
function getopstr(const o:toper; refwithalign: boolean) : TSymStr;
end; end;
@ -214,7 +217,7 @@ implementation
end; end;
function getopstr(const o:toper; refwithalign: boolean) : ansistring; function TLLVMInstrWriter.getopstr(const o:toper; refwithalign: boolean) : TSymStr;
var var
hs : ansistring; hs : ansistring;
doubleval: record doubleval: record
@ -289,6 +292,10 @@ implementation
begin begin
result:=getparas(o); result:=getparas(o);
end; end;
top_tai:
begin
result:=InstructionToString(o.ai);
end;
{$ifdef cpuextended} {$ifdef cpuextended}
top_extended80: top_extended80:
begin begin
@ -303,12 +310,17 @@ implementation
end; end;
procedure TLlvmInstrWriter.WriteInstruction(hp: tai); procedure TLLVMInstrWriter.WriteInstruction(hp: tai);
begin
owner.AsmWriteLn(InstructionToString(hp));
end;
function TLLVMInstrWriter.InstructionToString(hp: tai): TSymStr;
var var
op: tllvmop; op: tllvmop;
s: string; s, sep: TSymStr;
i, opstart: byte; i, opstart: byte;
sep: string[3];
done: boolean; done: boolean;
begin begin
op:=taillvm(hp).llvmopcode; op:=taillvm(hp).llvmopcode;
@ -345,8 +357,12 @@ implementation
la_ptrtoint, la_inttoptr, la_ptrtoint, la_inttoptr,
la_bitcast: la_bitcast:
begin begin
s:=s+getopstr(taillvm(hp).oper[0]^,false)+' = '+ { destination can be empty in case of nested constructs, or
llvm_op2str[op]+' '+ data initialisers }
if (taillvm(hp).oper[0]^.typ<>top_reg) or
(taillvm(hp).oper[0]^.reg<>NR_NO) then
s:=s+getopstr(taillvm(hp).oper[0]^,false)+' = ';
s:=s+llvm_op2str[op]+' '+
getopstr(taillvm(hp).oper[1]^,false)+' '+ getopstr(taillvm(hp).oper[1]^,false)+' '+
getopstr(taillvm(hp).oper[2]^,false)+' to '+ getopstr(taillvm(hp).oper[2]^,false)+' to '+
getopstr(taillvm(hp).oper[3]^,false); getopstr(taillvm(hp).oper[3]^,false);
@ -380,7 +396,7 @@ implementation
begin begin
s:=s+getreferencealignstring(taillvm(hp).oper[0]^.ref^) s:=s+getreferencealignstring(taillvm(hp).oper[0]^.ref^)
end; end;
owner.AsmWriteLn(s); result:=s;
end; end;
{****************************************************************************} {****************************************************************************}