Browse Source

+ some messy m68k changes (first attempt to implement a_param_*)

git-svn-id: trunk@5782 -
Károly Balogh 18 years ago
parent
commit
e5249a8b56
3 changed files with 275 additions and 12 deletions
  1. 3 0
      compiler/m68k/ag68kgas.pas
  2. 268 11
      compiler/m68k/cgcpu.pas
  3. 4 1
      compiler/m68k/cpupara.pas

+ 3 - 0
compiler/m68k/ag68kgas.pas

@@ -299,6 +299,9 @@ interface
          s:=gas_op2str[op]+cond2str[taicpu(hp).condition]+gas_opsize2str[taicpu(hp).opsize]
          s:=gas_op2str[op]+cond2str[taicpu(hp).condition]+gas_opsize2str[taicpu(hp).opsize]
         else
         else
          s:=gas_op2str[op]+gas_opsize2str[taicpu(hp).opsize];
          s:=gas_op2str[op]+gas_opsize2str[taicpu(hp).opsize];
+        if op = A_FMOVE then begin
+          writeln('fmove! opsize:',dword(taicpu(hp).opsize));
+        end;
         getopcodestring:=s;
         getopcodestring:=s;
       end;
       end;
 
 

+ 268 - 11
compiler/m68k/cgcpu.pas

@@ -38,9 +38,18 @@ unit cgcpu;
       tcg68k = class(tcg)
       tcg68k = class(tcg)
         procedure init_register_allocators;override;
         procedure init_register_allocators;override;
         procedure done_register_allocators;override;
         procedure done_register_allocators;override;
+        
+        procedure a_param_reg(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);override;
+        procedure a_param_const(list : TAsmList;size : tcgsize;a : aint;const cgpara : tcgpara);override;
+        procedure a_param_ref(list : TAsmList;size : tcgsize;const r : treference;const cgpara : tcgpara);override;
+        procedure a_paramaddr_ref(list : TAsmList;const r : treference;const cgpara : tcgpara);override;
+        
         procedure a_call_name(list : TAsmList;const s : string);override;
         procedure a_call_name(list : TAsmList;const s : string);override;
         procedure a_call_reg(list : TAsmList;reg : tregister);override;
         procedure a_call_reg(list : TAsmList;reg : tregister);override;
+        
         procedure a_load_const_reg(list : TAsmList;size : tcgsize;a : aint;register : tregister);override;
         procedure a_load_const_reg(list : TAsmList;size : tcgsize;a : aint;register : tregister);override;
+        procedure a_load_const_ref(list : TAsmList; tosize: tcgsize; a : aint;const ref : treference);override;
+        
         procedure a_load_reg_ref(list : TAsmList;fromsize,tosize : tcgsize;register : tregister;const ref : treference);override;
         procedure a_load_reg_ref(list : TAsmList;fromsize,tosize : tcgsize;register : tregister;const ref : treference);override;
         procedure a_load_reg_reg(list : TAsmList;fromsize,tosize : tcgsize;reg1,reg2 : tregister);override;
         procedure a_load_reg_reg(list : TAsmList;fromsize,tosize : tcgsize;reg1,reg2 : tregister);override;
         procedure a_load_ref_reg(list : TAsmList;fromsize,tosize : tcgsize;const ref : treference;register : tregister);override;
         procedure a_load_ref_reg(list : TAsmList;fromsize,tosize : tcgsize;const ref : treference;register : tregister);override;
@@ -48,12 +57,16 @@ unit cgcpu;
         procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
         procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
         procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); override;
         procedure a_loadfpu_ref_reg(list: TAsmList; size: tcgsize; const ref: treference; reg: tregister); override;
         procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); override;
         procedure a_loadfpu_reg_ref(list: TAsmList; size: tcgsize; reg: tregister; const ref: treference); override;
