22Close24
PpHdOn the 2008-02-27 at 09:32pm
Nouvelle version du patch avec un support partiel de abs32 --> abs16 pour les sections BSS.
diff -ur ld-tigcc.orig/bincode/fix_m68k.c ld-tigcc/bincode/fix_m68k.c
--- ld-tigcc.orig/bincode/fix_m68k.c	2005-02-14 07:25:28.000000000 +0100
+++ ld-tigcc/bincode/fix_m68k.c	2008-02-27 21:19:54.000000000 +0100
@@ -27,6 +27,10 @@
 
 #include <stdlib.h>
 
+#ifdef FLASH_OS_SUPPORT
+static void M68kFixBssAbs16 (RELOC *Reloc, OPTIMIZE_INFO *OptimizeInfo);
+#endif
+
 // Apply generic code fixes and optimizations to a section.
 void M68kFixCode (SECTION *Section)
 {
@@ -80,6 +84,12 @@
 					// Fix and possibly optimize or remove the reloc.
 					M68kFixReloc (Reloc, TargetDistance, OptimizeInfo);
 				}
+#ifdef FLASH_OS_SUPPORT
+                                // If we are for a flash os program, and the target is a BSS Section.
+                                if (Dest->Parent->Type == PT_FLASH_OS && Reloc->Target.Symbol
+                                    && Reloc->Target.Symbol->Parent == Reloc->Parent->Parent->BSSSection)
+                                  M68kFixBssAbs16 (Reloc, OptimizeInfo);
+#endif
 			}
 		}
 		
@@ -662,6 +672,193 @@
 	}
 }
 
