|
@@ -26,7 +26,7 @@ unit nllvmflw;
|
|
|
interface
|
|
|
|
|
|
uses
|
|
|
- aasmbase,
|
|
|
+ aasmbase,aasmdata,
|
|
|
nflw, ncgflw, ncgnstfl;
|
|
|
|
|
|
type
|
|
@@ -34,6 +34,11 @@ interface
|
|
|
function getasmlabel: tasmlabel; override;
|
|
|
end;
|
|
|
|
|
|
+ tllvmexceptionstatehandler = class(tcgexceptionstatehandler)
|
|
|
+ class procedure new_exception(list: TAsmList; const t: texceptiontemps; out exceptstate: texceptionstate); override;
|
|
|
+ class procedure emit_except_label(list: TAsmList; var exceptionstate: texceptionstate); override;
|
|
|
+ end;
|
|
|
+
|
|
|
|
|
|
implementation
|
|
|
|
|
@@ -42,8 +47,11 @@ implementation
|
|
|
*****************************************************************************}
|
|
|
|
|
|
uses
|
|
|
- aasmdata;
|
|
|
-
|
|
|
+ systems,
|
|
|
+ symconst,symdef,llvmdef,
|
|
|
+ cgbase,cgutils,hlcgobj,
|
|
|
+ llvmbase,aasmllvm,
|
|
|
+ procinfo,llvmpi;
|
|
|
|
|
|
function tllvmlabelnode.getasmlabel: tasmlabel;
|
|
|
begin
|
|
@@ -61,7 +69,73 @@ implementation
|
|
|
result:=asmlabel
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
+{*****************************************************************************
|
|
|
+ tllvmexceptionstatehandler
|
|
|
+*****************************************************************************}
|
|
|
+
|
|
|
+ class procedure tllvmexceptionstatehandler.new_exception(list: TAsmList; const t: texceptiontemps; out exceptstate: texceptionstate);
|
|
|
+ var
|
|
|
+ landingpadlabel: TAsmLabel;
|
|
|
+ begin
|
|
|
+ inherited;
|
|
|
+ { all calls inside the exception block have to be invokes instead,
|
|
|
+ which refer to the exception label. We can't use the same label as the
|
|
|
+ one used by the setjmp/longjmp, because only invoke operations are
|
|
|
+ allowed to refer to a landingpad label -> create an extra label and
|
|
|
+ emit:
|
|
|
+ landingpadlabel:
|
|
|
+ %reg = landingpad ..
|
|
|
+ exceptstate.exceptionlabel:
|
|
|
+ <exception handling code>
|
|
|
+ }
|
|
|
+ current_asmdata.getjumplabel(landingpadlabel);
|
|
|
+ { for consistency checking when popping }
|
|
|
+ tllvmprocinfo(current_procinfo).pushexceptlabel(exceptstate.exceptionlabel);
|
|
|
+ tllvmprocinfo(current_procinfo).pushexceptlabel(landingpadlabel);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ class procedure tllvmexceptionstatehandler.emit_except_label(list: TAsmList; var exceptionstate: texceptionstate);
|
|
|
+ var
|
|
|
+ reg: tregister;
|
|
|
+ clause: taillvm;
|
|
|
+ exc: treference;
|
|
|
+ landingpaddef: trecorddef;
|
|
|
+ begin
|
|
|
+ { prevent fallthrough into the landingpad, not allowed }
|
|
|
+ hlcg.a_jmp_always(list,exceptionstate.exceptionlabel);
|
|
|
+ hlcg.a_label(list,tllvmprocinfo(current_procinfo).CurrExceptLabel);
|
|
|
+ { indicate that we will catch everything to LLVM's control flow
|
|
|
+ analysis; our personality function will (for now) indicate that it
|
|
|
+ doesn't actually want to handle any exceptions, so the stack unwinders
|
|
|
+ will ignore us anyway (our own exceptions are still handled via
|
|
|
+ setjmp/longjmp) }
|
|
|
+ clause:=taillvm.exceptclause(
|
|
|
+ la_catch,voidpointertype,nil,nil);
|
|
|
+ { dummy register (for now): we use the same code as on other platforms
|
|
|
+ to determine the exception type, our "personality function" won't
|
|
|
+ return anything useful }
|
|
|
+ reg:=hlcg.getintregister(list,u32inttype);
|
|
|
+ { use packrecords 1 because we don't want padding (LLVM 4.0+ requires
|
|
|
+ exactly two fields in this struct) }
|
|
|
+ landingpaddef:=llvmgettemprecorddef([voidpointertype,u32inttype],
|
|
|
+ 1,
|
|
|
+ targetinfos[target_info.system]^.alignment.recordalignmin,
|
|
|
+ targetinfos[target_info.system]^.alignment.maxCrecordalign);
|
|
|
+ list.concat(taillvm.landingpad(reg,landingpaddef,clause));
|
|
|
+ { remove current exception label from the stack }
|
|
|
+ tllvmprocinfo(current_procinfo).popexceptlabel(tllvmprocinfo(current_procinfo).CurrExceptLabel);
|
|
|
+ { consistency check }
|
|
|
+ tllvmprocinfo(current_procinfo).popexceptlabel(exceptionstate.exceptionlabel);
|
|
|
+ inherited;
|
|
|
+
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
begin
|
|
|
clabelnode:=tllvmlabelnode;
|
|
|
+ cexceptionstatehandler:=tllvmexceptionstatehandler;
|
|
|
end.
|
|
|
|