+        
         procedure a_loadmm_reg_reg(list: TAsmList;fromsize,tosize : tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle); override;
         procedure a_loadmm_reg_reg(list: TAsmList;fromsize,tosize : tcgsize; reg1, reg2: tregister;shuffle : pmmshuffle); override;
         procedure a_loadmm_ref_reg(list: TAsmList;fromsize,tosize : tcgsize; const ref: treference; reg: tregister;shuffle : pmmshuffle); override;
         procedure a_loadmm_ref_reg(list: TAsmList;fromsize,tosize : tcgsize; const ref: treference; reg: tregister;shuffle : pmmshuffle); override;
         procedure a_loadmm_reg_ref(list: TAsmList;fromsize,tosize : tcgsize; reg: tregister; const ref: treference;shuffle : pmmshuffle); override;
         procedure a_loadmm_reg_ref(list: TAsmList;fromsize,tosize : tcgsize; reg: tregister; const ref: treference;shuffle : pmmshuffle); override;
         procedure a_parammm_reg(list: TAsmList; size: tcgsize; reg: tregister;const locpara : TCGPara;shuffle : pmmshuffle); override;
         procedure a_parammm_reg(list: TAsmList; size: tcgsize; reg: tregister;const locpara : TCGPara;shuffle : pmmshuffle); override;
+        
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: tcgsize; a: aint; reg: TRegister); override;
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: tcgsize; a: aint; reg: TRegister); override;
+        procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: aint; const ref: TReference); override;
         procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister); override;
         procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister); override;
+                
         procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
         procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
           l : tasmlabel);override;
           l : tasmlabel);override;
         procedure a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override;
         procedure a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); override;
@@ -180,6 +193,17 @@ unit cgcpu;
 {****************************************************************************}
 {****************************************************************************}
 {                               TCG68K                                       }
 {                               TCG68K                                       }
 {****************************************************************************}
 {****************************************************************************}
+
+
+    function use_push(const cgpara:tcgpara):boolean;
+      begin
+        result:=(not use_fixed_stack) and
+                assigned(cgpara.location) and
+                (cgpara.location^.loc=LOC_REFERENCE) and
+                (cgpara.location^.reference.index=NR_STACK_POINTER_REG);
+      end;
+
+
     procedure tcg68k.init_register_allocators;
     procedure tcg68k.init_register_allocators;
       begin
       begin
         inherited init_register_allocators;
         inherited init_register_allocators;
@@ -204,6 +228,166 @@ unit cgcpu;
       end;
       end;
 
 
 
 
