FoxAMDBackend.SymU 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. MODULE FoxAMDBackend;
  2. IMPORT Basic := FoxBasic, Scanner := FoxScanner, SyntaxTree := FoxSyntaxTree, Global := FoxGlobal, Backend := FoxBackend, Sections := FoxSections, IntermediateCode := FoxIntermediateCode, IntermediateBackend := FoxIntermediateBackend, BinaryCode := FoxBinaryCode, InstructionSet := FoxAMD64InstructionSet, Assembler := FoxAMD64Assembler, SemanticChecker := FoxSemanticChecker, Formats := FoxFormats, Diagnostics, Streams, Options, Strings, ObjectFileFormat := FoxGenericObjectFile, Compiler, Machine, D := Debugging, CodeGenerators := FoxCodeGenerators, ObjectFile;
  3. CONST
  4. none = -1;
  5. RAX = InstructionSet.regRAX;
  6. RCX = InstructionSet.regRCX;
  7. RDX = InstructionSet.regRDX;
  8. RBX = InstructionSet.regRBX;
  9. RSP = InstructionSet.regRSP;
  10. RBP = InstructionSet.regRBP;
  11. RSI = InstructionSet.regRSI;
  12. RDI = InstructionSet.regRDI;
  13. R8 = InstructionSet.regR8;
  14. R9 = InstructionSet.regR9;
  15. R10 = InstructionSet.regR10;
  16. R11 = InstructionSet.regR11;
  17. R12 = InstructionSet.regR12;
  18. R13 = InstructionSet.regR13;
  19. R14 = InstructionSet.regR14;
  20. R15 = InstructionSet.regR15;
  21. EAX = InstructionSet.regEAX;
  22. ECX = InstructionSet.regECX;
  23. EDX = InstructionSet.regEDX;
  24. EBX = InstructionSet.regEBX;
  25. ESP = InstructionSet.regESP;
  26. EBP = InstructionSet.regEBP;
  27. ESI = InstructionSet.regESI;
  28. EDI = InstructionSet.regEDI;
  29. R8D = InstructionSet.regR8D;
  30. R9D = InstructionSet.regR9D;
  31. R10D = InstructionSet.regR10D;
  32. R11D = InstructionSet.regR11D;
  33. R12D = InstructionSet.regR12D;
  34. R13D = InstructionSet.regR13D;
  35. R14D = InstructionSet.regR14D;
  36. R15D = InstructionSet.regR15D;
  37. AX = InstructionSet.regAX;
  38. CX = InstructionSet.regCX;
  39. DX = InstructionSet.regDX;
  40. BX = InstructionSet.regBX;
  41. SI = InstructionSet.regSI;
  42. DI = InstructionSet.regDI;
  43. BP = InstructionSet.regBP;
  44. SP = InstructionSet.regSP;
  45. R8W = InstructionSet.regR8W;
  46. R9W = InstructionSet.regR9W;
  47. R10W = InstructionSet.regR10W;
  48. R11W = InstructionSet.regR11W;
  49. R12W = InstructionSet.regR12W;
  50. R13W = InstructionSet.regR13W;
  51. R14W = InstructionSet.regR14W;
  52. R15W = InstructionSet.regR15W;
  53. AL = InstructionSet.regAL;
  54. CL = InstructionSet.regCL;
  55. DL = InstructionSet.regDL;
  56. BL = InstructionSet.regBL;
  57. SIL = InstructionSet.regSIL;
  58. DIL = InstructionSet.regDIL;
  59. BPL = InstructionSet.regBPL;
  60. SPL = InstructionSet.regSPL;
  61. R8B = InstructionSet.regR8B;
  62. R9B = InstructionSet.regR9B;
  63. R10B = InstructionSet.regR10B;
  64. R11B = InstructionSet.regR11B;
  65. R12B = InstructionSet.regR12B;
  66. R13B = InstructionSet.regR13B;
  67. R14B = InstructionSet.regR14B;
  68. R15B = InstructionSet.regR15B;
  69. AH = InstructionSet.regAH;
  70. CH = InstructionSet.regCH;
  71. DH = InstructionSet.regDH;
  72. BH = InstructionSet.regBH;
  73. ST0 = InstructionSet.regST0;
  74. XMM0 = InstructionSet.regXMM0;
  75. XMM7 = InstructionSet.regXMM7;
  76. YMM0 = InstructionSet.regYMM0;
  77. YMM7 = InstructionSet.regYMM7;
  78. Low = 0;
  79. High = 1;
  80. FrameSpillStack = TRUE;
  81. TYPE
  82. Ticket = CodeGenerators.Ticket;
  83. PhysicalRegisters* = OBJECT (CodeGenerators.PhysicalRegisters)
  84. VAR
  85. toVirtual: ARRAY InstructionSet.numberRegisters OF Ticket;
  86. reserved: ARRAY InstructionSet.numberRegisters OF BOOLEAN;
  87. hint: LONGINT;
  88. useFPU: BOOLEAN;
  89. PROCEDURE ^ & InitPhysicalRegisters(fpu, cooperative: BOOLEAN);
  90. PROCEDURE ^ AllocationHint*(index: LONGINT);
  91. PROCEDURE ^ NumberRegisters*(): LONGINT;
  92. END PhysicalRegisters;
  93. PhysicalRegisters32 = OBJECT (PhysicalRegisters)
  94. PROCEDURE ^ & InitPhysicalRegisters32(fpu, cooperative: BOOLEAN);
  95. PROCEDURE ^ Allocate*(index: LONGINT; virtualRegister: Ticket);
  96. PROCEDURE ^ SetReserved*(index: LONGINT; res: BOOLEAN);
  97. PROCEDURE ^ Reserved*(index: LONGINT): BOOLEAN;
  98. PROCEDURE ^ Free*(index: LONGINT);
  99. PROCEDURE ^ NextFree*(CONST type: IntermediateCode.Type): LONGINT;
  100. PROCEDURE ^ Mapped*(physical: LONGINT): Ticket;
  101. PROCEDURE ^ Dump*(w: Streams.Writer);
  102. END PhysicalRegisters32;
  103. PhysicalRegisters64 = OBJECT (PhysicalRegisters)
  104. PROCEDURE ^ & InitPhysicalRegisters64(fpu, cooperative: BOOLEAN);
  105. PROCEDURE ^ SetReserved*(index: LONGINT; res: BOOLEAN);
  106. PROCEDURE ^ Reserved*(index: LONGINT): BOOLEAN;
  107. PROCEDURE ^ Allocate*(index: LONGINT; virtualRegister: Ticket);
  108. PROCEDURE ^ Free*(index: LONGINT);
  109. PROCEDURE ^ NextFree*(CONST type: IntermediateCode.Type): LONGINT;
  110. PROCEDURE ^ Mapped*(physical: LONGINT): Ticket;
  111. END PhysicalRegisters64;
  112. CodeGeneratorAMD64 = OBJECT (CodeGenerators.GeneratorWithTickets)
  113. VAR
  114. builtinsModuleName: SyntaxTree.IdentifierString;
  115. cpuBits: LONGINT;
  116. opBP, opSP, opRA, opRB, opRC, opRD, opRSI, opRDI, opR8, opR9, opR10, opR11, opR12, opR13, opR14, opR15: Assembler.Operand;
  117. BP, SP, RA, RD, RS, RC: LONGINT;
  118. emitter: Assembler.Emitter;
  119. backend: BackendAMD64;
  120. stackSize: LONGINT;
  121. spillStackStart: LONGINT;
  122. fpStackPointer: LONGINT;
  123. ap: Ticket;
  124. PROCEDURE ^ & InitGeneratorAMD64(CONST runtime: SyntaxTree.IdentifierString; diagnostics: Diagnostics.Diagnostics; backend: BackendAMD64);
  125. PROCEDURE ^ Section*(in: IntermediateCode.Section; out: BinaryCode.Section);
  126. PROCEDURE ^ Supported*(CONST instruction: IntermediateCode.Instruction; VAR moduleName, procedureName: ARRAY OF CHAR): BOOLEAN;
  127. PROCEDURE ^ GetPartType*(CONST type: IntermediateCode.Type; part: LONGINT; VAR typePart: IntermediateCode.Type);
  128. PROCEDURE ^ Move(VAR dest, src: Assembler.Operand; CONST type: IntermediateCode.Type);
  129. PROCEDURE ^ ToSpillStack*(ticket: Ticket);
  130. PROCEDURE ^ AllocateSpillStack*(size: LONGINT);
  131. PROCEDURE ^ ToRegister*(ticket: Ticket);
  132. PROCEDURE ^ ExchangeTickets*(ticket1, ticket2: Ticket);
  133. PROCEDURE ^ MappedTo(CONST virtualRegister: LONGINT; part: LONGINT; physicalRegister: LONGINT): BOOLEAN;
  134. PROCEDURE ^ ResultRegister(CONST type: IntermediateCode.Type; part: LONGINT): LONGINT;
  135. PROCEDURE ^ IsMemoryOperand(vop: IntermediateCode.Operand; part: LONGINT): BOOLEAN;
  136. PROCEDURE ^ IsRegister(CONST vop: IntermediateCode.Operand): BOOLEAN;
  137. PROCEDURE ^ PhysicalOperandType(CONST op: Assembler.Operand): IntermediateCode.Type;
  138. PROCEDURE ^ GetSpillOperand(ticket: Ticket; VAR op: Assembler.Operand);
  139. PROCEDURE ^ TicketToOperand(ticket: Ticket; VAR op: Assembler.Operand);
  140. PROCEDURE ^ GetTemporaryRegister(type: IntermediateCode.Type; VAR op: Assembler.Operand);
  141. PROCEDURE ^ GetImmediateMem(CONST vop: IntermediateCode.Operand; part: LONGINT; VAR imm: Assembler.Operand);
  142. PROCEDURE ^ GetImmediate(CONST virtual: IntermediateCode.Operand; part: LONGINT; VAR physical: Assembler.Operand; forbidden16Bit, push: BOOLEAN);
  143. PROCEDURE ^ GetMemory(CONST virtual: IntermediateCode.Operand; part: LONGINT; VAR physical: Assembler.Operand);
  144. PROCEDURE ^ GetRegister(CONST virtual: IntermediateCode.Operand; part: LONGINT; VAR physical: Assembler.Operand; VAR ticket: Ticket);
  145. PROCEDURE ^ MakeOperand(CONST vop: IntermediateCode.Operand; part: LONGINT; VAR op: Assembler.Operand; ticket: Ticket);
  146. PROCEDURE ^ MakeRegister(CONST vop: IntermediateCode.Operand; part: LONGINT; VAR op: Assembler.Operand);
  147. PROCEDURE ^ SpecialMove(op, back: LONGINT; canStoreToMemory: BOOLEAN; VAR dest, src: Assembler.Operand; type: IntermediateCode.Type);
  148. PROCEDURE ^ ModifyStackPointer(sizeInBytes: HUGEINT);
  149. PROCEDURE ^ IsFloat(CONST operand: IntermediateCode.Operand): BOOLEAN;
  150. PROCEDURE ^ IsVector(CONST operand: IntermediateCode.Operand): BOOLEAN;
  151. PROCEDURE ^ IsComplex(CONST operand: IntermediateCode.Operand): BOOLEAN;
  152. PROCEDURE ^ Generate*(VAR instruction: IntermediateCode.Instruction);
  153. PROCEDURE ^ PostGenerate*(CONST instruction: IntermediateCode.Instruction);
  154. PROCEDURE ^ EmitEnter(CONST instruction: IntermediateCode.Instruction);
  155. PROCEDURE ^ EmitLeave(CONST instruction: IntermediateCode.Instruction);
  156. PROCEDURE ^ EmitExit(CONST instruction: IntermediateCode.Instruction);
  157. PROCEDURE ^ EmitReturnFPU(CONST instruction: IntermediateCode.Instruction);
  158. PROCEDURE ^ EmitReturn(CONST instruction: IntermediateCode.Instruction; part: LONGINT);
  159. PROCEDURE ^ EmitMovFloat(CONST vdest, vsrc: IntermediateCode.Operand);
  160. PROCEDURE ^ EmitMov(CONST vdest, vsrc: IntermediateCode.Operand; part: LONGINT);
  161. PROCEDURE ^ EmitConvertFloat(CONST instruction: IntermediateCode.Instruction);
  162. PROCEDURE ^ EmitConvert(CONST vdest, vsrc: IntermediateCode.Operand; part: LONGINT);
  163. PROCEDURE ^ EmitResult(CONST instruction: IntermediateCode.Instruction);
  164. PROCEDURE ^ EmitResultFPU(CONST instruction: IntermediateCode.Instruction);
  165. PROCEDURE ^ EmitCall(CONST instruction: IntermediateCode.Instruction);
  166. PROCEDURE ^ PrepareOp3(CONST instruction: IntermediateCode.Instruction; part: LONGINT; VAR left, right: Assembler.Operand; VAR ticket: Ticket);
  167. PROCEDURE ^ PrepareOp2(CONST instruction: IntermediateCode.Instruction; part: LONGINT; VAR left: Assembler.Operand; VAR ticket: Ticket);
  168. PROCEDURE ^ FinishOp(CONST vop: IntermediateCode.Operand; part: LONGINT; left: Assembler.Operand; ticket: Ticket);
  169. PROCEDURE ^ EmitArithmetic3Part(CONST instruction: IntermediateCode.Instruction; part: LONGINT; opcode: LONGINT);
  170. PROCEDURE ^ EmitArithmetic3(CONST instruction: IntermediateCode.Instruction; opcode: LONGINT);
  171. PROCEDURE ^ EmitArithmetic3XMM(CONST instruction: IntermediateCode.Instruction; op32, op64: LONGINT);
  172. PROCEDURE ^ EmitArithmetic2(CONST instruction: IntermediateCode.Instruction; part: LONGINT; opcode: LONGINT);
  173. PROCEDURE ^ EmitArithmetic2XMM(CONST instruction: IntermediateCode.Instruction; op32, op64: LONGINT);
  174. PROCEDURE ^ EmitArithmetic3FPU(CONST instruction: IntermediateCode.Instruction; op: LONGINT);
  175. PROCEDURE ^ EmitArithmetic2FPU(CONST instruction: IntermediateCode.Instruction; opcode: LONGINT);
  176. PROCEDURE ^ EmitMul(CONST instruction: IntermediateCode.Instruction);
  177. PROCEDURE ^ EmitDivMod(CONST instruction: IntermediateCode.Instruction);
  178. PROCEDURE ^ EmitShift(CONST instruction: IntermediateCode.Instruction);
  179. PROCEDURE ^ EmitCas(CONST instruction: IntermediateCode.Instruction);
  180. PROCEDURE ^ EmitCopy(CONST instruction: IntermediateCode.Instruction);
  181. PROCEDURE ^ EmitFill(CONST instruction: IntermediateCode.Instruction; down: BOOLEAN);
  182. PROCEDURE ^ EmitBr(CONST instruction: IntermediateCode.Instruction);
  183. PROCEDURE ^ EmitPush(CONST vop: IntermediateCode.Operand; part: LONGINT);
  184. PROCEDURE ^ EmitPop(CONST vop: IntermediateCode.Operand; part: LONGINT);
  185. PROCEDURE ^ EmitPushFloat(CONST vop: IntermediateCode.Operand);
  186. PROCEDURE ^ EmitPopFloat(CONST vop: IntermediateCode.Operand);
  187. PROCEDURE ^ EmitNeg(CONST instruction: IntermediateCode.Instruction);
  188. PROCEDURE ^ EmitNegXMM(CONST instruction: IntermediateCode.Instruction);
  189. PROCEDURE ^ EmitAbs(CONST instruction: IntermediateCode.Instruction);
  190. PROCEDURE ^ EmitAbsXMM(CONST instruction: IntermediateCode.Instruction);
  191. PROCEDURE ^ EmitTrap(CONST instruction: IntermediateCode.Instruction);
  192. PROCEDURE ^ EmitAsm(CONST instruction: IntermediateCode.Instruction);
  193. END CodeGeneratorAMD64;
  194. BackendAMD64 = OBJECT (IntermediateBackend.IntermediateBackend)
  195. VAR
  196. cg: CodeGeneratorAMD64;
  197. bits: LONGINT;
  198. traceable: BOOLEAN;
  199. forceFPU: BOOLEAN;
  200. winAPIRegisters: ARRAY 4 OF LONGINT;
  201. cRegisters: ARRAY 6 OF LONGINT;
  202. intParameterIndex: WORD;
  203. floatParameterIndex: WORD;
  204. PROCEDURE ^ & InitBackendAMD64;
  205. PROCEDURE ^ Initialize*(diagnostics: Diagnostics.Diagnostics; log: Streams.Writer; flags: SET; checker: SemanticChecker.Checker; system: Global.System);
  206. PROCEDURE ^ GetSystem*(): Global.System;
  207. PROCEDURE ^ HardwareIntegerRegister(index: LONGINT; sizeInBits: LONGINT): LONGINT;
  208. PROCEDURE ^ HardwareFloatRegister(index: LONGINT; sizeInBits: LONGINT): LONGINT;
  209. PROCEDURE ^ ResetParameterRegisters*;
  210. PROCEDURE ^ GetParameterRegister*(callingConvention: SyntaxTree.CallingConvention; type: IntermediateCode.Type; VAR register: WORD): BOOLEAN;
  211. PROCEDURE ^ SupportedInstruction*(CONST instruction: IntermediateCode.Instruction; VAR moduleName, procedureName: ARRAY OF CHAR): BOOLEAN;
  212. PROCEDURE ^ GenerateBinary(module: Sections.Module; dump: Streams.Writer);
  213. PROCEDURE ^ ProcessIntermediateCodeModule*(intermediateCodeModule: Formats.GeneratedModule): Formats.GeneratedModule;
  214. PROCEDURE ^ FindPC*(x: SyntaxTree.Module; CONST sectionName: ARRAY OF CHAR; sectionOffset: LONGINT);
  215. PROCEDURE ^ CanPassInRegister*(type: SyntaxTree.Type): BOOLEAN;
  216. PROCEDURE ^ GetDescription*(VAR instructionSet: ARRAY OF CHAR);
  217. PROCEDURE ^ DefineOptions*(options: Options.Options);
  218. PROCEDURE ^ GetOptions*(options: Options.Options);
  219. PROCEDURE ^ DefaultObjectFileFormat*(): Formats.ObjectFileFormat;
  220. PROCEDURE ^ DefaultSymbolFileFormat*(): Formats.SymbolFileFormat;
  221. END BackendAMD64;
  222. VAR
  223. registerOperands: ARRAY InstructionSet.numberRegisters OF Assembler.Operand;
  224. usePool: BOOLEAN;
  225. opEAX, opECX, opEDX, opEBX, opESP, opEBP, opESI, opEDI, opAX, opCX, opDX, opBX, opSI, opDI, opAL, opCL, opDL, opBL, opAH, opCH, opDH, opBH, opST0, opRSP, opRBP: Assembler.Operand;
  226. unusable, split, blocked, free: CodeGenerators.Ticket;
  227. traceStackSize: LONGINT;
  228. PROCEDURE ^ RegularSectionCount(sectionList: Sections.SectionList): LONGINT;
  229. PROCEDURE ^ Assert(b: BOOLEAN; CONST s: ARRAY OF CHAR);
  230. PROCEDURE ^ Halt(CONST s: ARRAY OF CHAR);
  231. PROCEDURE ^ ResolvedSection(in: IntermediateCode.Section): BinaryCode.Section;
  232. PROCEDURE ^ Init;
  233. PROCEDURE ^ Get*(): Backend.Backend;
  234. PROCEDURE ^ Trace*;
  235. BEGIN
  236. END FoxAMDBackend.