Procházet zdrojové kódy

* arm thumb: generate proper cfi

git-svn-id: trunk@48678 -
florian před 4 roky
rodič
revize
a3d68e6839
3 změnil soubory, kde provedl 32 přidání a 7 odebrání
  1. 11 6
      compiler/arm/cgcpu.pas
  2. 20 0
      compiler/cfidwarf.pas
  3. 1 1
      compiler/systems/i_linux.pas

+ 11 - 6
compiler/arm/cgcpu.pas

@@ -3733,6 +3733,15 @@ unit cgcpu;
                    if r in regs then
                      inc(registerarea,4);
                  list.concat(taicpu.op_regset(A_PUSH,R_INTREGISTER,R_SUBWHOLE,regs));
+                 { we need to run the loop twice to get cfi right }
+                 registerarea:=0;
+                 for r:=RS_R0 to RS_R15 do
+                   if r in regs then
+                     begin
+                       inc(registerarea,4);
+                       current_asmdata.asmcfi.cfa_offset(list,newreg(R_INTREGISTER,r,R_SUBWHOLE),-registerarea);
+                     end;
+                 current_asmdata.asmcfi.cfa_def_cfa_offset(list,registerarea);
                end;
 
             stackmisalignment:=registerarea mod current_settings.alignment.localalignmax;
@@ -3772,18 +3781,14 @@ unit cgcpu;
                     a_load_const_reg(list,OS_ADDR,-localsize,NR_R4);
                     list.concat(taicpu.op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R4));
                     include(regs,RS_R4);
-
-                    //!!!! if current_procinfo.framepointer=NR_STACK_POINTER_REG then
-                    //!!!!   a_reg_alloc(list,NR_R12);
-                    //!!!! a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
-                    //!!!! list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
-                    //!!!! a_reg_dealloc(list,NR_R12);
                   end;
+                current_asmdata.asmcfi.cfa_def_cfa_offset(list,registerarea+localsize);
               end;
 
             if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
               begin
                 list.concat(taicpu.op_reg_reg_const(A_ADD,current_procinfo.framepointer,NR_STACK_POINTER_REG,0));
+                current_asmdata.asmcfi.cfa_def_cfa_register(list,current_procinfo.framepointer);
               end;
           end;
       end;

+ 20 - 0
compiler/cfidwarf.pas

@@ -289,6 +289,26 @@ implementation
         list.concat(tai_const.create_uleb128bit(36));
         list.concat(tai_const.create_uleb128bit((-1) div data_alignment_factor));
       end;
+{$elseif defined(arm)}
+    procedure TDwarfAsmCFILowLevel.generate_initial_instructions(list:TAsmList);
+      begin
+        if GenerateThumbCode then
+          begin
+            list.concat(tai_const.create_8bit(DW_CFA_def_cfa));
+            list.concat(tai_const.create_uleb128bit(dwarf_reg(NR_STACK_POINTER_REG)));
+            list.concat(tai_const.create_uleb128bit(0));
+          end
+        else
+          begin
+            { FIXME!!! }
+            list.concat(tai_const.create_8bit(DW_CFA_def_cfa));
+            list.concat(tai_const.create_uleb128bit(dwarf_reg(NR_STACK_POINTER_REG)));
+            list.concat(tai_const.create_uleb128bit(sizeof(aint)));
+            list.concat(tai_const.create_8bit(DW_CFA_offset_extended));
+            list.concat(tai_const.create_uleb128bit(dwarf_reg(NR_RETURN_ADDRESS_REG)));
+            list.concat(tai_const.create_uleb128bit((-sizeof(aint)) div data_alignment_factor));
+          end;
+      end;
 {$else}
     { if more cpu dependend stuff is implemented, this needs more refactoring }
     procedure TDwarfAsmCFILowLevel.generate_initial_instructions(list:TAsmList);

+ 1 - 1
compiler/systems/i_linux.pas

@@ -679,7 +679,7 @@ unit i_linux;
             name         : 'Linux for ARMEL';
             shortname    : 'Linux';
             flags        : [tf_needs_symbol_size,tf_needs_symbol_type,tf_files_case_sensitive,
-                            tf_requires_proper_alignment,tf_safecall_exceptions,
+                            tf_needs_dwarf_cfi,tf_requires_proper_alignment,tf_safecall_exceptions,
 {$ifdef tls_threadvars}
                             tf_section_threadvars,
 {$endif tls_threadvars}