+    procedure tcg68k.a_param_reg(list : TAsmList;size : tcgsize;r : tregister;const cgpara : tcgpara);
+      var
+        pushsize : tcgsize;
+      begin
+        writeln('a_param_reg');
+      {
+        check_register_size(size,r);
+        if use_push(cgpara) then
+          begin
+            cgpara.check_simple_location;
+            if tcgsize2size[cgpara.location^.size]>cgpara.alignment then
+              pushsize:=cgpara.location^.size
+            else
+              pushsize:=int_cgsize(cgpara.alignment);
+            list.concat(taicpu.op_reg(A_PUSH,tcgsize2opsize[pushsize],makeregsize(list,r,pushsize)));
+          end
+        else
+        }
+//          inherited a_param_reg(list,size,r,cgpara);
+      end;
+
+
+    procedure tcg68k.a_param_const(list : TAsmList;size : tcgsize;a : aint;const cgpara : tcgpara);
+      var
+        pushsize : tcgsize;
+        ref : treference;
+      begin
+        writeln('a_param_const');
+        
+        { remove "not" to trigger the location bug (KB) }
+        if not use_push(cgpara) then
+          begin
+            cgpara.check_simple_location;
+            if tcgsize2size[cgpara.location^.size]>cgpara.alignment then
+              pushsize:=cgpara.location^.size
+            else
+              pushsize:=int_cgsize(cgpara.alignment);
+              
+            reference_reset_base(ref, NR_STACK_POINTER_REG, 0);
+            ref.direction := dir_dec;
+            list.concat(taicpu.op_const_ref(A_MOVE,tcgsize2opsize[pushsize],a,ref));
+          end
+        else
+          inherited a_param_const(list,size,a,cgpara);
+      end;
+
+
+    procedure tcg68k.a_param_ref(list : TAsmList;size : tcgsize;const r : treference;const cgpara : tcgpara);
+(*
+        procedure pushdata(paraloc:pcgparalocation;ofs:aint);
+        var
+          pushsize : tcgsize;
+          tmpreg   : tregister;
+          href     : treference;
+        begin
+          if not assigned(paraloc) then
+            exit;
+          if (paraloc^.loc<>LOC_REFERENCE) or
+             (paraloc^.reference.index<>NR_STACK_POINTER_REG) or
+             (tcgsize2size[paraloc^.size]>sizeof(aint)) then
+            internalerror(200501162);
+          { Pushes are needed in reverse order, add the size of the
+            current location to the offset where to load from. This
+            prevents wrong calculations for the last location when
+            the size is not a power of 2 }
+          if assigned(paraloc^.next) then
+            pushdata(paraloc^.next,ofs+tcgsize2size[paraloc^.size]);
+          { Push the data starting at ofs }
+          href:=r;
+          inc(href.offset,ofs);
+          if tcgsize2size[paraloc^.size]>cgpara.alignment then
+            pushsize:=paraloc^.size
+          else
+            pushsize:=int_cgsize(cgpara.alignment);
+          if tcgsize2size[paraloc^.size]<cgpara.alignment then
+            begin
+              tmpreg:=getintregister(list,pushsize);
+              a_load_ref_reg(list,paraloc^.size,pushsize,href,tmpreg);
+              list.concat(taicpu.op_reg(A_PUSH,TCgsize2opsize[pushsize],tmpreg));
+            end
+          else
+            list.concat(taicpu.op_ref(A_PUSH,TCgsize2opsize[pushsize],href));
+        end;
+*)
+      var
+        len : aint;
+        href : treference;
+      begin
+        writeln('a_param_ref');
+      {
+        { cgpara.size=OS_NO requires a copy on the stack }
+        if use_push(cgpara) then
+          begin
+            { Record copy? }
+            if (cgpara.size in [OS_NO,OS_F64]) or (size=OS_NO) then
+              begin
+                cgpara.check_simple_location;
+                len:=align(cgpara.intsize,cgpara.alignment);
+                g_stackpointer_alloc(list,len);
+                reference_reset_base(href,NR_STACK_POINTER_REG,0);
+                g_concatcopy(list,r,href,len);
+              end
+            else
+              begin
+                if tcgsize2size[cgpara.size]<>tcgsize2size[size] then
+                  internalerror(200501161);
+                { We need to push the data in reverse order,
+                  therefor we use a recursive algorithm }
+                pushdata(cgpara.location,0);
+              end
+          end
+        else
+        }
+          inherited a_param_ref(list,size,r,cgpara);
+      end;
+
+
+    procedure tcg68k.a_paramaddr_ref(list : TAsmList;const r : treference;const cgpara : tcgpara);
+      var
+        tmpreg : tregister;
+        opsize : topsize;
+      begin
+        writeln('a_paramaddr_ref');
+        with r do
+          begin
+          {
+            if (segment<>NR_NO) then
+              cgmessage(cg_e_cant_use_far_pointer_there);
+            if use_push(cgpara) then
+              begin
+                cgpara.check_simple_location;
+                opsize:=tcgsize2opsize[OS_ADDR];
+                if (segment=NR_NO) and (base=NR_NO) and (index=NR_NO) then
+                  begin
+                    if assigned(symbol) then
+                      list.concat(Taicpu.Op_sym_ofs(A_PUSH,opsize,symbol,offset))
+                    else
+                      list.concat(Taicpu.Op_const(A_PUSH,opsize,offset));
+                  end
+                else if (segment=NR_NO) and (base=NR_NO) and (index<>NR_NO) and
+                        (offset=0) and (scalefactor=0) and (symbol=nil) then
+                  list.concat(Taicpu.Op_reg(A_PUSH,opsize,index))
+                else if (segment=NR_NO) and (base<>NR_NO) and (index=NR_NO) and
+                        (offset=0) and (symbol=nil) then
+                  list.concat(Taicpu.Op_reg(A_PUSH,opsize,base))
+                else
+                  begin
+                    tmpreg:=getaddressregister(list);
+                    a_loadaddr_ref_reg(list,r,tmpreg);
+                    list.concat(taicpu.op_reg(A_PUSH,opsize,tmpreg));
+                  end;
+              end
+            else
+            }
+//              inherited a_paramaddr_ref(list,r,cgpara);
+          end;
+      end;
+
+
+
     function tcg68k.fixref(list: TAsmList; var ref: treference): boolean;
     function tcg68k.fixref(list: TAsmList; var ref: treference): boolean;
 
 
        begin
        begin
@@ -263,6 +447,8 @@ unit cgcpu;
 
 
     procedure tcg68k.a_load_const_reg(list : TAsmList;size : tcgsize;a : aint;register : tregister);
     procedure tcg68k.a_load_const_reg(list : TAsmList;size : tcgsize;a : aint;register : tregister);
       begin
       begin
