Press enter to see results or esc to cancel.

Intermediate Code For Assembler Instructions

This procedure generates intermediate code from opcodes and references generated for current assembler instruction.

Procedure GenerateAsmStatementIntermediateCode;
Var AsmCodeBlock: PAsmCodeBlock;

  Procedure Generate_rcByte (OpCode: Byte);
  Var IntermediateCodeRecord: PIntermediateCodeRecord;
  begin
    IntermediateCodeRecord := IncreaseSymbolTable (stIntermediateCode, 2);
    With IntermediateCodeRecord^ do
      begin
        RecordType := icByte;
        ByteCode := OpCode;
      end;
  end;

  Procedure Generate_Reference (W2, W4, W6, W8: Word; B1: Byte);
  Var IntermediateCodeRecord: PIntermediateCodeRecord;
      Word1, Word2: Word;
  begin
    IntermediateCodeRecord := IncreaseSymbolTable (stIntermediateCode, 7);
    Word1 := W8 or Word (B1) shl 12;
    Word2 := W6;
    If (Word1 and $3000 = 0) and (Word1 and $8000 <> 0) then AsmError (InvalidSymbolReference);
    With IntermediateCodeRecord^ do
      begin
        If (Word1 and $C000 = $4000) and (Word2 <> 0) then RecordType := icReferenceAsmBlock else RecordType := icReference;
        ReferencedUnitRecordOfs := Word1;
        ReferencedBlockRecordOfs := Word2;
        ReferencedOfs := W2;
      end;
  end;

  Procedure Generate_rcJumpNear (W6, W8: Word; OpCode: Byte);
  Var IntermediateCodeRecord: PIntermediateCodeRecord;
  begin
    IntermediateCodeRecord := IncreaseSymbolTable (stIntermediateCode, 8);
    If W8 and $C000 <> $4000 then AsmError (InvalidSymbolReference);
    With IntermediateCodeRecord^ do
      begin
        RecordType := icJumpNear;
        JumpCode := OpCode;
        LabelIdentifierOffset := W6;
        Next_GOTO_Record := Last_GOTO_Record;
      end;
    Last_GOTO_Record := Ofs (IntermediateCodeRecord^);
  end;

  Procedure Generate_FPU_Instruction (B1_01, B1_FE, W2: Byte);
  begin
    Case B1_01 of
      0: begin
           If W2 = $9B then GenerateInstruction_TwoBytes ($CD, $3D) else
             If B1_FE = 0 then GenerateInstruction_Byte (W2) else
               GenerateInstruction_TwoBytes (B1_FE, W2);
         end;
      1: begin
           If B1_FE <> 0 then ModifyFPUInstructionForFixup (W2, B1_FE - $26) else ModifyFPUInstructionForFixup (W2, $FF);
           GenerateInstruction_Byte (W2);
         end;
    end;
  end;

begin
  AsmCodeBlock := @AsmIntermediateCodeRecord;
  While SizeOfAsmIntermediateCodeRecords > 0 do
    begin
      Dec (SizeOfAsmIntermediateCodeRecords, SizeOf (TAsmCodeBlock));
      With AsmCodeBlock^ do
        Case Recordtype of
          acByte:      Generate_rcByte (OpCode);
          acReference: Generate_Reference (icW2, icW4, icW6, icW8, icB1);
          acJumpNear:  Generate_rcJumpNear (icW6, icW8, JumpOpCode);
          else         Generate_FPU_Instruction (icB1 and $01, icB1 and $FE, icW2);
        end;
      Inc (AsmCodeBlock);
    end;
end;