Sfoglia il codice sorgente

Merged revisions 6728-6731,6735-6738,6740-6743,6755,6765,6771-6772,6784,6796-6797,6800,6806,6808-6809,6815,6824,6842-6843,6864-6866,6868-6869,6872,6882-6883,6889,6891,6893-6894,6896,6898,6901-6903,6908,6916,6921-6922,6924-6925,6927-6928,6930,6943-6946,6952,6954,6956,6974,6976,6996-6997,7002,7007,7016,7020-7021,7033,7037,7040,7042,7045,7068-7069,7075-7079,7087,7094,7098-7099,7101,7103,7109,7115-7119,7128,7136-7137,7139,7150,7160-7162,7175,7179,7190-7195,7198,7202,7205-7206,7208-7217,7220-7222,7225-7228,7230,7233,7239-7241,7244,7246,7263,7275,7277,7279-7281,7285,7288-7289,7291-7293,7296,7300,7303,7310,7318,7340-7341,7343,7345,7372-7373,7375-7376,7379,7381,7383-7388,7391-7392,7400,7404-7406,7411,7422,7425,7436,7441-7442,7444-7445,7450,7456,7463,7467,7475,7479,7486,7504,7506-7509,7522,7527,7534-7536,7558-7559,7563-7565,7567,7570-7571,7573-7576,7586,7589,7592-7594,7607,7612,7615,7619-7620,7622-7623,7626,7628,7631,7633,7646,7663,7677,7681-7683,7689,7697,7704-7712,7725,7736,7738,7740,7744-7746,7751,7753,7764,7767,7769-7770,7776-7777,7788,7830,7836-7839,7846,7849,7862,7864-7865,7869,7872,7877,7882,7927-7929,7953,7961,7967,7971,7986-7987,7990-7994,7998-8000,8004-8006,8008-8012,8016,8027,8034,8036-8037,8039,8044,8046,8048,8051,8060,8071,8075-8076,8082-8083,8087-8089,8095-8096,8099-8100,8136,8187,8190,8203,8206-8207,8212-8213,8215,8225,8227,8233-8239,8262,8302,8307,8309,8316,8318-8319,8336,8338-8340,8404,8410-8411,8430,8438-8442,8445-8446,8448,8450-8454,8456-8457,8459,8462,8469-8470,8472-8483,8486-8488,8490,8493,8496,8506,8535-8537,8539-8546,8554,8560,8575-8576,8581-8587,8590,8593-8594,8596,8600,8605,8607,8625,8630-8638,8640-8641,8659,8665,8667,8681-8682,8686-8687,8702,8705,8710-8714,8719,8721-8723,8727,8730-8731,8743,8747-8751,8766-8769,8797,8822,8831,8848-8849,8851,8879,8885-8889,8891-8893,8895,8897,8912,8917,8942,8950,8998,9000-9006,9017,9021,9024-9025,9033,9035,9040,9047,9059,9074,9076-9082,9084,9086,9088-9090,9096,9108,9114,9127,9130,9132-9133,9185,9211,9236-9238,9260,9262,9266,9269-9272,9276-9278,9295,9307-9308,9310,9322,9337,9340,9343-9344,9359,9373-9375,9387,9396,9399,9401-9402,9434,9450-9456,9459-9463,9466,9468-9469,9472-9473,9476-9477,9480,9491-9492,9529,9536,9550,9566-9568,9571,9573,9576-9577,9579,9583,9587,9632-9637,9655-9656,9658,9692,9694-9695,9697-9714,9720,9722,9729,9732-9733,9740,9745,9749-9750,9753-9757,9760-9766,9768-9770,9772-9774,9814,9819-9820 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r9017 | karoly | 2007-10-31 23:33:00 +0100 (Wed, 31 Oct 2007) | 2 lines

+ made m68k to compile system unit again
........
r9024 | karoly | 2007-11-01 01:22:47 +0100 (Thu, 01 Nov 2007) | 2 lines