+        writeln('a_load_const_reg');
+        
         if getregtype(register)=R_ADDRESSREGISTER then
         if getregtype(register)=R_ADDRESSREGISTER then
          begin
          begin
            list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
            list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
@@ -278,6 +464,13 @@ unit cgcpu;
               list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
               list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
          end;
          end;
       end;
       end;
+      
+    procedure tcg68k.a_load_const_ref(list : TAsmList; tosize: tcgsize; a : aint;const ref : treference);
+      begin
+        writeln('a_load_const_ref');
+        
+        list.concat(taicpu.op_const_ref(A_MOVE,S_L,longint(a),ref));
+      end;
 
 
 
 
     procedure tcg68k.a_load_reg_ref(list : TAsmList;fromsize,tosize : tcgsize;register : tregister;const ref : treference);
     procedure tcg68k.a_load_reg_ref(list : TAsmList;fromsize,tosize : tcgsize;register : tregister;const ref : treference);
@@ -286,6 +479,7 @@ unit cgcpu;
       begin
       begin
          href := ref;
          href := ref;
          fixref(list,href);
          fixref(list,href);
+         writeln('a_load_reg_ref');
          { move to destination reference }
          { move to destination reference }
          list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[fromsize],register,href));
          list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[fromsize],register,href));
       end;
       end;
@@ -542,14 +736,38 @@ unit cgcpu;
                   end;
                   end;
               end;
               end;
           OP_XOR :
           OP_XOR :
-              Begin
-                 list.concat(taicpu.op_const_reg(A_EORI,S_L,a, reg));
+              begin
+                list.concat(taicpu.op_const_reg(A_EORI,S_L,a, reg));
               end;
               end;
         else
         else
             internalerror(20020729);
             internalerror(20020729);
          end;
          end;
       end;
       end;
 
 
+    procedure tcg68k.a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: aint; const ref: TReference);
+      var
+        opcode: tasmop;
+      begin
+        writeln('a_op_const_ref');
+        
+        optimize_op_const(op, a);
+        opcode := topcg2tasmop[op];        
+        case op of
+          OP_NONE :
+            begin
+              { opcode was optimized away }
+            end;
+          OP_MOVE :
+            begin            
+              { Optimized, replaced with a simple load }
+              a_load_const_ref(list,size,a,ref);
+            end;
+          else
+            begin
+              internalerror(2007010101);
+            end;
+        end;
+      end;
 
 
     procedure tcg68k.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister);
     procedure tcg68k.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister);
       var
       var
@@ -1007,11 +1225,22 @@ unit cgcpu;
       end;
       end;
 
 
 
 
-    procedure tcg68k.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
+    procedure tcg68k.g_proc_entry(list: TAsmList; localsize: longint; nostackframe:boolean);
       var
       var
-        r,rsp:Tregister;
-        ref : treference;
+        r,rsp: TRegister;
+        ref  : TReference;
       begin
       begin
+        writeln('proc entry, localsize:',localsize);
+
+        if not nostackframe then 
+          begin
+            if (localsize<>0) then localsize:=-localsize;
+            // size can't be negative
+            if (localsize>0) then internalerror(2006122601);
+            list.concat(taicpu.op_reg_const(A_LINK,S_W,NR_FRAME_POINTER_REG,localsize));
+          end;
+      end;
+(*      
         r:=NR_FRAME_POINTER_REG;
         r:=NR_FRAME_POINTER_REG;
         rsp:=NR_STACK_POINTER_REG;
         rsp:=NR_STACK_POINTER_REG;
         if localsize<>0 then
         if localsize<>0 then
@@ -1030,7 +1259,8 @@ unit cgcpu;
              list.concat(taicpu.op_reg_ref(A_MOVE,S_L,r,ref));
              list.concat(taicpu.op_reg_ref(A_MOVE,S_L,r,ref));
              list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r));
              list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r));
            end;
            end;
-      end;
+           *)
+    //  end;
 
 
 
 
 {    procedure tcg68k.g_restore_frame_pointer(list : TAsmList);
 {    procedure tcg68k.g_restore_frame_pointer(list : TAsmList);
@@ -1042,14 +1272,40 @@ unit cgcpu;
       end;
       end;
 }
 }
 
 