+
+#ifdef FLASH_OS_SUPPORT
+static void M68kFixBssAbs16 (RELOC *Reloc, OPTIMIZE_INFO *OptimizeInfo)
+{
+  SECTION *Section = Reloc->Parent;
+  I1 *Data = Section->Data;
+  OFFSET RelocLocation = Reloc->Location;
+  OFFSET OpcodeLocation;
+  I1 *Opcode;
+
+  // Return if there is no data, the reloc is not optimizable or if the reloc size is not 4 bytes.
+  // If the section doesn't support the cut ranges, it doesn't worth the effort (we don't any reloc to emit).
+  if (!Data || Reloc->Unoptimizable || Reloc->Size != 4 || !Section->CanCutRanges)
+    return;
+  if (!(Reloc->Target.Symbol))
+    return;
+
+  // Test is the reloc is optimizable: the absolute address muse be < 2^15
+  OpcodeLocation  = GetLocationOffset (Reloc->Target.Symbol->Parent, &(Reloc->Target)) + Reloc->FixedOffset;
+  OpcodeLocation += (OFFSET) (OptimizeInfo->FlashOSBSSStart);
+  if (OpcodeLocation >= 0x7FFF)
+    return;
+
+  // Most opcodes are two bytes long, and the reloc follows immediately.
+  OpcodeLocation = RelocLocation - 2;
+  // Safety check before accessing the section data.
+  if (!IsBinaryDataRange (Section, OpcodeLocation, OpcodeLocation + 6, Reloc))
+    return;
+
+  Opcode = Data + OpcodeLocation;
+
+  // *** Move Optimization ***
+  // Optimize LEA(.L) var.L,reg into LEA(.w) var.W),reg.
+  if ((((Opcode [0] & M68K_LEA_ABS_MASK_0) == M68K_LEA_ABS_0) && ((Opcode [1] & M68K_LEA_ABS_MASK_1) == M68K_LEA_ABS_1))
+      // Optimize PEA(.L) var.L into PEA(.L) var.W(%PC).
+      || ((Opcode [0] == M68K_PEA_ABS_0) && (Opcode [1] == M68K_PEA_ABS_1))
+      // Optimize MOVE.x var.L,reg/(reg)/(reg)+ into
+      // MOVE.x var.W(%PC),reg/(reg)/(reg)+.
+      || (((Opcode [0] & M68K_MOVE_ABS_REG_MASK_0) == M68K_MOVE_ABS_REG_0) && ((Opcode [1] & M68K_MOVE_ABS_REG_MASK_1) == M68K_MOVE_ABS_REG_1)
+          && (!((Opcode [0] & M68K_MOVE_ABS_REG_INV_0_MASK_0) == M68K_MOVE_ABS_REG_INV_0_0))
+          && (!(((Opcode [0] & M68K_MOVE_ABS_REG_INV_1_MASK_0) == M68K_MOVE_ABS_REG_INV_1_0) && ((Opcode [1] & M68K_MOVE_ABS_REG_INV_1_MASK_1) == M68K_MOVE_ABS_REG_INV_1_1))))
+      // Optimize MOVE.x var.L,-(reg) into
+      // MOVE.x var.W(%PC),-(reg).
+      || (((Opcode [0] & M68K_MOVE_ABS_PREDEC_MASK_0) == M68K_MOVE_ABS_PREDEC_0) && ((Opcode [1] & M68K_MOVE_ABS_PREDEC_MASK_1) == M68K_MOVE_ABS_PREDEC_1)
+          && (!((Opcode [0] & M68K_MOVE_ABS_PREDEC_INV_0_MASK_0) == M68K_MOVE_ABS_PREDEC_INV_0_0))))
+    {
+      OptimizeInfo->OptimizeMovesResult++;
+      if (OptimizeInfo->NearAssemblyResult >= 0)
+        OptimizeInfo->NearAssemblyResult += 2;
+      if (OptimizeInfo->OptimizeMoves)
+        {
+          // Turn the opcode into an abs16 one.
+          M68K_MAKE_ABS16_OPCODE_1 (Opcode [1]);
+          // Change the reloc to 2-byte absolute.
+          Reloc->Size = 2;
+          // Cut or fill the gained space.
+          M68kCutOrFillRange (Section, OpcodeLocation + 4, OpcodeLocation + 6, OptimizeInfo);
+        }
+      return;
+    }
+
+  // *** Test Optimization ***
+  // Optimize CMP.x var.L,reg into CMP.x var.W(%PC),reg.
+  if ((((Opcode [0] & M68K_CMP_ABS_REG_MASK_0) == M68K_CMP_ABS_REG_0) && ((Opcode [1] & M68K_CMP_ABS_REG_MASK_1) == M68K_CMP_ABS_REG_1)
+       && (!((Opcode [1] & M68K_CMP_ABS_REG_INV_0_MASK_1) == M68K_CMP_ABS_REG_INV_0_1)))
+      // Optimize BTST reg,var.L into BTST reg,var.W(%PC).
+      || (((Opcode [0] & M68K_BTST_REG_ABS_MASK_0) == M68K_BTST_REG_ABS_0) && ((Opcode [1] & M68K_BTST_REG_ABS_MASK_1) == M68K_BTST_REG_ABS_1)))
+    {
+      OptimizeInfo->OptimizeTestsResult++;
+      if (OptimizeInfo->NearAssemblyResult >= 0)
+        OptimizeInfo->NearAssemblyResult += 2;
+      if (OptimizeInfo->OptimizeTests)
+        {
+          // Turn the opcode into a abs16 one.
+          M68K_MAKE_ABS16_OPCODE_1 (Opcode [1]);
+          // Change the reloc to 2-byte absolute.
+          Reloc->Size = 2;
+          // Cut or fill the gained space.
+          M68kCutOrFillRange (Section, OpcodeLocation + 4, OpcodeLocation + 6, OptimizeInfo);
+        }
+      return;
+    }
+
+  // *** Calculation Optimization ***
+  // Optimize ADD/SUB.x var.L,reg into
+  // ADD/SUB.x var.W(%PC),reg.
+  if ((((Opcode [0] & M68K_ADDSUB_ABS_REG_0_MASK_0) == M68K_ADDSUB_ABS_REG_0_0) && ((Opcode [1] & M68K_ADDSUB_ABS_REG_0_MASK_1) == M68K_ADDSUB_ABS_REG_0_1))
+      || (((Opcode [0] & M68K_ADDSUB_ABS_REG_1_MASK_0) == M68K_ADDSUB_ABS_REG_1_0) && ((Opcode [1] & M68K_ADDSUB_ABS_REG_1_MASK_1) == M68K_ADDSUB_ABS_REG_1_1))
+      // Optimize MUL/DIV.x var.L,reg into
+      // MUL/DIV.x var.W(%PC),reg.
+      || (((Opcode [0] & M68K_MULDIV_ABS_REG_MASK_0) == M68K_MULDIV_ABS_REG_0) && ((Opcode [1] & M68K_MULDIV_ABS_REG_MASK_1) == M68K_MULDIV_ABS_REG_1))
+      // Optimize AND/OR.x var.L,reg into
+      // AND/OR.x var.W(%PC),reg.
+      || (((Opcode [0] & M68K_ANDOR_ABS_REG_MASK_0) == M68K_ANDOR_ABS_REG_0) && ((Opcode [1] & M68K_ANDOR_ABS_REG_MASK_1) == M68K_ANDOR_ABS_REG_1)))
+    {
+      OptimizeInfo->OptimizeCalcsResult++;
+      if (OptimizeInfo->NearAssemblyResult >= 0)
+        OptimizeInfo->NearAssemblyResult += 2;
+      if (OptimizeInfo->OptimizeCalcs)
+        {
+          // Turn the opcode into a abs16 one.
+          M68K_MAKE_ABS16_OPCODE_1 (Opcode [1]);
+          // Change the reloc to 2-byte .
+          Reloc->Size = 2;
+          // Cut or fill the gained space.
+          M68kCutOrFillRange (Section, OpcodeLocation + 4, OpcodeLocation + 6, OptimizeInfo);
+        }
+      return;
+    }
+
+  // Check opcodes of 8 bytes without prefix
+  if (!IsBinaryDataRange (Section, OpcodeLocation, OpcodeLocation + 8, Reloc))
+    return;
+
+  // Optimize MOVE.x var.L,ofs(reg) into
+  // MOVE.x var.W,ofs(reg)
+  // We cannot handle this above because of the
+  // offset, which comes after the reloc.
+  if (((Opcode [0] & M68K_MOVE_ABS_OFSREG_MASK_0) == M68K_MOVE_ABS_OFSREG_0) && ((Opcode [1] & M68K_MOVE_ABS_OFSREG_MASK_1) == M68K_MOVE_ABS_OFSREG_1)
+      && (!((Opcode [0] & M68K_MOVE_ABS_OFSREG_INV_0_MASK_0) == M68K_MOVE_ABS_OFSREG_INV_0_0)))
+    {
+      OptimizeInfo->OptimizeMovesResult++;
+      if (OptimizeInfo->NearAssemblyResult >= 0)
+        OptimizeInfo->NearAssemblyResult += 2;
+      if (OptimizeInfo->OptimizeMoves)
+        {
+          // Turn the opcode into a abs16 one.
+          M68K_MAKE_ABS16_OPCODE_1 (Opcode [1]);
+          // Move the offset to the correct place.
+          Opcode [4] = Opcode [6];
+          Opcode [5] = Opcode [7];
+          // Change the reloc to 2-byte abs16.
+          Reloc->Size = 2;
+          // Cut or fill the gained space.
+          M68kCutOrFillRange (Section, OpcodeLocation + 6, OpcodeLocation + 8, OptimizeInfo);
+        }
+      return;
+    }
+
+  // Now Opcode are bigger (8 bytes)
+  OpcodeLocation = RelocLocation - 4;
+  Opcode = Data + OpcodeLocation;
+
+  if (!IsBinaryDataRange (Section, OpcodeLocation, OpcodeLocation + 8, Reloc))
+    return;
+
+  // Optimize MOVEM.x var.L,regs into
+  // MOVEM var.W,regs.
+  if (((Opcode [0] & M68K_MOVEM_ABS_REGS_MASK_0) == M68K_MOVEM_ABS_REGS_0) && ((Opcode [1] & M68K_MOVEM_ABS_REGS_MASK_1) == M68K_MOVEM_ABS_REGS_1))
+    {
+      OptimizeInfo->OptimizeMovesResult++;
+      if (OptimizeInfo->NearAssemblyResult >= 0)
+        OptimizeInfo->NearAssemblyResult += 2;
+      if (OptimizeInfo->OptimizeMoves)
+        {
+          // Turn the opcode into a abs16 one.
+          M68K_MAKE_ABS16_OPCODE_1 (Opcode [1]);
+          // Change the reloc to 2-byte relative.
+          Reloc->Size = 2;
+          // Cut or fill the gained space.
+          M68kCutOrFillRange (Section, OpcodeLocation + 6, OpcodeLocation + 8, OptimizeInfo);
+        }
+    }
+
+  // Optimize BTST #num,var.L into
+  // BTST #num,var.W
+  if ((Opcode [0] == M68K_BTST_IMM_ABS_0) && (Opcode [1] == M68K_BTST_IMM_ABS_1) && (Opcode [2] == M68K_BTST_IMM_ABS_2))
+    {
+      OptimizeInfo->OptimizeTestsResult++;
+      if (OptimizeInfo->NearAssemblyResult >= 0)
+        OptimizeInfo->NearAssemblyResult += 2;
+      if (OptimizeInfo->OptimizeTests)
+        {
+          // Turn the opcode into a abs16 one.
+          M68K_MAKE_ABS16_OPCODE_1 (Opcode [1]);
+          // Change the reloc to 2-byte absolute.
+          Reloc->Size = 2;
+          // Cut or fill the gained space.
+          M68kCutOrFillRange (Section, OpcodeLocation + 6, OpcodeLocation + 8, OptimizeInfo);
+        }
+    }
+
+  // Nothing can be done
+  return;
+}
+#endif
+
 // Checks if a specific reloc might be optimizable. This is currently
 // limited to 4-bytes absolute relocs because that is the only case
 // this is needed for.