+ quick hack to have linker support for amiga/m68k (it produces some kind of binary at least)
........
r9040 | karoly | 2007-11-01 15:16:17 +0100 (Thu, 01 Nov 2007) | 2 lines

+ first (failed) attempt to have a working stackframe generation
........
r9047 | karoly | 2007-11-01 17:04:16 +0100 (Thu, 01 Nov 2007) | 2 lines

+ fix(?) stack return address with an ugly hack...
........
r9127 | karoly | 2007-11-04 02:40:02 +0100 (Sun, 04 Nov 2007) | 3 lines

+ first attempt to implement a_call_reg
+ various other changes
........
r9130 | karoly | 2007-11-04 16:27:31 +0100 (Sun, 04 Nov 2007) | 2 lines

* removed a_call_reg hack, not needed after peter's latest fix
........
r9819 | florian | 2008-01-20 17:07:42 +0100 (Sun, 20 Jan 2008) | 2 lines

* spilling for neg, ext and extb fixed
........
r9820 | florian | 2008-01-20 17:13:20 +0100 (Sun, 20 Jan 2008) | 2 lines

* more spilling fixes
........

git-svn-id: branches/fixes_2_2@9839 -

peter 17 anni fa
parent
commit
49525fcea8

+ 6 - 2
compiler/aggas.pas

