source: trunk/Compiler/Modules/ASM8051/ProducerASM8051.pas

Last change on this file was 77, checked in by chronos, 6 months ago
  • Modified: Compiler targets moved into modules.
File size: 6.4 KB
Line 
1unit ProducerASM8051;
2
3interface
4
5uses
6 SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, SourceCodePascal, Producer, Generics.Collections;
8
9type
10 TMemoryType = (mtProgram, mtData, mtEEPROM);
11
12 TDevice = class
13 Family: string;
14 Memory: array[TMemoryType] of Integer;
15 end;
16
17 TAssemblerLine = class
18 LabelName: string;
19 Instruction: string;
20 Operand1: string;
21 Operand2: string;
22 SourceCode: string;
23 function AsString: string;
24 end;
25
26 { TProducerAsm8051 }
27
28 TProducerAsm8051 = class(TProducer)
29 private
30 procedure AddInstruction(LabelName, Instruction, Operand1,
31 Operand2: string);
32// procedure GenerateCommonBlock(CommonBlock: TCommonBlock; LabelPrefix: string);
33 procedure GenerateExpression(Expression: TExpression; LabelPrefix: string);
34 procedure GenerateProgram(ProgramBlock: TProgram);
35 procedure GenerateModule(Module: TSourceModule);
36 public
37 AssemblyCode: TObjectList<TAssemblerLine>;
38 procedure AssignToStringList(Target: TStringList); override;
39 procedure Produce(Module: TSourceModule); override;
40 constructor Create;
41 destructor Destroy; override;
42 end;
43
44
45implementation
46
47{ TAssemblerLine }
48
49function TAssemblerLine.AsString: string;
50begin
51 if LabelName = '' then LabelName := #9 else
52 LabelName := LabelName + ':'#9;
53 if Operand2 <> '' then Operand1 := Operand1 + ', ';
54
55 Result := LabelName + Instruction + ' ' + Operand1 + Operand2;
56end;
57
58{ TProducerAsm8051 }
59
60procedure TProducerAsm8051.AddInstruction(LabelName, Instruction, Operand1,
61 Operand2: string);
62var
63 NewLine: TAssemblerLine;
64begin
65 NewLine := TAssemblerLine.Create;
66 AssemblyCode.Add(NewLine);
67 NewLine.LabelName := LabelName;
68 NewLine.Instruction := Instruction;
69 NewLine.Operand1 := Operand1;
70 NewLine.Operand2 := Operand2;
71end;
72
73(*
74procedure TCommonBlock.GenerateAssembler(Compiler: TCompiler; LabelPrefix: string);
75var
76 I: Integer;
77 LabelName: string;
78begin
79 with Compiler do
80 for I := 0 to Operations.Count - 1 do
81 with TOperation(Operations[I]) do begin
82 if Referenced then LabelName := Name + '_L' + IntToStr(I)
83 else LabelName := '';
84 case Instruction of
85 inJump: begin
86 AddInstruction(LabelName, 'JMP', Name + '_L' + IntToStr(GotoAddress), '');
87 end;
88 inConditionalJump: begin
89 ExpressionTree.GenerateAssembler(Compiler, LabelPrefix + '_L' + IntToStr(GotoAddress));
90 AddInstruction(LabelName, 'BRCS', Name + '_L' + IntToStr(GotoAddress), '');
91 end;
92 inExpressionEvaluation: begin
93 if LabelName <> '' then AddInstruction(LabelName, '', '', '');
94 ExpressionTree.GenerateAssembler(Compiler, Name + '_L' + IntToStr(GotoAddress));
95 end;
96 inReturn:
97 AddInstruction(LabelName, 'RET', '', '');
98 end;
99 end;
100end;
101*)
102
103constructor TProducerAsm8051.Create;
104begin
105 AssemblyCode := TObjectList<TAssemblerLine>.Create;
106 {$IFDEF Windows}
107 CompilerPath := 'c:\ASM8051\ASM51.EXE';
108 {$ENDIF}
109end;
110
111destructor TProducerAsm8051.Destroy;
112begin
113 FreeAndNil(AssemblyCode);
114 inherited;
115end;
116
117(*
118 procedure TProducerAsm8051.GenerateCommonBlock(CommonBlock: TCommonBlock; LabelPrefix: string);
119 var
120 I: Integer;
121 LabelName: string;
122 begin
123 with CommonBlock do
124 for I := 0 to Operations.Count - 1 do
125 with TOperation(Operations[I]) do begin
126 if Referenced then LabelName := Name + '_L' + IntToStr(I)
127 else LabelName := '';
128 case Instruction of
129 inJump: begin
130 AddInstruction(LabelName, 'JMP', Name + '_L' + IntToStr(GotoAddress), '');
131 end;
132 inConditionalJump: begin
133 GenerateExpression(ExpressionTree, LabelPrefix + '_L' + IntToStr(GotoAddress));
134 AddInstruction(LabelName, 'BRCS', Name + '_L' + IntToStr(GotoAddress), '');
135 end;
136 inExpressionEvaluation: begin
137 if LabelName <> '' then AddInstruction(LabelName, '', '', '');
138 GenerateExpression(ExpressionTree, Name + '_L' + IntToStr(GotoAddress));
139 end;
140 inReturn:
141 AddInstruction(LabelName, 'RET', '', '');
142 end;
143 end;
144 end;
145*)
146
147procedure TProducerAsm8051.GenerateExpression(Expression: TExpression; LabelPrefix: string);
148var
149 I: Integer;
150begin
151 with Expression do
152 case NodeType of
153 ntNone: ;
154 ntVariable: if Assigned(Variable) then AddInstruction('', 'GETVAR', Variable.Name, '');
155 nTFunction: AddInstruction('', 'CALL', FunctionCall.FunctionRef.Name, '');
156 ntConstant: AddInstruction('', 'CONST', '', '');
157 ntOperator: begin
158 for I := 0 to SubItems.Count - 1 do
159 GenerateExpression(TExpression(SubItems[I]), LabelPrefix);
160 if OperatorName = '+' then AddInstruction('', 'ADD', '', '')
161 else if OperatorName = '-' then AddInstruction('', 'SUB', '', '')
162 else if OperatorName = '*' then AddInstruction('', 'MUL', '', '')
163 else if OperatorName = '/' then AddInstruction('', 'DIV', '', '')
164 else if OperatorName = 'div' then AddInstruction('', 'DIV', '', '')
165 else if OperatorName = 'mod' then AddInstruction('', 'MOD', '', '')
166 else if OperatorName = 'xor' then AddInstruction('', 'XOR', '', '')
167 else if OperatorName = 'or' then AddInstruction('', 'OR', '', '')
168 else if OperatorName = 'and' then AddInstruction('', 'AND', '', '')
169 else if OperatorName = 'not' then AddInstruction('', 'NEG', '', '')
170 else if OperatorName = ':=' then AddInstruction('', 'ST', '', '')
171 else if OperatorName = '>' then AddInstruction('', 'CP', '', '')
172 else if OperatorName = '>=' then AddInstruction('', 'CP', '', '')
173 else if OperatorName = '<' then AddInstruction('', 'CP', '', '')
174 else if OperatorName = '<=' then AddInstruction('', 'CP', '', '')
175 else if OperatorName = '=' then AddInstruction('', 'TST', '', '')
176 else if OperatorName = '<>' then AddInstruction('', 'CP', '', '');
177 end;
178 end;
179end;
180
181procedure TProducerAsm8051.GenerateProgram(ProgramBlock: TProgram);
182var
183 I: Integer;
184begin
185// with ProgramBlock do
186// for I := 0 to Modules.Count - 1 do
187// GenerateCommonBlock(TSourceModuleTSourceModule(Modules[I]), '');
188end;
189
190procedure TProducerAsm8051.GenerateModule(Module: TSourceModule);
191begin
192 Module.TargetFile := Module.Name + '.asm';
193end;
194
195procedure TProducerAsm8051.AssignToStringList(Target: TStringList);
196var
197 I: Integer;
198begin
199 Target.Clear;
200 for I := 0 to AssemblyCode.Count - 1 do begin
201 Target.Add(TAssemblerLine(AssemblyCode[I]).AsString);
202 end;
203end;
204
205procedure TProducerAsm8051.Produce(Module: TSourceModule);
206begin
207 GenerateModule(Module);
208end;
209
210end.
Note: See TracBrowser for help on using the repository browser.