-    procedure tcg68k.g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean);
+    procedure tcg68k.g_proc_exit(list : TAsmList; parasize: longint; nostackframe: boolean);
       var
       var
-        r,hregister : tregister;
-        ref : treference;
-      begin
+//        r,hregister : TRegister;
+        localsize: aint;
+        spr : TRegister;
+        fpr : TRegister;
+        ref : TReference;
+      begin 
+        if not nostackframe then
+          begin
+            localsize := current_procinfo.calc_stackframe_size;
+            writeln('proc exit with stackframe, size:',localsize);
+            list.concat(taicpu.op_reg(A_UNLK,S_NO,NR_FRAME_POINTER_REG));
+            if (localsize<>0) then 
+              begin
+                { only 68020+ supports RTD, so this needs another code path
+                  for 68000 and Coldfire (KB) }
+{$WARNING 68020+ only code generation, without fallback}
+                localsize+=4;
+                list.concat(taicpu.op_const(A_RTD,S_NO,localsize));
+              end
+            else 
+              list.concat(taicpu.op_none(A_RTS,S_NO));
+          end
+        else 
+          begin
+            writeln('proc exit, no stackframe');
+            list.concat(taicpu.op_none(A_RTS,S_NO)); 
+          end;
+          
 //         writeln('g_proc_exit');
 //         writeln('g_proc_exit');
          { Routines with the poclearstack flag set use only a ret.
          { Routines with the poclearstack flag set use only a ret.
-           also routines with parasize=0     }
+           also  routines with parasize=0     }
+           (*
          if current_procinfo.procdef.proccalloption in clearstack_pocalls then
          if current_procinfo.procdef.proccalloption in clearstack_pocalls then
            begin
            begin
              { complex return values are removed from stack in C code PM }
              { complex return values are removed from stack in C code PM }
@@ -1097,6 +1353,7 @@ unit cgcpu;
                 list.concat(taicpu.op_none(A_RTS,S_NO));
                 list.concat(taicpu.op_none(A_RTS,S_NO));
                end;
                end;
            end;
            end;
+           *)
       end;
       end;
 
 
 
 

+ 4 - 1
compiler/m68k/cpupara.pas

@@ -303,6 +303,7 @@ unit cpupara;
             if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
             if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) and
                is_array_of_const(paradef) then
                is_array_of_const(paradef) then
               begin
               begin
+                writeln('loc register');
                 paraloc:=hp.paraloc[side].add_location;
                 paraloc:=hp.paraloc[side].add_location;
                 { hack: the paraloc must be valid, but is not actually used }
                 { hack: the paraloc must be valid, but is not actually used }
                 paraloc^.loc:=LOC_REGISTER;
                 paraloc^.loc:=LOC_REGISTER;
@@ -316,6 +317,7 @@ unit cpupara;
                is_open_array(paradef) or
                is_open_array(paradef) or
                is_array_of_const(paradef) then
                is_array_of_const(paradef) then
               begin
               begin
+                writeln('loc register');
                 paradef:=voidpointertype;
                 paradef:=voidpointertype;
                 loc:=LOC_REGISTER;
                 loc:=LOC_REGISTER;
                 paracgsize := OS_ADDR;
                 paracgsize := OS_ADDR;
@@ -337,6 +339,7 @@ unit cpupara;
                     paralen := tcgsize2size[OS_ADDR];
                     paralen := tcgsize2size[OS_ADDR];
                   end;
                   end;
               end;
               end;
+              
             hp.paraloc[side].alignment:=std_param_align;
             hp.paraloc[side].alignment:=std_param_align;
             hp.paraloc[side].size:=paracgsize;
             hp.paraloc[side].size:=paracgsize;
             hp.paraloc[side].intsize:=paralen;
             hp.paraloc[side].intsize:=paralen;
@@ -384,7 +387,7 @@ unit cpupara;
                 else { LOC_REFERENCE }
                 else { LOC_REFERENCE }
 }
 }
                   begin
                   begin
-//		    writeln('loc reference');
+		    writeln('loc reference');
                     paraloc^.loc:=LOC_REFERENCE;
                     paraloc^.loc:=LOC_REFERENCE;
                     paraloc^.size:=int_cgsize(paralen);
                     paraloc^.size:=int_cgsize(paralen);
                     if (side = callerside) then
                     if (side = callerside) then