瀏覽代碼

Start of PIC code support

git-svn-id: trunk@21777 -
pierre 13 年之前
父節點
當前提交
7982b34416
共有 1 個文件被更改,包括 64 次插入14 次删除
  1. 64 14
      compiler/mips/cgcpu.pas

+ 64 - 14
compiler/mips/cgcpu.pas

@@ -508,7 +508,7 @@ procedure TCGMIPS.init_register_allocators;
 begin
   inherited init_register_allocators;
 
-  if (cs_create_pic in current_settings.moduleswitches) and
+  if (cs_create_pic in current_settings.moduleswitches) and assigned(current_procinfo) and
     (pi_needs_got in current_procinfo.flags) then
     begin
       current_procinfo.got := NR_GP;
@@ -686,8 +686,18 @@ end;
 
 
 procedure TCGMIPS.a_call_name(list: tasmlist; const s: string; weak: boolean);
+var
+  href: treference;
 begin
-  list.concat(taicpu.op_sym(A_JAL,current_asmdata.RefAsmSymbol(s)));
+  if (cs_create_pic in current_settings.moduleswitches) then
+	begin
+	  reference_reset(href,sizeof(aint));
+	  href.symbol:=current_asmdata.RefAsmSymbol(s);
+	  a_loadaddr_ref_reg(list,href,NR_PIC_FUNC);
+	  list.concat(taicpu.op_reg(A_JALR,NR_PIC_FUNC));
+	end
+  else  
+    list.concat(taicpu.op_sym(A_JAL,current_asmdata.RefAsmSymbol(s)));
   { Delay slot }
   list.concat(taicpu.op_none(A_NOP));
 end;
@@ -695,6 +705,9 @@ end;
 
 procedure TCGMIPS.a_call_reg(list: tasmlist; Reg: TRegister);
 begin
+  if (cs_create_pic in current_settings.moduleswitches) and 
+     (Reg <> NR_PIC_FUNC) then
+    list.concat(taicpu.op_reg_reg(A_MOVE, reg, NR_PIC_FUNC));
   list.concat(taicpu.op_reg(A_JALR, reg));
   { Delay slot }
   list.concat(taicpu.op_none(A_NOP));
@@ -1339,7 +1352,7 @@ var
   lastintoffset,lastfpuoffset,
   nextoffset : aint;
   i : longint;
-  ra_save,framesave : taicpu;
+  ra_save,framesave,gp_save : taicpu;
   fmask,mask : dword;
   saveregs : tcpuregisterset;
   StoreOp : TAsmOp;
@@ -1388,8 +1401,12 @@ begin
   include(saveregs,RS_R31);
   if (TMIPSProcinfo(current_procinfo).needs_frame_pointer) then
     include(saveregs,RS_FRAME_POINTER_REG);
+  if (cs_create_pic in current_settings.moduleswitches) and
+     (pi_needs_got in current_procinfo.flags) then
+	include(saveregs,RS_GP);
   lastintoffset:=LocalSize;
   framesave:=nil;
+  gp_save:=nil;
 
   for reg:=RS_R1 to RS_R31 do
     begin
@@ -1403,10 +1420,15 @@ begin
             framesave:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
           else if (reg=RS_R31) then
             ra_save:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
+		  else if (reg=RS_GP) and
+                  (cs_create_pic in current_settings.moduleswitches) and
+                  (pi_needs_got in current_procinfo.flags) then
+			gp_save:=taicpu.op_const(A_P_CPRESTORE,nextoffset)
           else
             begin
               if cs_asm_source in current_settings.globalswitches then
-                helplist.concat(tai_comment.Create(strpnew(std_regname(newreg(R_INTREGISTER,reg,R_SUBWHOLE))+' register saved.')));
+                helplist.concat(tai_comment.Create(strpnew(
+				  std_regname(newreg(R_INTREGISTER,reg,R_SUBWHOLE))+' register saved.')));
               helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
             end;
           inc(nextoffset,4);
@@ -1418,13 +1440,26 @@ begin
   list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31));
   list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset)));
   list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset)));