@@ -249,12 +249,16 @@ implementation
           '.data',
 { why doesn't .rodata work? (FK) }
 {$warning TODO .data.ro not yet working}
-{$if defined(arm) or defined(powerpc)}
+{$if defined(arm) or defined(powerpc)} 
           '.rodata',
 {$else arm}
           '.data',
 {$endif arm}
-          '.rodata',
+{$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
+          '.data',
+{$else}
+	  '.rodata',
+{$endif}
           '.bss',
           '.threadvar',
           '.pdata',

+ 4 - 2
compiler/m68k/aasmcpu.pas

@@ -513,7 +513,7 @@ type
       begin
         case opcode of
           A_MOVE, A_MOVEQ, A_ADD, A_ADDQ, A_ADDX, A_SUB, A_SUBQ,
-          A_AND, A_LSR, A_LSL, A_ASR, A_ASL, A_EOR, A_EORI:
+          A_AND, A_LSR, A_LSL, A_ASR, A_ASL, A_EOR, A_EORI, A_OR:
             if opnr=1 then begin
               result:=operand_write;
             end else begin
@@ -521,8 +521,10 @@ type
             end;
           A_TST,A_CMP,A_CMPI:
             result:=operand_read;
-          A_CLR,A_NEG,A_SXX:
+          A_CLR, A_SXX:
             result:=operand_write;
+          A_NEG, A_EXT, A_EXTB, A_NOT:
+            result:=operand_readwrite;
           else begin
 {$WARNING FIX ME!!! remove ugly debug code ... }
             writeln('M68K: unknown opcode when spilling: ',gas_op2str[opcode]);

+ 82 - 53
compiler/m68k/cgcpu.pas

@@ -19,7 +19,11 @@
 
  ****************************************************************************
 }
+{DEFINE DEBUG_CHARLIE}
+
+{$IFNDEF DEBUG_CHARLIE}
 {$WARNINGS OFF}
+{$ENDIF}
 unit cgcpu;
 
 {$i fpcdefs.inc}
@@ -236,7 +240,7 @@ unit cgcpu;
         ref : treference;
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_param_reg');
+//        writeln('a_param_reg');
 {$endif DEBUG_CHARLIE}
         { it's probably necessary to port this from x86 later, or provide an m68k solution (KB) }
 {$WARNING FIX ME! check_register_size()}
@@ -264,9 +268,8 @@ unit cgcpu;
         ref : treference;
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_param_const');
+//        writeln('a_param_const');
 {$endif DEBUG_CHARLIE}
-        { remove "not" to trigger the location bug (KB) }
         if use_push(cgpara) then
           begin
             cgpara.check_simple_location;
@@ -333,7 +336,7 @@ unit cgcpu;
         href : treference;
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_param_ref');
+//        writeln('a_param_ref');
 {$endif DEBUG_CHARLIE}
 
         { cgpara.size=OS_NO requires a copy on the stack }
@@ -368,7 +371,7 @@ unit cgcpu;
         opsize : topsize;
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_paramaddr_ref');
+//        writeln('a_paramaddr_ref');
 {$endif DEBUG_CHARLIE}
         with r do
           begin
@@ -453,12 +456,27 @@ unit cgcpu;
       end;
 
 
-    procedure tcg68k.a_call_reg(list : TAsmList;reg : tregister);
-     var
-       href : treference;
-     begin
-       reference_reset_base(href, reg, 0);
-       //!!! a_call_ref(list,href);
+    procedure tcg68k.a_call_reg(list : TAsmList;reg: tregister);
+      var
+        tmpref : treference;
+	tmpreg : tregister;
+      begin
+{$ifdef DEBUG_CHARLIE}
+	list.concat(tai_comment.create(strpnew('a_call_reg')));
+{$endif}
+	if isaddressregister(reg) then
+	  begin
+	    { if we have an address register, we can jump to the address directly }
+            reference_reset_base(tmpref,reg,0);
+	  end
+	else
+	  begin
+	    { if we have a data register, we need to move it to an address register first }
+	    tmpreg:=getaddressregister(list);
+            reference_reset_base(tmpref,tmpreg,0);
+	    list.concat(taicpu.op_reg_reg(A_MOVE,S_L,reg,tmpreg));
+	  end;
+	list.concat(taicpu.op_ref(A_JSR,S_NO,tmpref));
      end;
 
 
@@ -466,10 +484,10 @@ unit cgcpu;
     procedure tcg68k.a_load_const_reg(list : TAsmList;size : tcgsize;a : aint;register : tregister);
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_load_const_reg');
+//        writeln('a_load_const_reg');
 {$endif DEBUG_CHARLIE}
 
-        if getregtype(register)=R_ADDRESSREGISTER then
+        if isaddressregister(register) then
          begin
            list.concat(taicpu.op_const_reg(A_MOVE,S_L,longint(a),register))
          end
@@ -488,7 +506,7 @@ unit cgcpu;
     procedure tcg68k.a_load_const_ref(list : TAsmList; tosize: tcgsize; a : aint;const ref : treference);
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_load_const_ref');
+        list.concat(tai_comment.create(strpnew('a_load_const_ref')));
 {$endif DEBUG_CHARLIE}
 
         list.concat(taicpu.op_const_ref(A_MOVE,S_L,longint(a),ref));
@@ -499,13 +517,13 @@ unit cgcpu;
       var
        href : treference;
       begin
-         href := ref;
-         fixref(list,href);
+        href := ref;
+        fixref(list,href);
 {$ifdef DEBUG_CHARLIE}
-         writeln('a_load_reg_ref');
+        list.concat(tai_comment.create(strpnew('a_load_reg_ref')));
 {$endif DEBUG_CHARLIE}
-         { move to destination reference }
-         list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[fromsize],register,href));
+        { move to destination reference }
+        list.concat(taicpu.op_reg_ref(A_MOVE,TCGSize2OpSize[fromsize],register,href));
       end;
 
 
@@ -519,7 +537,7 @@ unit cgcpu;
         fixref(list,aref);
         fixref(list,bref);
 {$ifdef DEBUG_CHARLIE}
-        writeln('a_load_ref_ref');
+//        writeln('a_load_ref_ref');
 {$endif DEBUG_CHARLIE}
         list.concat(taicpu.op_ref_ref(A_MOVE,TCGSize2OpSize[fromsize],aref,bref));
       end;
@@ -1278,39 +1296,47 @@ unit cgcpu;
         ref  : TReference;
       begin
 {$ifdef DEBUG_CHARLIE}
