FoxBackend.Mod 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. MODULE FoxBackend; (** AUTHOR "kaeserm,fof"; PURPOSE "Oberon Compiler: Common backend module"; **)
  2. IMPORT
  3. Streams, Diagnostics, Basic := FoxBasic, Global := FoxGlobal, Formats := FoxFormats, SyntaxTree := FoxSyntaxTree, SemanticChecker := FoxSemanticChecker, Options, Strings;
  4. TYPE
  5. SectionName = ARRAY 256 OF CHAR;
  6. Backend* = OBJECT
  7. VAR
  8. diagnostics-: Diagnostics.Diagnostics;
  9. log-: Streams.Writer;
  10. flags*: SET;
  11. system-: Global.System;
  12. error-: BOOLEAN;
  13. checker-: SemanticChecker.Checker;
  14. source-: SyntaxTree.String;
  15. findSectionName-: SectionName;
  16. findSectionOffset-: LONGINT;
  17. capabilities-: SET;
  18. oberon07-: BOOLEAN;
  19. instructionWidth -: LONGINT;
  20. hasLinkRegister-: BOOLEAN;
  21. name-: ARRAY 32 OF CHAR;
  22. (* constructor *)
  23. PROCEDURE & InitBackend *;
  24. BEGIN
  25. oberon07 := FALSE;
  26. system := NIL; (* only one instance per backend, never reallocate ! *)
  27. diagnostics := NIL;
  28. flags := {};
  29. error := FALSE;
  30. findSectionName := "";
  31. findSectionOffset := 0;
  32. instructionWidth := -1;
  33. hasLinkRegister := FALSE;
  34. END InitBackend;
  35. PROCEDURE SetOberon07*;
  36. BEGIN
  37. (*
  38. ASSERT(system = NIL); (* assert that system Object has not been requested yet *)
  39. object may be reused!
  40. *)
  41. oberon07 := TRUE
  42. END SetOberon07;
  43. PROCEDURE SetCapabilities*(capabilities: SET);
  44. BEGIN
  45. SELF.capabilities := capabilities;
  46. END SetCapabilities;
  47. PROCEDURE SetHasLinkRegister*;
  48. BEGIN
  49. hasLinkRegister := TRUE;
  50. END SetHasLinkRegister;
  51. PROCEDURE SetInstructionWidth* (instructionWidth: LONGINT);
  52. BEGIN
  53. SELF.instructionWidth := instructionWidth;
  54. (*TRACE(instructionWidth);*)
  55. END SetInstructionWidth;
  56. PROCEDURE ResetError*;
  57. BEGIN error := FALSE
  58. END ResetError;
  59. (* initialize backend for usage *)
  60. PROCEDURE Initialize*(diagnostics: Diagnostics.Diagnostics; log: Streams.Writer; flags: SET; checker: SemanticChecker.Checker; system: Global.System);
  61. BEGIN
  62. error := FALSE;
  63. SELF.diagnostics := diagnostics;
  64. SELF.log := log;
  65. SELF.flags := flags;
  66. SELF.checker := checker;
  67. SELF.system := system;
  68. END Initialize;
  69. PROCEDURE SetName*(CONST name: ARRAY OF CHAR);
  70. BEGIN
  71. COPY(name, SELF.name);
  72. END SetName;
  73. (* Get the system used by this backend (singleton) *)
  74. PROCEDURE GetSystem*():Global.System;
  75. BEGIN
  76. RETURN Global.DefaultSystem();
  77. END GetSystem;
  78. PROCEDURE Error*(CONST source: ARRAY OF CHAR; position: Basic.Position; errorNumber: LONGINT; CONST err: ARRAY OF CHAR);
  79. BEGIN
  80. IF (errorNumber # Basic.InvalidCode) OR (err # "") THEN
  81. Basic.ErrorC(diagnostics, source, position, errorNumber, err);
  82. END;
  83. error := TRUE;
  84. END Error;
  85. PROCEDURE ProcessSyntaxTreeModule*(syntaxTreeModule: SyntaxTree.Module): Formats.GeneratedModule;
  86. BEGIN RETURN NIL
  87. END ProcessSyntaxTreeModule;
  88. PROCEDURE ProcessIntermediateCodeModule*(intermediateCodeModule: Formats.GeneratedModule): Formats.GeneratedModule;
  89. BEGIN RETURN NIL (* only applicable for backends that use an intermediate backend *)
  90. END ProcessIntermediateCodeModule;
  91. (* general emision for chained backends -- used for active cells specification emission *)
  92. PROCEDURE Emit*(backend: Backend): BOOLEAN;
  93. BEGIN RETURN FALSE
  94. END Emit;
  95. PROCEDURE FindPC*(x: SyntaxTree.Module; CONST sectionName: ARRAY OF CHAR; sectionOffset: LONGINT);
  96. BEGIN
  97. END FindPC;
  98. (* code address check method to patch code addresses if in forbidden range (Spartan6!) *)
  99. PROCEDURE CheckCodeAddress*(VAR adr: LONGINT) ;
  100. BEGIN
  101. END CheckCodeAddress;
  102. (* method to query the instruction set description *)
  103. PROCEDURE GetDescription*(VAR instructionSet: ARRAY OF CHAR);
  104. BEGIN instructionSet := "undefined";
  105. END GetDescription;
  106. PROCEDURE CanPassInRegister*(type: SyntaxTree.Type): BOOLEAN;
  107. BEGIN RETURN FALSE
  108. END CanPassInRegister;
  109. PROCEDURE DefineOptions*(options: Options.Options);
  110. END DefineOptions;
  111. PROCEDURE GetOptions*(options: Options.Options);
  112. END GetOptions;
  113. PROCEDURE DefaultObjectFileFormat*(): Formats.ObjectFileFormat;
  114. BEGIN RETURN NIL
  115. END DefaultObjectFileFormat;
  116. PROCEDURE DefaultSymbolFileFormat*(): Formats.SymbolFileFormat;
  117. BEGIN RETURN NIL
  118. END DefaultSymbolFileFormat;
  119. END Backend;
  120. PROCEDURE GetDummy*():Backend;
  121. VAR backend: Backend;
  122. BEGIN
  123. NEW(backend);
  124. RETURN backend;
  125. END GetDummy;
  126. PROCEDURE GetBackendByName*(CONST name: ARRAY OF CHAR): Backend;
  127. VAR
  128. procname: ARRAY 256 OF CHAR;
  129. factory: PROCEDURE (): Backend;
  130. backend: Backend;
  131. BEGIN
  132. backend := NIL;
  133. IF Strings.Length(name) > 0 THEN
  134. GETPROCEDURE(name,"Get", factory); (* try long name for example -G=OCERABackend *)
  135. IF factory = NIL THEN (* try short name for example -G=ERA*)
  136. procname := "Fox";
  137. Strings.Append(procname, name);
  138. Strings.Append(procname, "Backend");
  139. GETPROCEDURE(procname,"Get", factory);
  140. END;
  141. IF factory # NIL THEN
  142. backend := factory();
  143. Assert(backend # NIL,"backend factory returned NIL backend");
  144. END;
  145. END;
  146. RETURN backend
  147. END GetBackendByName;
  148. PROCEDURE Assert(b: BOOLEAN; CONST reason: ARRAY OF CHAR);
  149. BEGIN
  150. ASSERT(b);
  151. END Assert;
  152. END FoxBackend.