Browse Source

* converted new_exception to hlcgobj
o also gets rid of the ifdefs

git-svn-id: branches/hlcgllvm@28377 -

Jonas Maebe 11 năm trước cách đây
mục cha
commit
9a683a0288
3 tập tin đã thay đổi với 61 bổ sung43 xóa
  1. 8 0
      compiler/hlcg2ll.pas
  2. 16 0
      compiler/hlcgobj.pas
  3. 37 43
      compiler/ncgutil.pas

+ 8 - 0
compiler/hlcg2ll.pas

@@ -246,6 +246,8 @@ unit hlcg2ll;
           procedure g_flags2ref(list: TAsmList; size: tdef; const f: tresflags; const ref:TReference); override;
 {$endif cpuflags}
 
+          procedure g_exception_reason_save(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const href: treference); override;
+
 //          procedure g_maybe_testvmt(list : TAsmList;reg:tregister;objdef:tobjectdef);
           {# This should emit the opcode to copy len bytes from the source
              to destination.
@@ -946,6 +948,12 @@ implementation
     begin
       cg.g_flags2ref(list,def_cgsize(size),f,ref);
     end;
+
+  procedure thlcg2ll.g_exception_reason_save(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const href: treference);
+    begin
+      cg.g_exception_reason_save(list,href);
+    end;
+
 {$endif cpuflags}
 
   procedure thlcg2ll.g_concatcopy(list: TAsmList; size: tdef; const source, dest: treference);

+ 16 - 0
compiler/hlcgobj.pas

@@ -392,6 +392,15 @@ unit hlcgobj;
           procedure g_flags2ref(list: TAsmList; size: tdef; const f: tresflags; const ref:TReference); virtual; abstract;
 {$endif cpuflags}
 
+          {#
+              This routine is used in exception management nodes. It should
+              save the exception reason currently in the reg. The
+              save should be done either to a temp (pointed to by href).
+              or on the stack (pushing the value on the stack).
+           }
+          procedure g_exception_reason_save(list : TAsmList; fromsize, tosize: tdef; reg: tregister; const href : treference);virtual;
+
+
           procedure g_maybe_testself(list : TAsmList; selftype: tdef; reg:tregister);
 //          procedure g_maybe_testvmt(list : TAsmList;reg:tregister;objdef:tobjectdef);
           {# This should emit the opcode to copy len bytes from the source
@@ -3022,6 +3031,13 @@ implementation
       end;
     end;
 
+
+  procedure thlcgobj.g_exception_reason_save(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const href: treference);
+    begin
+      a_load_reg_ref(list,fromsize,tosize,reg,href);
+    end;
+
+
   procedure thlcgobj.g_maybe_testself(list: TAsmList; selftype: tdef; reg: tregister);
     var
       OKLabel : tasmlabel;

+ 37 - 43
compiler/ncgutil.pas

@@ -402,71 +402,65 @@ implementation
 
 
     procedure new_exception(list:TAsmList;const t:texceptiontemps;exceptlabel:tasmlabel);
-      const
-{$ifdef cpu16bitaddr}
-        pushexceptaddr_frametype_cgsize = OS_S16;
-        setjmp_result_cgsize = OS_S16;
-{$else cpu16bitaddr}
-        pushexceptaddr_frametype_cgsize = OS_S32;
-        setjmp_result_cgsize = OS_S32;
-{$endif cpu16bitaddr}
       var
-        paraloc1,paraloc2,paraloc3 : tcgpara;
+        paraloc1, paraloc2, paraloc3, pushexceptres, setjmpres: tcgpara;
         pd: tprocdef;
-{$ifdef i8086}
-        tmpreg: TRegister;
-{$endif i8086}
+        tmpresloc: tlocation;
       begin
-        pd:=search_system_proc('fpc_pushexceptaddr');
         paraloc1.init;
         paraloc2.init;
         paraloc3.init;
+
+        { fpc_pushexceptaddr(exceptionframetype, setjmp_buffer, exception_address_chain_entry) }
+        pd:=search_system_proc('fpc_pushexceptaddr');
         paramanager.getintparaloc(pd,1,paraloc1);
         paramanager.getintparaloc(pd,2,paraloc2);
         paramanager.getintparaloc(pd,3,paraloc3);
         if pd.is_pushleftright then
           begin
-            { push type of exceptionframe }
-            cg.a_load_const_cgpara(list,pushexceptaddr_frametype_cgsize,1,paraloc1);
-            cg.a_loadaddr_ref_cgpara(list,t.jmpbuf,paraloc2);
-            cg.a_loadaddr_ref_cgpara(list,t.envbuf,paraloc3);
+            { type of exceptionframe }
+            hlcg.a_load_const_cgpara(list,paraloc1.def,1,paraloc1);
+            { setjmp buffer }
+            hlcg.a_loadaddr_ref_cgpara(list,rec_jmp_buf,t.jmpbuf,paraloc2);
+            { exception address chain entry }
+            hlcg.a_loadaddr_ref_cgpara(list,rec_exceptaddr,t.envbuf,paraloc3);
           end
         else
           begin
-            cg.a_loadaddr_ref_cgpara(list,t.envbuf,paraloc3);
-            cg.a_loadaddr_ref_cgpara(list,t.jmpbuf,paraloc2);
-            { push type of exceptionframe }
-            cg.a_load_const_cgpara(list,pushexceptaddr_frametype_cgsize,1,paraloc1);
+            hlcg.a_loadaddr_ref_cgpara(list,rec_exceptaddr,t.envbuf,paraloc3);
+            hlcg.a_loadaddr_ref_cgpara(list,rec_jmp_buf,t.jmpbuf,paraloc2);
+            hlcg.a_load_const_cgpara(list,paraloc1.def,1,paraloc1);
           end;
         paramanager.freecgpara(list,paraloc3);
         paramanager.freecgpara(list,paraloc2);
         paramanager.freecgpara(list,paraloc1);
-        cg.allocallcpuregisters(list);
-        cg.a_call_name(list,'FPC_PUSHEXCEPTADDR',false);
-        cg.deallocallcpuregisters(list);
+        { perform the fpc_pushexceptaddr call }
+        pushexceptres:=hlcg.g_call_system_proc(list,pd,[@paraloc1,@paraloc2,@paraloc3],nil);
+
+        { get the result }
+        location_reset(tmpresloc,LOC_REGISTER,def_cgsize(pushexceptres.def));
+        tmpresloc.register:=hlcg.getaddressregister(list,pushexceptres.def);
+        hlcg.gen_load_cgpara_loc(list,pushexceptres.def,pushexceptres,tmpresloc,true);
+        pushexceptres.resetiftemp;
 
+        { fpc_setjmp(result_of_pushexceptaddr_call) }
         pd:=search_system_proc('fpc_setjmp');
         paramanager.getintparaloc(pd,1,paraloc1);
-{$ifdef i8086}
-        if current_settings.x86memorymodel in x86_far_data_models then
-          begin
-            tmpreg:=cg.getintregister(list,OS_32);
-            cg.a_load_reg_reg(list,OS_16,OS_16,NR_FUNCTION_RESULT32_LOW_REG,tmpreg);
-            cg.a_load_reg_reg(list,OS_16,OS_16,NR_FUNCTION_RESULT32_HIGH_REG,GetNextReg(tmpreg));
-            cg.a_load_reg_cgpara(list,OS_32,tmpreg,paraloc1);
-          end
-        else
-{$endif i8086}
-          cg.a_load_reg_cgpara(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
-        paramanager.freecgpara(list,paraloc1);
-        cg.allocallcpuregisters(list);
-        cg.a_call_name(list,'FPC_SETJMP',false);
-        cg.deallocallcpuregisters(list);
-        cg.alloccpuregisters(list,R_INTREGISTER,[RS_FUNCTION_RESULT_REG]);
 
-        cg.g_exception_reason_save(list, t.reasonbuf);
-        cg.a_cmp_const_reg_label(list,setjmp_result_cgsize,OC_NE,0,cg.makeregsize(list,NR_FUNCTION_RESULT_REG,setjmp_result_cgsize),exceptlabel);
-        cg.dealloccpuregisters(list,R_INTREGISTER,[RS_FUNCTION_RESULT_REG]);
+        hlcg.a_load_reg_cgpara(list,pushexceptres.def,tmpresloc.register,paraloc1);
+        paramanager.freecgpara(list,paraloc1);
+        { perform the fpc_setjmp call }
+        setjmpres:=hlcg.g_call_system_proc(list,pd,[@paraloc1],nil);
+        setjmpres.check_simple_location;
+        if setjmpres.location^.loc<>LOC_REGISTER then
+          internalerror(2014080701);
+        hlcg.getcpuregister(list,setjmpres.location^.register);
+        hlcg.g_exception_reason_save(list,setjmpres.def,ossinttype,setjmpres.location^.register,t.reasonbuf);
+        { if we get 0 here in the function result register, it means that we
+          longjmp'd back here }
+        hlcg.a_cmp_const_reg_label(list,setjmpres.def,OC_NE,0,setjmpres.location^.register,exceptlabel);
+        hlcg.ungetcpuregister(list,setjmpres.location^.register);
+        setjmpres.resetiftemp;
         paraloc1.done;
         paraloc2.done;
         paraloc3.done;