-        writeln('proc entry, localsize:',localsize);
+//        writeln('proc entry, localsize:',localsize);
 {$endif DEBUG_CHARLIE}
-
+	
         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));
+	    if localsize<>0 then
+	      begin
+	        { size can't be negative }
+		if (localsize < 0) then
+		  internalerror(2006122601);
+	      
+                { Not to complicate the code generator too much, and since some }
+                { of the systems only support this format, the localsize cannot }
+                { exceed 32K in size.                                           }
+                if (localsize > high(smallint)) then
+                  CGMessage(cg_e_localsize_too_big);
+                
+                list.concat(taicpu.op_reg_const(A_LINK,S_W,NR_FRAME_POINTER_REG,-localsize));
+	      end
+	    else
+	      begin
+	        list.concat(taicpu.op_reg_const(A_LINK,S_W,NR_FRAME_POINTER_REG,0));
+(*		
+		{ FIXME! - Carl's original code uses this method. However,
+		  according to the 68060 users manual, a LINK is faster than
+		  two moves. So, use a link in #0 case too, for now. I'm not
+		  really sure tho', that LINK supports #0 disposition, but i
+		  see no reason why it shouldn't support it. (KB) }
+		  
+	        { when localsize = 0, use two moves, instead of link }
+		r:=NR_FRAME_POINTER_REG;
+		rsp:=NR_STACK_POINTER_REG;
+		
+	        reference_reset_base(ref,NR_STACK_POINTER_REG,0);
+		ref.direction:=dir_dec;
+                list.concat(taicpu.op_reg_ref(A_MOVE,S_L,r,ref));
+                list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r));
+		*)
+	      end;
           end;
       end;
