2
0

FoxTRMAssembler.Mod 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. MODULE FoxTRMAssembler; (** AUTHOR ""; PURPOSE ""; *)
  2. IMPORT InstructionSet := FoxTRMInstructionSet, FoxAssembler, D := Debugging, Scanner := FoxScanner, Diagnostics;
  3. CONST Trace=FoxAssembler.Trace;
  4. TYPE
  5. Register* = LONGINT; (* index for InstructionSet.registers *)
  6. Operand* = InstructionSet.Operand;
  7. TYPE
  8. Assembler*= OBJECT (FoxAssembler.Assembler)
  9. VAR capabilities-: SET;
  10. instructionSet: InstructionSet.InstructionSet;
  11. PROCEDURE &Init2*(diagnostics: Diagnostics.Diagnostics; capabilities: SET; instructionSet: InstructionSet.InstructionSet);
  12. BEGIN
  13. SELF.capabilities := capabilities;
  14. SELF.instructionSet:=instructionSet;
  15. Init(diagnostics);
  16. END Init2;
  17. PROCEDURE Instruction*(CONST mnemonic: ARRAY OF CHAR);
  18. VAR i,numberOperands,mnem,pos: LONGINT; VAR operands: ARRAY 3 OF Operand; instruction: InstructionSet.Instruction;
  19. PROCEDURE ParseOperand;
  20. (* stub, must be overwritten by implementation *)
  21. VAR operand: InstructionSet.Operand;
  22. result: FoxAssembler.Result;
  23. register1,register2: SHORTINT;
  24. stop,memory: BOOLEAN;
  25. BEGIN
  26. stop := FALSE;
  27. register1 := InstructionSet.None;
  28. register2 := InstructionSet.None;
  29. result.type := -1;
  30. result.value := 0;
  31. IF numberOperands >= 2 THEN Error(errorPosition,"too many operands")
  32. ELSE
  33. memory := ThisToken(Scanner.LeftBracket);
  34. IF (symbol.token = Scanner.Identifier) & GetRegister(symbol.identifierString,register1) THEN
  35. NextSymbol;
  36. stop := ~ThisToken(Scanner.Plus);
  37. END;
  38. IF ~stop THEN
  39. IF (symbol.token = Scanner.Identifier) THEN
  40. IF GetRegister(symbol.identifierString,register2) THEN
  41. NextSymbol;
  42. ELSIF GetNonConstant(errorPosition,symbol.identifierString, result) THEN
  43. NextSymbol;
  44. ELSIF Expression(result,FALSE) THEN
  45. END;
  46. ELSIF Expression(result,FALSE) THEN
  47. END;
  48. END;
  49. IF memory & ExpectToken(Scanner.RightBracket) THEN
  50. instructionSet.InitMemory(operand,register1,result.value);
  51. ELSIF register1 # -1 THEN
  52. instructionSet.InitRegister(operand,register1);
  53. ELSE
  54. instructionSet.InitImmediate(operand,result.sizeInBits,result.value);
  55. END;
  56. IF result.fixup # NIL THEN
  57. instructionSet.AddFixup(operand,result.fixup);
  58. END;
  59. operands[numberOperands] := operand;
  60. END;
  61. END ParseOperand;
  62. BEGIN
  63. IF Trace THEN
  64. D.String("Instruction: "); D.String(mnemonic); D.String(" "); D.Ln;
  65. END;
  66. pos := errorPosition;
  67. mnem := instructionSet.FindMnemonic(mnemonic);
  68. IF mnem >= 0 THEN
  69. FOR i := 0 TO 2 DO instructionSet.InitOperand(operands[i]) END;
  70. numberOperands := 0;
  71. IF symbol.token # Scanner.Ln THEN
  72. REPEAT
  73. ParseOperand;
  74. INC(numberOperands);
  75. UNTIL error OR ~ThisToken(Scanner.Comma);
  76. END;
  77. IF ~error THEN
  78. instructionSet.MakeInstruction(instruction,mnem,operands[0],operands[1]);
  79. IF instruction.format = InstructionSet.None THEN
  80. ErrorSS(pos,"operand instruction format mismatch",mnemonic);
  81. ELSIF instructionSet.instructionFormats[instruction.format].capabilities > capabilities THEN
  82. Error(pos,"instruction not supported");
  83. ELSE
  84. IF pass < FoxAssembler.MaxPasses THEN
  85. (* not last pass: only increment the current PC by a unit *)
  86. section.resolved.SetPC(section.resolved.pc + 1)
  87. ELSE
  88. instructionSet.EmitInstruction(instruction, mnem, section.resolved);
  89. END;
  90. END;
  91. END
  92. ELSE
  93. ErrorSS(pos,"unknown instruction ",mnemonic)
  94. END
  95. END Instruction;
  96. PROCEDURE GetRegister(CONST ident: ARRAY OF CHAR; VAR register: SHORTINT): BOOLEAN;
  97. BEGIN
  98. register := instructionSet.FindRegister(ident);
  99. RETURN register # InstructionSet.None
  100. END GetRegister;
  101. END Assembler;
  102. END FoxTRMAssembler.
  103. SystemTools.Free FoxTRMAssembler FoxTRMInstructionSet ~