diff -ur ld-tigcc.orig/bincode/m68k.h ld-tigcc/bincode/m68k.h
--- ld-tigcc.orig/bincode/m68k.h	2004-12-23 00:12:09.000000000 +0100
+++ ld-tigcc/bincode/m68k.h	2008-02-27 19:56:44.000000000 +0100
@@ -37,6 +37,10 @@
 // Make a relative opcode out of an absolute one.
 #define M68K_MAKE_REL_OPCODE_1(Opcode_1) ((Opcode_1)++)
 
+// Make an absolute 16 bits opcode out of an absolute 32 bits address
+#define M68K_MAKE_ABS16_OPCODE_1(Opcode_1) ((Opcode_1)--)
+#define M68K_MAKE_ABS16_OPCODE_0(Opcode_0) ((Opcode_0)-=2)
+
 // *** General Branches ***
 
 // Opcode of the unconditional absolute JMP instruction.
diff -ur ld-tigcc.orig/export/exp_os.c ld-tigcc/export/exp_os.c
--- ld-tigcc.orig/export/exp_os.c	2004-12-23 00:12:09.000000000 +0100
+++ ld-tigcc/export/exp_os.c	2008-02-27 20:57:16.000000000 +0100
@@ -110,33 +110,43 @@
 		{
 			// Get the current file name for error messages.
 			const char *CurFileName = GetFileName (MainSection, Reloc->Location);
+                        OFFSET TargetLocation = 0;
 			
 			// If this can be resolved to a calculator-dependent value, write the
 			// value into the section data.
 			if (EmitCalcBuiltinValue (Reloc, DestCalc, File, FileSize, DataStart))
 				continue;
 			
-			// We can only emit relocs with a target symbol in the same section.
 			if (!(Reloc->Target.Symbol))
 				FailWithError (CurFileName, "Unresolved reference to `%s'.", Reloc->Target.SymbolName);
-			if (Reloc->Target.Symbol->Parent != MainSection)
-				FailWithError (CurFileName, "Cannot emit reloc to `%s' in different section.", Reloc->Target.SymbolName);
-			
+
 			// We can only emit 4-byte absolute relocs.
-			if (Reloc->Relative || (Reloc->Size != 4))
+                        // Or 2-byte absolute relocs to the BSS Section.
+			if (Reloc->Relative || (Reloc->Size != 4 && (Reloc->Size != 2 || Reloc->Target.Symbol->Parent != Program->BSSSection)))
 				FailWithError (CurFileName, "Cannot emit %ld byte %s reloc to `%s'.", (long) Reloc->Size, Reloc->Relative ? "relative" : "absolute", Reloc->Target.SymbolName);
-			
-			{
-				OFFSET TargetLocation = GetLocationOffset (MainSection, &(Reloc->Target)) + Reloc->FixedOffset;
+
+                        // Check for BSS Section
+                        if (Program->OptimizeInfo->FlashOSBSSStart > 0
+                            && Reloc->Target.Symbol->Parent == Program->BSSSection) {
+                          TargetLocation = GetLocationOffset (Program->BSSSection, &(Reloc->Target)) + Reloc->FixedOffset;
+                          TargetLocation += (OFFSET) (Program->OptimizeInfo->FlashOSBSSStart);
+                          ExportSeek (File, DataStart + Reloc->Location);
+                          ExportWriteTI (File, TargetLocation, Reloc->Size, TRUE, TRUE);
+                          continue;
+                        }
+			// We can only emit relocs with a target symbol in the same section.
+			else if (Reloc->Target.Symbol->Parent != MainSection)
+				FailWithError (CurFileName, "Cannot emit reloc to `%s' in different section.", Reloc->Target.SymbolName);
+
+			TargetLocation = GetLocationOffset (MainSection, &(Reloc->Target)) + Reloc->FixedOffset;
 				
-				TargetLocation += (OFFSET) (ROMBase + 0x12000);
-				ExportSeek (File, DataStart + Reloc->Location);
-				ExportWriteTI (File, TargetLocation, Reloc->Size, TRUE, TRUE);
+                        TargetLocation += (OFFSET) (ROMBase + 0x12000);
+                        ExportSeek (File, DataStart + Reloc->Location);
+                        ExportWriteTI (File, TargetLocation, Reloc->Size, TRUE, TRUE);
 				
-				// Do not increase the statistics, since that would give a false
-				// impression that the relocation entries actually take up some
-				// space in the OS.
-			}
+                        // Do not increase the statistics, since that would give a false
+                        // impression that the relocation entries actually take up some
+                        // space in the OS.
 		}
 	}
 	
