FoxTRMAssembler.Mod 3.8 KB

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