FoxBackend.Mod 5.2 KB

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