diff -ur ld-tigcc.orig/intrface.h ld-tigcc/intrface.h
--- ld-tigcc.orig/intrface.h	2005-03-31 06:12:52.000000000 +0200
+++ ld-tigcc/intrface.h	2008-02-26 20:42:06.000000000 +0100
@@ -52,6 +52,8 @@
 		CutRanges,          // Cut unneeded section ranges when optimizing.
 		ReorderSections,    // Reorder sections to shorten references.
 		MergeConstants;     // Merge constants and strings to avoid duplication.
+        B4
+                FlashOSBSSStart;    // Flash OS Start of BSS Section
 	SI4
 		ProgramSize,            // Size of the on-calc program variable.
 		DataSize,               // Size of the data variable.
diff -ur ld-tigcc.orig/main.c ld-tigcc/main.c
--- ld-tigcc.orig/main.c	2005-04-22 21:34:10.000000000 +0200
+++ ld-tigcc/main.c	2008-02-26 20:42:02.000000000 +0100
@@ -389,6 +389,8 @@
 #ifdef FLASH_OS_SUPPORT
 				if (Program.Type == PT_FLASH_OS)
 				{
+                                        if (OptInfo->FlashOSBSSStart > 0 && Program.BSSSection)
+                                          Program.BSSSection->Handled = TRUE;
 					// Flash OS export: merge startup and normal sections separately.
 					// The resulting two parts are merged later, padding the first
 					// part to the full 24 KB of the OS startup area (base 1)
diff -ur ld-tigcc.orig/main_opt.inc ld-tigcc/main_opt.inc
--- ld-tigcc.orig/main_opt.inc	2006-07-16 03:58:15.000000000 +0200
+++ ld-tigcc/main_opt.inc	2008-02-26 20:42:17.000000000 +0100
@@ -67,6 +67,7 @@
 					        "     --native             Link in TIGCC native mode\n"
 #ifdef FLASH_OS_SUPPORT
 					        "     --flash-os           Create (unsigned) Flash OS\n"
+						"     --flash-os-bss-start=<start> Start of the BSS Section in RAM (For Flash OS)\n"
 #endif /* FLASH_OS_SUPPORT */
 #ifdef FARGO_SUPPORT
 					        "     --fargo              Create Fargo II program\n"
@@ -131,6 +132,16 @@
 				{
 					Program.Type = PT_FLASH_OS;
 					Warning (NULL, "Flash OS support in TIGCC is experimental.");
+					OutputBin = TRUE;
+				}
+				else
+				if (!(strncmp (Arg, "flash-os-bss-start=", sizeof ("flash-os-bss-start=") - 1)))
+				{
+					char *End;
+					Arg += sizeof ("flash-os-bss-start=") - 1;
+					OptInfo->FlashOSBSSStart = strtoul (Arg, &End, 0);
+					if (End == Arg)
+					   Error (NULL, "Invalid number for flash-os-bss-start");
 				}
 				else
 #endif /* FLASH_OS_SUPPORT */
diff -ur ld-tigcc.orig/manip.c ld-tigcc/manip.c
--- ld-tigcc.orig/manip.c	2005-07-02 00:08:58.000000000 +0200
+++ ld-tigcc/manip.c	2008-02-26 20:28:56.000000000 +0100
@@ -955,7 +955,7 @@
 {
 	BOOLEAN MergeForward = FALSE;
 	SECTION *CurMergedSection = NULL, *Section, *NextSection;
-	
+
 	// For each section...
 	for (Section = GetLast (Program->Sections); Section; Section = NextSection)
 	{
diff -ur ld-tigcc.orig/special.c ld-tigcc/special.c
--- ld-tigcc.orig/special.c	2005-08-03 02:31:49.000000000 +0200
+++ ld-tigcc/special.c	2008-02-27 19:25:12.000000000 +0100
@@ -332,8 +332,11 @@
 		Result = Result && AddGlobalImport (Program, "__handle_constructors");
 	if (Program->Destructors.Start)
 		Result = Result && AddGlobalImport (Program, "__handle_destructors");
-	if (Program->BSSSection && Program->BSSSection->Initialized)
-		Result = Result && AddGlobalImport (Program, "__initialize_bss");
+	if (Program->BSSSection && Program->BSSSection->Initialized
+#ifdef FLASH_OS_SUPPORT
+            && Program->Type != PT_FLASH_OS
+#endif /* FLASH_OS_SUPPORT */
+          )	Result = Result && AddGlobalImport (Program, "__initialize_bss");
 	
 	// Handle BSS section if any.
 	if (Program->BSSSection && (!(Program->BSSSection->Handled)))
@@ -738,6 +741,16 @@
 				else
 					return TRUE;
 			}
+			else if (SymNameMatches ("bss_even_end"))
+			{
+				if (Program->BSSSection)
+				{
+					NewSymbol = Program->BSSSection->SectionSymbol;
+					NewTargetOffset = (OFFSET) ((unsigned long) (Program->BSSSection->Size + 1) & ~1UL);
+				}
+				else
+					return TRUE;
+			}
 			else if (SymNameMatches ("bss_size"))
 			{
 				if (Program->BSSSection)
@@ -789,6 +802,18 @@
 				else
 					return TRUE;
 			}
+#ifdef FLASH_OS_SUPPORT
+                        else if (SymNameMatches ("archive_start"))
+                          {
+				if (Program->ResolveAllBuiltins && Program->MainSection)
+                                  {
+                                    SetToEntryPoint = TRUE;
+                                    NewValue = (OFFSET) ((unsigned long) (Program->MainSection->Size + 65535) & ~65535UL) - 0x02000;
+                                  }
+				else
+                                  return TRUE;
+                          }
+#endif
 			else if (SymNameMatches ("kernel_export_table"))
 			{
 				BOOLEAN HasExports = FALSE;

Ca triple la taille du patch !

Limitations: je n'ai la détection de code que celle déjà supporté par ld-tigcc.
Il faut rajouter le support des instructions suivantes couic
move. reg/(reg)/(reg)+,abs.l
move. -(reg),abs.l
move. off(reg),abs.l
move.l #imm,var
clr var.l
tst var.l
cmpi #imm,abs.l
addi #imm,var.l
subi #imm,var.l
ori #imm,var.l
andi #imm,var.l
eori #imm,var.l
movem. ...,var.l
(Dites moi si j'en ai oublié).

Sous l'assembleur, serait-il possible de spécifier par section, l'option cut-ranges ?
Sorte de HandleSpecialSymbol mais par section ?