+  if (cs_create_pic in current_settings.moduleswitches) and
+     (pi_needs_got in current_procinfo.flags) then
+	begin
+      list.concat(Taicpu.op_reg(A_P_CPLOAD,NR_PIC_FUNC));
+	end;
   list.concat(Taicpu.op_none(A_P_SET_NOREORDER));
   list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
 
   if (-LocalSize >= simm16lo) and (-LocalSize <= simm16hi) then
     begin
       if cs_asm_source in current_settings.globalswitches then
-        list.concat(tai_comment.Create(strpnew('Stack register updated substract '+tostr(LocalSize)+' for local size')));
+		begin
+          list.concat(tai_comment.Create(strpnew('Stack register updated substract '+tostr(LocalSize)+' for local size')));
+          list.concat(tai_comment.Create(strpnew(' 0-'+
+				   tostr(TMIPSProcInfo(current_procinfo).maxpushedparasize)+' for called function parameters')));
+          list.concat(tai_comment.Create(strpnew('Register save area at '+
+				   tostr(TMIPSProcInfo(current_procinfo).intregstart))));
+          list.concat(tai_comment.Create(strpnew('FPU register save area at '+
+				   tostr(TMIPSProcInfo(current_procinfo).floatregstart))));
+		end;
       list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize));
       if cs_asm_source in current_settings.globalswitches then
         list.concat(tai_comment.Create(strpnew('RA register saved.')));
@@ -1434,6 +1469,8 @@ begin
           if cs_asm_source in current_settings.globalswitches then
             list.concat(tai_comment.Create(strpnew('Frame S8/FP register saved.')));
           list.concat(framesave);
+          if cs_asm_source in current_settings.globalswitches then
+            list.concat(tai_comment.Create(strpnew('New frame FP register set to $sp+'+ToStr(LocalSize))));
           list.concat(Taicpu.op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,
             NR_STACK_POINTER_REG,LocalSize));
         end;
@@ -1458,6 +1495,14 @@ begin
             NR_STACK_POINTER_REG,NR_R1));
         end;
     end;
+  if assigned(gp_save) then
+	begin
+      if cs_asm_source in current_settings.globalswitches then
+        list.concat(tai_comment.Create(strpnew('GOT register saved.')));
+      list.concat(Taicpu.op_none(A_P_SET_MACRO));
+      list.concat(gp_save);
+      list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
+	end;
 
   with TMIPSProcInfo(current_procinfo) do
     begin
@@ -1517,7 +1562,7 @@ begin
         end;
     end;
   if (cs_create_pic in current_settings.moduleswitches) and
-    (pi_needs_got in current_procinfo.flags) then
+     (pi_needs_got in current_procinfo.flags) then
     begin
       current_procinfo.got := NR_GP;
     end;
@@ -1776,25 +1821,30 @@ end;
 
 procedure TCGMIPS.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const labelname: string; ioffset: longint);
 
-  procedure loadvmttor25;
+  procedure loadvmttorvmt;
     var
       href: treference;
     begin
       reference_reset_base(href, NR_R2, 0, sizeof(aint));  { return value }
-      cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25);
+      cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_VMT);
     end;
 
 
-   procedure op_onr25methodaddr;
+   procedure op_onrvmtmethodaddr;
      var
        href : treference;
+	   reg : tregister;
      begin
        if (procdef.extnumber=$ffff) then
          Internalerror(200006139);
        { call/jmp  vmtoffs(%eax) ; method offs }
-       reference_reset_base(href, NR_R25, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint));
-       cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25);
-       list.concat(taicpu.op_reg(A_JR, NR_R25));
+       reference_reset_base(href, NR_VMT, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint));
+       if (cs_create_pic in current_settings.moduleswitches) then
+	     reg:=NR_PIC_FUNC
+	   else
+	     reg:=NR_VMT;
+       cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, reg);
+       list.concat(taicpu.op_reg(A_JR, reg));
      end;
 var
   make_global: boolean;
@@ -1825,8 +1875,8 @@ begin
   if (po_virtualmethod in procdef.procoptions) and
       not is_objectpascal_helper(procdef.struct) then
   begin
-    loadvmttor25;
-    op_onr25methodaddr;
+    loadvmttorvmt;
+    op_onrvmtmethodaddr;
   end
   else
    list.concat(taicpu.op_sym(A_J,current_asmdata.RefAsmSymbol(procdef.mangledname)));