-(*
-        r:=NR_FRAME_POINTER_REG;
-        rsp:=NR_STACK_POINTER_REG;
-        if localsize<>0 then
-           begin
-             { Not to complicate the code generator too much, and since some  }
-             { of the systems only support this format, the localsize cannot }
-             { exceed 32K in size.                                            }
-             if (localsize < low(smallint)) or (localsize > high(smallint)) then
-                CGMessage(cg_e_localsize_too_big);
-             list.concat(taicpu.op_reg_const(A_LINK,S_W,r,-localsize));
-           end { endif localsize <> 0 }
-          else
-           begin
-             reference_reset_base(ref,NR_STACK_POINTER_REG,0);
-             ref.direction:=dir_dec;
-             list.concat(taicpu.op_reg_ref(A_MOVE,S_L,r,ref));
-             list.concat(taicpu.op_reg_reg(A_MOVE,S_L,rsp,r));
-           end;
-           *)
-    //  end;
-
 
 {    procedure tcg68k.g_restore_frame_pointer(list : TAsmList);
       var
@@ -1333,16 +1359,19 @@ unit cgcpu;
           begin
             localsize := current_procinfo.calc_stackframe_size;
 {$ifdef DEBUG_CHARLIE}
-            writeln('proc exit with stackframe, size:',localsize);
+//            writeln('proc exit with stackframe, size:',localsize,' parasize:',parasize);
 {$endif DEBUG_CHARLIE}
             list.concat(taicpu.op_reg(A_UNLK,S_NO,NR_FRAME_POINTER_REG));
-            if (localsize<>0) then
+	    parasize := parasize - 8; { FIXME: ugly hack to correct the value...
+	                                but the real fun is, that works for now. 
+					i wonder where the extra 8 size comes from.
+					... maybe return address + framepointer size? (KB) }
+            if (parasize<>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}
-                inc(localsize,4);
-                list.concat(taicpu.op_const(A_RTD,S_NO,localsize));
+                list.concat(taicpu.op_const(A_RTD,S_NO,parasize));
               end
             else
               list.concat(taicpu.op_none(A_RTS,S_NO));
@@ -1350,7 +1379,7 @@ unit cgcpu;
         else
           begin
 {$ifdef DEBUG_CHARLIE}
-            writeln('proc exit, no stackframe');
+//            writeln('proc exit, no stackframe');
 {$endif DEBUG_CHARLIE}
             list.concat(taicpu.op_none(A_RTS,S_NO));
           end;

+ 1 - 0
compiler/m68k/cpubase.pas

@@ -256,6 +256,7 @@ unit cpubase;
 {$warning FIX ME!!! frame pointer is A5 on Amiga, but A6 on unixes?}
       NR_FRAME_POINTER_REG = NR_A5;
       RS_FRAME_POINTER_REG = RS_A5;
+
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM

+ 33 - 4
compiler/systems/t_amiga.pas

@@ -35,9 +35,9 @@ type
   TLinkerAmiga = class(texternallinker)
     private
       function WriteResponseFile(isdll: boolean): boolean;
-//      procedure SetAmiga68kInfo;
+      procedure SetAmiga68kInfo;
       procedure SetAmigaPPCInfo;
-//      function MakeAmiga68kExe: boolean;
+      function MakeAmiga68kExe: boolean;
       function MakeAmigaPPCExe: boolean;
     public
       constructor Create; override;
@@ -76,6 +76,13 @@ begin
   StaticLibFiles.doubles:=true;
 end;
 
+procedure TLinkerAmiga.SetAmiga68kInfo;
+begin
+  with Info do begin
+    ExeCmd[1]:='m68k-amiga-ld $OPT -d -n -o $EXE $RES';
+  end;
+end;
+
 procedure TLinkerAmiga.SetAmigaPPCInfo;
 begin
   with Info do begin
@@ -86,7 +93,7 @@ end;
 procedure TLinkerAmiga.SetDefaultInfo;
 begin
   case (target_info.system) of
-    system_m68k_amiga:      begin end;
+    system_m68k_amiga:      SetAmiga68kInfo;
     system_powerpc_amiga:   SetAmigaPPCInfo;
   end;
 end;
@@ -196,6 +203,26 @@ begin
   WriteResponseFile:=True;
 end;
 
+
+function TLinkerAmiga.MakeAmiga68kExe: boolean;
+var
+  BinStr,
+  CmdStr  : TCmdStr;
+  StripStr: string[40];
+begin
+  StripStr:='';
+  if (cs_link_strip in current_settings.globalswitches) then StripStr:='-s';
+
+  { Call linker }
+  SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr);
+  Replace(cmdstr,'$OPT',Info.ExtraOptions);
+  Replace(cmdstr,'$EXE',PathConv(maybequoted(ScriptFixFileName(current_module.exefilename^))));
+  Replace(cmdstr,'$RES',PathConv(maybequoted(ScriptFixFileName(outputexedir+Info.ResName))));
+  Replace(cmdstr,'$STRIP',StripStr);
+  MakeAmiga68kExe:=DoExec(FindUtil(BinStr),CmdStr,true,false);
+end;
+
+
 function TLinkerAmiga.MakeAmigaPPCExe: boolean;
 var
   BinStr,
@@ -214,6 +241,7 @@ begin
   MakeAmigaPPCExe:=DoExec(FindUtil(BinStr),CmdStr,true,false);
 end;
 
+
 function TLinkerAmiga.MakeExecutable:boolean;
 var
   success : boolean;
@@ -225,7 +253,7 @@ begin
   WriteResponseFile(false);
 
   case (target_info.system) of
-    system_m68k_amiga:      begin end;
+    system_m68k_amiga:      success:=MakeAmiga68kExe;
     system_powerpc_amiga:   success:=MakeAmigaPPCExe;
   end;
 
@@ -244,6 +272,7 @@ end;
 initialization
 {$ifdef m68k}
 {$warning No executable creation support for m68k yet!}
+  RegisterExternalLinker(system_m68k_Amiga_info,TLinkerAmiga);
   RegisterTarget(system_m68k_Amiga_info);
 {$endif m68k}
 {$ifdef powerpc}