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
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 ?