Subversion Repositories Kolibri OS

Rev

Rev 7209 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7209 Rev 7597
Line 1... Line 1...
1
(*
1
(*
2
    Copyright 2016, 2017, 2018 Anton Krotov
2
    BSD 2-Clause License
Line 3... Line 3...
3
 
3
 
4
    This file is part of Compiler.
-
 
5
 
-
 
6
    Compiler is free software: you can redistribute it and/or modify
-
 
7
    it under the terms of the GNU General Public License as published by
-
 
8
    the Free Software Foundation, either version 3 of the License, or
4
    Copyright (c) 2018, 2019, Anton Krotov
9
    (at your option) any later version.
-
 
10
 
-
 
11
    Compiler is distributed in the hope that it will be useful,
-
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-
 
14
    GNU General Public License for more details.
-
 
15
 
-
 
16
    You should have received a copy of the GNU General Public License
-
 
17
    along with Compiler. If not, see .
5
    All rights reserved.
Line 18... Line 6...
18
*)
6
*)
Line 19... Line 7...
19
 
7
 
Line 20... Line -...
20
MODULE X86;
-
 
Line 21... Line 8...
21
 
8
MODULE X86;
Line 22... Line -...
22
IMPORT UTILS, sys := SYSTEM, SCAN, ELF;
-
 
23
 
9
 
Line 24... Line 10...
24
CONST
10
IMPORT CODE, REG, UTILS, LISTS, BIN, PE32, KOS, MSCOFF, ELF, mConst := CONSTANTS, MACHINE, CHL := CHUNKLISTS, PATHS;
25
 
-
 
Line 26... Line -...
26
  ADIM* = 5;
-
 
27
 
-
 
28
  lxPlus = 51; lxMinus = 52; lxMult = 53; lxSlash = 54;
-
 
29
  lxEQ = 71; lxNE = 72; lxLT = 73; lxGT = 74; lxLE = 75; lxGE = 76;
-
 
30
 
-
 
31
  TINTEGER = 1; TREAL = 2; TLONGREAL = 3; TCHAR = 4; TSET = 5; TBOOLEAN = 6; TVOID = 7;
11
 
Line -... Line 12...
-
 
12
 
32
  TNIL = 8; TCARD16 = 9; TSTRING = 10; TARRAY = 11; TRECORD = 12; TPOINTER = 13; TPROC = 14;
13
CONST
Line 33... Line -...
33
 
-
 
34
  stABS* = 1; stODD* = 2; stLEN* = 3; stLSL* = 4; stASR* = 5; stROR* = 6; stFLOOR* = 7;
14
 
Line 35... Line -...
35
  stFLT* = 8; stORD* = 9; stCHR* = 10; stLONG* = 11; stSHORT* = 12; stINC* = 13;
-
 
36
  stDEC* = 14; stINCL* = 15; stEXCL* = 16; stCOPY* = 17; stNEW* = 18; stASSERT* = 19;
15
    eax = REG.R0; ecx = REG.R1; edx = REG.R2;
37
  stPACK* = 20; stUNPK* = 21; stDISPOSE* = 22; stFABS* = 23; stINC1* = 24;
-
 
Line 38... Line -...
38
  stDEC1* = 25; stASSERT1* = 26; stUNPK1* = 27; stPACK1* = 28; stLSR* = 29;
-
 
Line 39... Line -...
39
  stLENGTH* = 30; stMIN* = 31; stMAX* = 32;
-
 
40
 
-
 
41
  sysMOVE* = 108;
-
 
42
 
-
 
43
  JMP* = 0E9X; CALL = 0E8X;
16
 
Line 44... Line -...
44
  JE = 84X; JNE = 85X; JLE = 8EX; JGE = 8DX; JG = 8FX; JL = 8CX;
-
 
Line 45... Line 17...
45
 
17
    al = eax; cl = ecx; dl = edx; ah = 4;
Line -... Line 18...
-
 
18
 
-
 
19
    ax = eax; cx = ecx; dx = edx;
-
 
20
 
46
  JCMD = 1; LCMD = 2; GCMD = 3; OCMD = 4; ECMD = 5;
21
    esp = 4;
-
 
22
    ebp = 5;
47
  PUSHEAX = 6; PUSHECX = 7; PUSHEDX = 8; POPEAX = 9; POPECX = 10; POPEDX = 11;
23
 
-
 
24
    sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H;
48
  ICMP1 = 13; ICMP2 = 14;
25
 
Line -... Line 26...
-
 
26
    je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; jnb = 83H;
-
 
27
 
-
 
28
 
49
 
29
    CODECHUNK = 8;
Line -... Line 30...
-
 
30
 
-
 
31
 
50
  defcall = 0; stdcall = 1; cdecl = 2; winapi = 3;
32
TYPE
Line 51... Line 33...
51
 
33
 
Line 52... Line -...
52
  _rset* = 0; _inset* = 1; _saverec* = 2; _length* = 3; _checktype* = 4; _strcmp* = 5;
-
 
53
  _lstrcmp* = 6; _rstrcmp* = 7; _savearr* = 8; _newrec* = 9; _disprec* = 10; _arrayidx* = 11;
-
 
54
  _arrayrot* = 12; _assrt* = 13; _strcopy* = 14; _arrayidx1* = 15; _init* = 16; _close* = 17; _halt* = 18;
-
 
55
  ASSRT = 19; hInstance = 20; SELFNAME = 21; RTABLE = 22;LoadLibrary = 23; GetProcAddress = 24;
34
    COMMAND = CODE.COMMAND;
Line 56... Line -...
56
  Exports = 25; szSTART = 26; START = 27; szversion = 28; _floor = 29; HALT = 30;
-
 
57
 
-
 
58
  FREGS = 8;
-
 
59
 
35
 
60
TYPE
-
 
61
 
-
 
62
  ASMLINE* = POINTER TO RECORD (UTILS.rITEM)
-
 
63
    cmd, clen, varadr, adr, tcmd, codeadr: INTEGER; short: BOOLEAN
-
 
-
 
36
 
64
  END;
37
    ANYCODE = POINTER TO RECORD (LISTS.ITEM)
65
 
38
 
66
  TFLT = ARRAY 2 OF INTEGER;
-
 
67
 
-
 
68
  TIDX* = ARRAY ADIM OF INTEGER;
-
 
-
 
39
        offset: INTEGER
69
 
40
 
Line 70... Line 41...
70
  SECTIONNAME = ARRAY 8 OF CHAR;
41
    END;
71
 
-
 
72
  SECTION = RECORD
-
 
73
    name: SECTIONNAME;
-
 
74
    size, adr, sizealign, OAPfile, reserved6, reserved7, reserved8, attrflags: INTEGER
-
 
75
  END;
-
 
76
 
-
 
77
  HEADER = RECORD
-
 
78
    msdos: ARRAY 180 OF CHAR;
-
 
-
 
42
 
79
    typecomp, seccount: sys.CARD16;
43
    TCODE = POINTER TO RECORD (ANYCODE)
Line 80... Line 44...
80
    time, reserved1, reserved2: INTEGER;
44
 
-
 
45
        code:    ARRAY CODECHUNK OF BYTE;
81
    PEoptsize, infflags, PEfile, compver: sys.CARD16;
46
        length:  INTEGER
82
    codesize, datasize, initdatasize, startadr,
-
 
-
 
47
 
83
    codeadr, rdataadr, loadadr, secalign, filealign,
48
    END;
Line 84... Line 49...
84
    oldestver, version, oldestverNT, reserved3,
49
 
85
    filesize, headersize, dllcrc: INTEGER;
-
 
86
    UI, reserved4: sys.CARD16;
-
 
87
    stksize, stkalloc, heapsize, heapalloc, reserved5, structcount: INTEGER;
-
 
88
    structs: ARRAY 16 OF RECORD adr, size: INTEGER END;
-
 
89
    sections: ARRAY 3 OF SECTION
-
 
90
  END;
-
 
-
 
50
    LABEL = POINTER TO RECORD (ANYCODE)
91
 
51
 
Line 92... Line 52...
92
  COFFHEADER = RECORD
52
        label: INTEGER
-
 
53
 
93
    Machine: sys.CARD16;
54
    END;
94
    NumberOfSections: sys.CARD16;
-
 
-
 
55
 
95
    TimeDateStamp,
56
    JUMP = POINTER TO RECORD (ANYCODE)
Line 96... Line -...
96
    PointerToSymbolTable,
-
 
97
    NumberOfSymbols: INTEGER;
-
 
98
    SizeOfOptionalHeader,
-
 
99
    Characteristics: sys.CARD16;
-
 
100
    text, data, bss: SECTION
-
 
101
  END;
-
 
102
 
-
 
103
  KOSHEADER = RECORD
-
 
104
    menuet01: ARRAY 8 OF CHAR;
-
 
105
    ver, start, size, mem, sp, param, path: INTEGER
-
 
Line -... Line 57...
-
 
57
 
-
 
58
        label, diff: INTEGER;
-
 
59
        short: BOOLEAN
-
 
60
 
-
 
61
    END;
-
 
62
 
-
 
63
    JMP = POINTER TO RECORD (JUMP)
-
 
64
 
-
 
65
    END;
-
 
66
 
-
 
67
    JCC = POINTER TO RECORD (JUMP)
-
 
68
 
-
 
69
        jmp: INTEGER
-
 
70
 
106
  END;
71
    END;
-
 
72
 
-
 
73
    CALL = POINTER TO RECORD (JUMP)
-
 
74
 
-
 
75
    END;
-
 
76
 
-
 
77
    RELOC = POINTER TO RECORD (ANYCODE)
-
 
78
 
-
 
79
        op, value: INTEGER
-
 
80
 
107
 
81
    END;
-
 
82
 
-
 
83
 
-
 
84
VAR
-
 
85
 
-
 
86
    R: REG.REGS;
-
 
87
 
-
 
88
    program: BIN.PROGRAM;
-
 
89
 
-
 
90
    CodeList: LISTS.LIST;
108
  ETABLE = RECORD
91
 
-
 
92
 
-
 
93
PROCEDURE Byte (n: INTEGER): BYTE;
-
 
94
    RETURN MACHINE.Byte(n, 0)
109
    reserved1, time, reserved2, dllnameoffset, firstnum, adrcount,
95
END Byte;
-
 
96
 
Line 110... Line 97...
110
    namecount, arradroffset, arrnameptroffset, arrnumoffset: INTEGER;
97
 
111
    arradr, arrnameptr: ARRAY 10000H OF INTEGER;
98
PROCEDURE Word (n: INTEGER): INTEGER;
-
 
99
    RETURN MACHINE.Byte(n, 0) + MACHINE.Byte(n, 1) * 256
-
 
100
END Word;
112
    arrnum: ARRAY 10000H OF sys.CARD16;
101
 
-
 
102
 
113
    text: ARRAY 1000000 OF CHAR;
103
PROCEDURE OutByte* (n: BYTE);
Line -... Line 104...
-
 
104
VAR
114
    textlen, size: INTEGER
105
    c: TCODE;
115
  END;
-
 
116
 
106
    last: ANYCODE;
117
  RELOC = RECORD
107
 
118
    Page, Size: INTEGER;
108
BEGIN
119
    reloc: ARRAY 1024 OF sys.CARD16
109
    last := CodeList.last(ANYCODE);
-
 
110
 
Line 120... Line 111...
120
  END;
111
    IF (last IS TCODE) & (last(TCODE).length < CODECHUNK) THEN
121
 
112
        c := last(TCODE);
122
VAR asmlist: UTILS.LIST; start: ASMLINE; dll, con, gui, kos, elf, obj, kem: BOOLEAN;
-
 
123
    Lcount, reccount, topstk: INTEGER; recarray: ARRAY 2048 OF INTEGER; current*: ASMLINE;
-
 
124
    callstk: ARRAY 1024, 2 OF ASMLINE; OutFile: UTILS.STRING;
113
        c.code[c.length] := n;
125
    Code: ARRAY 4000000 OF CHAR; ccount: INTEGER; Data: ARRAY 1000000 OF CHAR; dcount: INTEGER;
-
 
126
    Labels: ARRAY 200000 OF INTEGER; rdata: ARRAY 400H OF INTEGER; Header: HEADER; etable: ETABLE;
-
 
127
    ExecName: UTILS.STRING; LoadAdr: INTEGER; Reloc: ARRAY 200000 OF CHAR; rcount: INTEGER;
-
 
128
    RtlProc: ARRAY 20 OF INTEGER; OutFilePos: INTEGER; RelocSection: SECTION;
-
 
129
    fpu*: INTEGER; isfpu: BOOLEAN; maxfpu: INTEGER; fpucmd: ASMLINE;
-
 
130
    kosexp: ARRAY 65536 OF RECORD Name: SCAN.NODE; Adr, NameLabel: INTEGER END; kosexpcount: INTEGER;
-
 
131
    maxstrlen*: INTEGER;
-
 
132
 
-
 
133
PROCEDURE set_maxstrlen* (value: INTEGER);
-
 
134
BEGIN
-
 
135
    maxstrlen := value
-
 
136
END set_maxstrlen;
-
 
137
 
-
 
138
PROCEDURE AddRtlProc*(idx, proc: INTEGER);
-
 
139
BEGIN
-
 
140
  RtlProc[idx] := proc
-
 
141
END AddRtlProc;
-
 
142
 
-
 
143
PROCEDURE IntToCard16(i: INTEGER): sys.CARD16;
-
 
144
VAR w: sys.CARD16;
-
 
145
BEGIN
-
 
146
  sys.GET(sys.ADR(i), w)
-
 
147
  RETURN w
-
 
148
END IntToCard16;
-
 
149
 
-
 
150
PROCEDURE CopyStr(VAR Dest: ARRAY OF CHAR; Source: ARRAY OF CHAR; VAR di: INTEGER; si: INTEGER);
-
 
151
BEGIN
-
 
152
  DEC(di);
-
 
153
  REPEAT
-
 
154
    INC(di);
-
 
155
    Dest[di] := Source[si];
-
 
156
    INC(si)
-
 
157
  UNTIL Dest[di] = 0X
114
        INC(c.length)
158
END CopyStr;
-
 
159
 
-
 
160
PROCEDURE exch(VAR a, b: INTEGER);
115
    ELSE
161
VAR c: INTEGER;
-
 
162
BEGIN
-
 
163
  c := a;
-
 
164
  a := b;
-
 
165
  b := c
-
 
166
END exch;
-
 
167
 
-
 
168
PROCEDURE Sort(VAR NamePtr, Adr: ARRAY OF INTEGER; Text: ARRAY OF CHAR; LB, RB: INTEGER);
-
 
169
VAR L, R: INTEGER;
-
 
170
 
-
 
171
  PROCEDURE strle(s1, s2: INTEGER): BOOLEAN;
-
 
172
  VAR S1, S2: ARRAY 256 OF CHAR; i: INTEGER;
-
 
173
  BEGIN
-
 
174
    i := 0;
116
        NEW(c);
175
    CopyStr(S1, Text, i, s1);
-
 
176
    i := 0;
-
 
177
    CopyStr(S2, Text, i, s2)
-
 
178
    RETURN S1 <= S2
-
 
179
  END strle;
-
 
180
 
-
 
181
BEGIN
-
 
182
  IF LB < RB THEN
-
 
183
    L := LB;
-
 
184
    R := RB;
-
 
185
    REPEAT
-
 
186
      WHILE (L < RB) & strle(NamePtr[L], NamePtr[LB]) DO
-
 
187
        INC(L)
-
 
188
      END;
-
 
189
      WHILE (R > LB) & strle(NamePtr[LB], NamePtr[R]) DO
-
 
190
        DEC(R)
-
 
191
      END;
-
 
192
      IF L < R THEN
-
 
193
        exch(NamePtr[L], NamePtr[R]);
-
 
194
        exch(Adr[L], Adr[R])
-
 
195
      END
117
        c.code[0] := n;
196
    UNTIL L >= R;
-
 
197
    IF R > LB THEN
-
 
198
      exch(NamePtr[LB], NamePtr[R]);
-
 
199
      exch(Adr[LB], Adr[R]);
-
 
200
      Sort(NamePtr, Adr, Text, LB, R - 1)
-
 
201
    END;
-
 
202
    Sort(NamePtr, Adr, Text, R + 1, RB)
-
 
203
  END
-
 
204
END Sort;
-
 
205
 
-
 
206
PROCEDURE PackExport(Name: ARRAY OF CHAR);
-
 
207
VAR i: INTEGER;
-
 
208
BEGIN
-
 
209
  Sort(etable.arrnameptr, etable.arradr, etable.text, 0, etable.namecount - 1);
-
 
210
  FOR i := 0 TO etable.namecount - 1 DO
-
 
211
    etable.arrnum[i] := IntToCard16(i)
-
 
Line 212... Line 118...
212
  END;
118
        c.length  := 1;
213
  etable.size := 40 + etable.adrcount * 4 + etable.namecount * 6;
119
        LISTS.push(CodeList, c)
-
 
120
    END
-
 
121
 
214
  etable.arradroffset := 40;
122
END OutByte;
-
 
123
 
-
 
124
 
-
 
125
PROCEDURE OutInt (n: INTEGER);
215
  etable.arrnameptroffset := 40 + etable.adrcount * 4;
126
BEGIN
-
 
127
    OutByte(MACHINE.Byte(n, 0));
-
 
128
    OutByte(MACHINE.Byte(n, 1));
-
 
129
    OutByte(MACHINE.Byte(n, 2));
-
 
130
    OutByte(MACHINE.Byte(n, 3))
-
 
131
END OutInt;
-
 
132
 
-
 
133
 
-
 
134
PROCEDURE OutByte2 (a, b: BYTE);
-
 
135
BEGIN
216
  etable.arrnumoffset := etable.arrnameptroffset + etable.namecount * 4;
136
    OutByte(a);
-
 
137
    OutByte(b)
-
 
138
END OutByte2;
-
 
139
 
-
 
140
 
-
 
141
PROCEDURE OutByte3 (a, b, c: BYTE);
-
 
142
BEGIN
-
 
143
    OutByte(a);
217
  etable.dllnameoffset := etable.size + etable.textlen;
144
    OutByte(b);
218
  CopyStr(etable.text, Name, etable.textlen, 0);
-
 
219
  INC(etable.textlen);
-
 
220
  FOR i := 0 TO etable.namecount - 1 DO
-
 
221
    etable.arrnameptr[i] := etable.arrnameptr[i] + etable.size
-
 
222
  END;
-
 
223
  etable.size := etable.size + etable.textlen
-
 
224
END PackExport;
-
 
225
 
-
 
226
PROCEDURE ProcExport*(Number: INTEGER; Name: SCAN.NODE; NameLabel: INTEGER);
-
 
227
BEGIN
-
 
228
  IF dll THEN
-
 
229
    etable.arradr[etable.adrcount] := Number;
-
 
230
    INC(etable.adrcount);
-
 
231
    etable.arrnameptr[etable.namecount] := etable.textlen;
-
 
232
    INC(etable.namecount);
-
 
233
    CopyStr(etable.text, Name.Name, etable.textlen, 0);
-
 
234
    INC(etable.textlen)
-
 
235
  ELSIF obj THEN
-
 
236
    kosexp[kosexpcount].Name := Name;
145
    OutByte(c)
237
    kosexp[kosexpcount].Adr := Number;
146
END OutByte3;
238
    kosexp[kosexpcount].NameLabel := NameLabel;
147
 
239
    INC(kosexpcount)
-
 
240
  END
-
 
241
END ProcExport;
-
 
242
 
-
 
243
PROCEDURE Err(code: INTEGER);
-
 
244
BEGIN
-
 
245
  CASE code OF
-
 
246
  |1: UTILS.ErrMsg(67); UTILS.OutString(OutFile)
-
 
247
  |2: UTILS.ErrMsg(69); UTILS.OutString(OutFile)
-
 
248
  ELSE
-
 
249
  END;
-
 
250
  UTILS.Ln;
-
 
251
  UTILS.HALT(1)
-
 
252
END Err;
-
 
253
 
-
 
254
PROCEDURE Align*(n, m: INTEGER): INTEGER;
-
 
255
  RETURN n + (m - n MOD m) MOD m
-
 
256
END Align;
-
 
257
 
-
 
258
PROCEDURE PutReloc(R: RELOC);
-
 
259
VAR i: INTEGER;
-
 
260
BEGIN
-
 
261
  sys.PUT(sys.ADR(Reloc[rcount]), R.Page);
-
 
262
  INC(rcount, 4);
-
 
263
  sys.PUT(sys.ADR(Reloc[rcount]), R.Size);
-
 
264
  INC(rcount, 4);
-
 
265
  FOR i := 0 TO ASR(R.Size - 8, 1) - 1 DO
-
 
266
    sys.PUT(sys.ADR(Reloc[rcount]), R.reloc[i]);
-
 
267
    INC(rcount, 2)
-
 
268
  END
-
 
269
END PutReloc;
-
 
270
 
-
 
271
PROCEDURE InitArray(VAR adr: INTEGER; chars: UTILS.STRING);
-
 
272
VAR i, x, n: INTEGER;
-
 
273
BEGIN
-
 
274
  n := LEN(chars) - 1;
-
 
275
  i := 0;
-
 
276
  WHILE (i < n) & (chars[i] # 0X) DO
-
 
277
    x := SCAN.hex(chars[i]) * 16 + SCAN.hex(chars[i + 1]);
-
 
278
    sys.PUT(adr, CHR(x));
-
 
279
    INC(adr);
-
 
280
    INC(i, 2)
-
 
281
  END
-
 
282
END InitArray;
-
 
283
 
-
 
284
PROCEDURE WriteF(F, A, N: INTEGER);
-
 
285
BEGIN
-
 
286
  IF UTILS.Write(F, A, N) # N THEN
-
 
287
    Err(2)
-
 
288
  END
-
 
289
END WriteF;
-
 
290
 
-
 
291
PROCEDURE Write(A, N: INTEGER);
-
 
292
BEGIN
-
 
293
  sys.MOVE(A, OutFilePos, N);
-
 
294
  OutFilePos := OutFilePos + N
-
 
295
END Write;
-
 
296
 
-
 
297
PROCEDURE Fill(n: INTEGER; c: CHAR);
-
 
298
VAR i: INTEGER;
-
 
299
BEGIN
-
 
300
  FOR i := 1 TO n DO
-
 
301
    Write(sys.ADR(c), 1)
-
 
302
  END
-
 
303
END Fill;
-
 
304
 
-
 
305
PROCEDURE SetSection(VAR Section: SECTION; name: SECTIONNAME; size, adr, sizealign, OAPfile, attrflags: INTEGER);
-
 
306
BEGIN
-
 
307
  Section.name := name;
-
 
308
  Section.size := size;
-
 
309
  Section.adr := adr;
-
 
310
  Section.sizealign := sizealign;
-
 
311
  Section.OAPfile := OAPfile;
148
 
312
  Section.attrflags := attrflags;
-
 
313
END SetSection;
-
 
314
 
-
 
315
PROCEDURE WritePE(FName: ARRAY OF CHAR; stksize, codesize, datasize, rdatasize, gsize: INTEGER);
-
 
316
CONST textattr = 60000020H; rdataattr = 40000040H; dataattr = 0C0000040H; relocattr = 42000040H;
-
 
317
VAR i, F, adr, acodesize, compver, version, stkalloc, heapsize, heapalloc, filesize, filebuf: INTEGER;
-
 
318
    cur: ASMLINE;
-
 
319
BEGIN
-
 
320
 
-
 
321
  compver := 0;
-
 
322
  version := 0;
-
 
323
  stkalloc := stksize;
-
 
324
  heapsize := 100000H;
-
 
325
  heapalloc := 100000H;
-
 
326
  acodesize := Align(codesize, 1000H) + 1000H;
-
 
327
  adr := sys.ADR(rdata);
-
 
328
  filesize := acodesize + Align(rdatasize, 1000H) + Align(datasize, 1000H) + Align(rcount, 1000H);
-
 
329
 
-
 
330
  InitArray(adr, "5000000040000000000000003400000000000000000000006200000000000000");
-
 
331
  InitArray(adr, "0000000000000000000000000000000000000000500000004000000000000000");
-
 
332
  InitArray(adr, "A4014C6F61644C6962726172794100001F0147657450726F6341646472657373");
-
 
333
  InitArray(adr, "00006B65726E656C33322E646C6C0000");
-
 
334
 
-
 
335
  rdata[ 0] := acodesize + 50H;
-
 
336
  rdata[ 1] := acodesize + 40H;
-
 
337
  rdata[ 3] := acodesize + 34H;
-
 
338
  rdata[ 6] := acodesize + 62H;
-
 
339
  rdata[ 7] := acodesize;
-
 
340
  rdata[13] := acodesize + 50H;
-
 
341
  rdata[14] := acodesize + 40H;
-
 
342
 
-
 
343
  adr := sys.ADR(Header.msdos);
-
 
344
  InitArray(adr, "4D5A90000300000004000000FFFF0000B8000000000000004000000000000000");
-
 
345
  InitArray(adr, "00000000000000000000000000000000000000000000000000000000B0000000");
-
 
346
  InitArray(adr, "0E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F");
-
 
347
  InitArray(adr, "742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000");
-
 
348
  InitArray(adr, "5DCF9F8719AEF1D419AEF1D419AEF1D497B1E2D413AEF1D4E58EE3D418AEF1D4");
-
 
349
  InitArray(adr, "5269636819AEF1D4000000000000000050450000");
-
 
350
  Header.typecomp := IntToCard16(014CH);
-
 
351
  IF dll THEN
-
 
352
    Header.seccount := IntToCard16(0004H);
-
 
353
    Header.infflags := IntToCard16(210EH)
-
 
354
  ELSE
-
 
355
    Header.seccount := IntToCard16(0003H);
-
 
356
    Header.infflags := IntToCard16(010FH)
-
 
357
  END;
-
 
358
  Header.time := UTILS.Date;
-
 
359
  Header.PEoptsize := IntToCard16(00E0H);
-
 
360
  Header.PEfile := IntToCard16(010BH);
-
 
361
  Header.compver := IntToCard16(compver);
-
 
362
  Header.codesize := Align(codesize, 200H);
-
 
363
  Header.datasize := Align(datasize + gsize, 200H) + Align(rdatasize, 200H) + Align(rcount, 200H);
-
 
364
  Header.startadr := 1000H;
-
 
365
  Header.codeadr := 1000H;
-
 
366
  Header.rdataadr := Header.codeadr + Align(codesize, 1000H);
-
 
367
  Header.loadadr := LoadAdr;
-
 
368
  Header.secalign := 1000H;
-
 
369
  Header.filealign := 0200H;
-
 
370
  Header.oldestver := 0004H;
-
 
371
  Header.version := version;
-
 
372
  Header.oldestverNT := 0004H;
-
 
373
  Header.filesize := Align(codesize, 1000H) + Align(datasize + gsize, 1000H) + Align(rdatasize, 1000H) + Align(rcount, 1000H) + 1000H;
-
 
374
  Header.headersize := 0400H;
-
 
375
  Header.UI := IntToCard16(ORD(con) + 2);
-
 
376
  Header.stksize := stksize;
-
 
377
  Header.stkalloc := stkalloc;
-
 
378
  Header.heapsize := heapsize;
-
 
379
  Header.heapalloc := heapalloc;
-
 
380
  Header.structcount := 10H;
-
 
381
  IF dll THEN
-
 
382
    Header.structs[0].adr := Header.rdataadr + 0DAH;
-
 
383
    Header.structs[0].size := etable.size
-
 
384
  END;
-
 
385
 
-
 
386
  Header.structs[1].adr := Header.rdataadr + 0CH;
-
 
387
  Header.structs[1].size := 28H;
-
 
388
  Header.structs[12].adr := Header.rdataadr;
-
 
389
  Header.structs[12].size := 0CH;
-
 
390
 
-
 
391
  SetSection(Header.sections[0], ".text", codesize, 1000H, Align(codesize, 200H), 400H, textattr);
-
 
392
  SetSection(Header.sections[1], ".rdata", rdatasize, Align(codesize, 1000H) + 1000H, Align(rdatasize, 200H),
-
 
393
    Align(codesize, 200H) + 400H, rdataattr);
-
 
394
  SetSection(Header.sections[2], ".data", datasize + gsize, Align(codesize, 1000H) + Align(rdatasize, 1000H) + 1000H,
-
 
395
    Align(datasize, 200H), Align(codesize, 200H) + Align(rdatasize, 200H) + 400H, dataattr);
-
 
396
 
-
 
397
  IF dll THEN
-
 
398
    SetSection(RelocSection, ".reloc", rcount, Header.sections[2].adr + Align(datasize + gsize, 1000H), Align(rcount, 200H),
-
 
399
      Header.sections[2].OAPfile + Align(datasize, 200H), relocattr);
-
 
400
    Header.structs[5].adr := RelocSection.adr;
-
 
401
    Header.structs[5].size := rcount
-
 
402
  END;
-
 
403
 
-
 
404
  F := UTILS.CreateF(FName);
-
 
405
  IF F = 0 THEN
-
 
406
    Err(1)
-
 
407
  END;
-
 
408
  OutFilePos := UTILS.GetMem(filesize);
-
 
409
  filebuf := OutFilePos;
-
 
410
  UTILS.MemErr(OutFilePos = 0);
-
 
411
 
-
 
412
  Write(sys.ADR(Header), sys.SIZE(HEADER));
-
 
413
  IF dll THEN
-
 
414
    Write(sys.ADR(RelocSection), sys.SIZE(SECTION));
-
 
415
    Fill(Align(sys.SIZE(HEADER) + sys.SIZE(SECTION), 200H) - (sys.SIZE(HEADER) + sys.SIZE(SECTION)), 0X)
-
 
416
  ELSE
-
 
417
    Fill(Align(sys.SIZE(HEADER), 200H) - sys.SIZE(HEADER), 0X)
-
 
418
  END;
-
 
419
 
-
 
420
  cur := asmlist.First(ASMLINE);
-
 
421
  WHILE cur # NIL DO
-
 
422
    Write(sys.ADR(Code[cur.cmd]), cur.clen);
-
 
423
    cur := cur.Next(ASMLINE)
-
 
424
  END;
-
 
425
  Fill(Align(codesize, 200H) - codesize, 0X);
-
 
426
  Write(sys.ADR(rdata), 0DAH);
-
 
427
  IF dll THEN
-
 
428
    etable.time := Header.time;
-
 
429
    Write(sys.ADR(etable), 40);
-
 
430
    Write(sys.ADR(etable.arradr), etable.adrcount * 4);
-
 
431
    Write(sys.ADR(etable.arrnameptr), etable.namecount * 4);
-
 
432
    Write(sys.ADR(etable.arrnum), etable.namecount * 2);
-
 
433
    Write(sys.ADR(etable.text), etable.textlen)
-
 
434
  END;
-
 
435
  Fill(Align(rdatasize, 200H) - rdatasize, 0X);
-
 
436
  Write(sys.ADR(Data), datasize);
-
 
437
  Fill(Align(datasize, 200H) - datasize, 0X);
-
 
438
  IF dll THEN
-
 
439
    Write(sys.ADR(Reloc), rcount);
-
 
Line 440... Line 149...
440
    Fill(Align(rcount, 200H) - rcount, 0X)
149
PROCEDURE OutWord (n: INTEGER);
441
  END;
150
BEGIN
-
 
151
    ASSERT((0 <= n) & (n <= 65535));
-
 
152
    OutByte2(n MOD 256, n DIV 256)
-
 
153
END OutWord;
-
 
154
 
-
 
155
 
442
  WriteF(F, filebuf, OutFilePos - filebuf);
156
PROCEDURE isByte (n: INTEGER): BOOLEAN;
443
  UTILS.CloseF(F)
157
    RETURN (-128 <= n) & (n <= 127)
-
 
158
END isByte;
-
 
159
 
444
END WritePE;
160
 
445
 
161
PROCEDURE short (n: INTEGER): INTEGER;
-
 
162
    RETURN 2 * ORD(isByte(n))
446
PROCEDURE New;
163
END short;
-
 
164
 
Line -... Line 165...
-
 
165
 
-
 
166
PROCEDURE long (n: INTEGER): INTEGER;
-
 
167
    RETURN 40H * ORD(~isByte(n))
-
 
168
END long;
-
 
169
 
-
 
170
 
-
 
171
PROCEDURE OutIntByte (n: INTEGER);
-
 
172
BEGIN
-
 
173
    IF isByte(n) THEN
-
 
174
        OutByte(Byte(n))
-
 
175
    ELSE
-
 
176
        OutInt(n)
-
 
177
    END
-
 
178
END OutIntByte;
-
 
179
 
-
 
180
 
447
VAR nov: ASMLINE;
181
PROCEDURE shift* (op, reg: INTEGER);
448
BEGIN
182
BEGIN
449
  NEW(nov);
183
    CASE op OF
450
  UTILS.MemErr(nov = NIL);
-
 
451
  nov.cmd := ccount;
184
    |CODE.opASR, CODE.opASR1, CODE.opASR2: OutByte(0F8H + reg)
-
 
185
    |CODE.opROR, CODE.opROR1, CODE.opROR2: OutByte(0C8H + reg)
Line 452... Line 186...
452
  UTILS.Insert(asmlist, nov, current);
186
    |CODE.opLSL, CODE.opLSL1, CODE.opLSL2: OutByte(0E0H + reg)
453
  current := current.Next(ASMLINE)
187
    |CODE.opLSR, CODE.opLSR1, CODE.opLSR2: OutByte(0E8H + reg)
454
END New;
188
    END
455
 
-
 
456
PROCEDURE Empty(varadr: INTEGER);
189
END shift;
Line -... Line 190...
-
 
190
 
457
BEGIN
191
 
458
  New;
192
PROCEDURE mov (reg1, reg2: INTEGER);
459
  current.clen := 0;
193
BEGIN
460
  current.tcmd := ECMD;
194
    OutByte2(89H, 0C0H + reg2 * 8 + reg1)  // mov reg1, reg2
461
  current.varadr := varadr
195
END mov;
-
 
196
 
Line 462... Line 197...
462
END Empty;
197
 
463
 
198
PROCEDURE xchg (reg1, reg2: INTEGER);
464
PROCEDURE OutByte(byte: INTEGER);
199
VAR
465
BEGIN
200
    regs: SET;
466
  New;
201
 
Line -... Line 202...
-
 
202
BEGIN
467
  current.clen := 1;
203
    regs := {reg1, reg2};
468
  Code[ccount] := CHR(byte);
204
    IF regs = {eax, ecx} THEN
469
  INC(ccount)
205
        OutByte(91H)                // xchg eax, ecx
470
END OutByte;
-
 
471
 
206
    ELSIF regs = {eax, edx} THEN
-
 
207
        OutByte(92H)                // xchg eax, edx
Line 472... Line 208...
472
PROCEDURE OutInt(int: INTEGER);
208
    ELSIF regs = {ecx, edx} THEN
473
BEGIN
209
        OutByte2(87H, 0D1H)         // xchg ecx, edx
474
  New;
210
    END
475
  current.clen := 4;
-
 
476
  sys.PUT(sys.ADR(Code[ccount]), int);
211
END xchg;
-
 
212
 
Line 477... Line 213...
477
  INC(ccount, 4)
213
 
478
END OutInt;
-
 
479
 
214
PROCEDURE pop (reg: INTEGER);
480
PROCEDURE PushEAX;
-
 
481
BEGIN
-
 
482
  OutByte(50H);
-
 
483
  current.tcmd := PUSHEAX
-
 
484
END PushEAX;
215
BEGIN
485
 
-
 
486
PROCEDURE PushECX;
216
    OutByte(58H + reg) // pop reg
Line -... Line 217...
-
 
217
END pop;
487
BEGIN
218
 
488
  OutByte(51H);
219
 
489
  current.tcmd := PUSHECX
-
 
490
END PushECX;
220
PROCEDURE push (reg: INTEGER);
491
 
-
 
492
PROCEDURE PushEDX;
-
 
493
BEGIN
-
 
494
  OutByte(52H);
221
BEGIN
-
 
222
    OutByte(50H + reg) // push reg
Line 495... Line 223...
495
  current.tcmd := PUSHEDX
223
END push;
496
END PushEDX;
224
 
497
 
225
 
498
PROCEDURE PopEAX;
226
PROCEDURE movrc (reg, n: INTEGER);
499
BEGIN
227
BEGIN
-
 
228
    OutByte(0B8H + reg); // mov reg, n
Line 500... Line 229...
500
  OutByte(58H);
229
    OutInt(n)
501
  current.tcmd := POPEAX
230
END movrc;
502
END PopEAX;
-
 
503
 
-
 
504
PROCEDURE PopECX;
-
 
505
BEGIN
-
 
506
  OutByte(59H);
-
 
507
  current.tcmd := POPECX
-
 
508
END PopECX;
-
 
509
 
-
 
510
PROCEDURE PopEDX;
-
 
511
BEGIN
-
 
512
  OutByte(5AH);
-
 
513
  current.tcmd := POPEDX
-
 
514
END PopEDX;
-
 
515
 
-
 
516
PROCEDURE OutCode(cmd: UTILS.STRING);
-
 
517
VAR a, b: INTEGER;
-
 
518
BEGIN
-
 
519
  New;
-
 
520
  a := sys.ADR(Code[ccount]);
-
 
521
  b := a;
-
 
522
  InitArray(a, cmd);
-
 
523
  ccount := a - b + ccount;
-
 
524
  current.clen := a - b
-
 
525
END OutCode;
-
 
526
 
-
 
527
PROCEDURE Del*(last: ASMLINE);
-
 
528
BEGIN
-
 
529
  last.Next := current.Next;
-
 
530
  IF current = asmlist.Last THEN
-
 
531
    asmlist.Last := last
-
 
532
  END;
-
 
533
  current := last
-
 
534
END Del;
-
 
535
 
-
 
536
PROCEDURE NewLabel*(): INTEGER;
-
 
537
BEGIN
-
 
538
  INC(Lcount)
-
 
539
  RETURN Lcount
-
 
540
END NewLabel;
-
 
541
 
-
 
542
PROCEDURE PushCall*(asmline: ASMLINE);
231
 
543
BEGIN
-
 
544
  New;
-
 
545
  callstk[topstk][0] := asmline;
232
 
546
  callstk[topstk][1] := current;
-
 
547
  INC(topstk)
-
 
548
END PushCall;
-
 
549
 
-
 
550
PROCEDURE Param*;
-
 
551
BEGIN
-
 
552
  current := callstk[topstk - 1][0]
-
 
553
END Param;
-
 
554
 
-
 
555
PROCEDURE EndCall*;
-
 
556
BEGIN
-
 
557
  current := callstk[topstk - 1][1];
-
 
558
  DEC(topstk)
-
 
559
END EndCall;
-
 
560
 
-
 
561
PROCEDURE Init*(UI: INTEGER);
-
 
562
VAR nov: ASMLINE;
-
 
563
BEGIN
-
 
564
  dcount := 4;
-
 
565
  dll := UI = 1;
-
 
566
  gui := UI = 2;
-
 
567
  con := UI = 3;
-
 
568
  kos := UI = 4;
-
 
569
  elf := UI = 5;
-
 
570
  obj := UI = 6;
-
 
571
  Lcount := HALT;
-
 
572
  asmlist := UTILS.CreateList();
-
 
573
  NEW(nov);
-
 
574
  UTILS.MemErr(nov = NIL);
-
 
575
  UTILS.Push(asmlist, nov);
-
 
576
  current := nov
-
 
577
END Init;
-
 
578
 
233
PROCEDURE pushc (n: INTEGER);
Line -... Line 234...
-
 
234
BEGIN
579
PROCEDURE datastr(str: UTILS.STRING);
235
    OutByte(68H + short(n)); // push n
580
VAR i, n: INTEGER;
236
    OutIntByte(n)
581
BEGIN
237
END pushc;
582
  i := 0;
238
 
583
  n := LEN(str);
239
 
-
 
240
PROCEDURE test (reg: INTEGER);
Line 584... Line 241...
584
  WHILE (i < n) & (str[i] # 0X) DO
241
BEGIN
585
    Data[dcount] := str[i];
242
    OutByte2(85H, 0C0H + reg * 9)  // test reg, reg
586
    INC(dcount);
-
 
587
    INC(i)
243
END test;
588
  END;
244
 
589
  Data[dcount] := 0X;
245
 
-
 
246
PROCEDURE neg (reg: INTEGER);
Line 590... Line 247...
590
  INC(dcount)
247
BEGIN
591
END datastr;
248
    OutByte2(0F7H, 0D8H + reg)  // neg reg
592
 
-
 
593
PROCEDURE dataint(n: INTEGER);
-
 
594
BEGIN
-
 
595
  sys.PUT(sys.ADR(Data[dcount]), n);
249
END neg;
596
  INC(dcount, 4)
-
 
597
END dataint;
-
 
598
 
250
 
Line -... Line 251...
-
 
251
 
599
PROCEDURE jmp*(jamp: CHAR; label: INTEGER);
252
PROCEDURE not (reg: INTEGER);
600
VAR n: INTEGER;
253
BEGIN
601
BEGIN
254
    OutByte2(0F7H, 0D0H + reg)  // not reg
602
  New;
-
 
603
  CASE jamp OF
255
END not;
604
  |JMP, CALL:
-
 
605
    n := 5
-
 
606
  |JE, JLE, JGE, JG, JL, JNE:
256
 
607
    Code[ccount] := 0FX;
257
 
608
    INC(ccount);
-
 
Line 609... Line 258...
609
    n := 6
258
PROCEDURE add (reg1, reg2: INTEGER);
610
  ELSE
259
BEGIN
611
  END;
-
 
612
  current.clen := n;
260
    OutByte2(01H, 0C0H + reg2 * 8 + reg1)  // add reg1, reg2
613
  Code[ccount] := jamp;
261
END add;
614
  INC(ccount);
-
 
615
  current.codeadr := sys.ADR(Code[ccount]);
262
 
616
  current.varadr := sys.ADR(Labels[label]);
-
 
617
  current.tcmd := JCMD;
-
 
Line 618... Line 263...
618
  current.short := TRUE;
263
 
619
  INC(ccount, 4)
264
PROCEDURE andrc (reg, n: INTEGER);
-
 
265
BEGIN
-
 
266
    OutByte2(81H + short(n), 0E0H + reg);  // and reg, n
-
 
267
    OutIntByte(n)
-
 
268
END andrc;
-
 
269
 
-
 
270
 
-
 
271
PROCEDURE orrc (reg, n: INTEGER);
-
 
272
BEGIN
-
 
273
    OutByte2(81H + short(n), 0C8H + reg);  // or reg, n
-
 
274
    OutIntByte(n)
-
 
275
END orrc;
-
 
276
 
620
END jmp;
277
 
621
 
278
PROCEDURE addrc (reg, n: INTEGER);
622
PROCEDURE jmplong(jamp: CHAR; label: INTEGER);
279
BEGIN
623
BEGIN
280
    OutByte2(81H + short(n), 0C0H + reg);  // add reg, n
624
  jmp(jamp, label);
281
    OutIntByte(n)
625
  current.short := FALSE
282
END addrc;
626
END jmplong;
-
 
627
 
-
 
628
PROCEDURE Label*(label: INTEGER);
283
 
629
BEGIN
284
 
-
 
285
PROCEDURE subrc (reg, n: INTEGER);
-
 
286
BEGIN
-
 
287
    OutByte2(81H + short(n), 0E8H + reg);  // sub reg, n
-
 
288
    OutIntByte(n)
-
 
289
END subrc;
-
 
290
 
-
 
291
 
-
 
292
PROCEDURE cmprr (reg1, reg2: INTEGER);
-
 
293
BEGIN
-
 
294
    OutByte2(39H, 0C0H + reg2 * 8 + reg1)  // cmp reg1, reg2
-
 
295
END cmprr;
-
 
296
 
-
 
297
 
-
 
298
PROCEDURE cmprc (reg, n: INTEGER);
-
 
299
BEGIN
-
 
300
    OutByte2(81H + short(n), 0F8H + reg);  // cmp reg, n
-
 
301
    OutIntByte(n)
630
  New;
302
END cmprc;
631
  current.varadr := sys.ADR(Labels[label]);
-
 
Line 632... Line 303...
632
  current.tcmd := LCMD
303
 
-
 
304
 
-
 
305
PROCEDURE setcc (cond, reg: INTEGER);
-
 
306
BEGIN
633
END Label;
307
    OutByte3(0FH, cond, 0C0H + reg)  // setcc reg
634
 
308
END setcc;
635
PROCEDURE CmdN(Number: INTEGER);
309
 
636
BEGIN
310
 
637
  New;
311
PROCEDURE drop;
638
  current.clen := 4;
312
BEGIN
639
  current.codeadr := sys.ADR(Code[ccount]);
-
 
640
  current.varadr := sys.ADR(Labels[Number]);
313
    REG.Drop(R)
641
  current.tcmd := OCMD;
-
 
Line 642... Line 314...
642
  INC(ccount, 4)
314
END drop;
-
 
315
 
-
 
316
 
-
 
317
PROCEDURE log2* (x: INTEGER): INTEGER;
-
 
318
VAR
-
 
319
    n: INTEGER;
-
 
320
 
-
 
321
BEGIN
643
END CmdN;
322
    ASSERT(x > 0);
-
 
323
 
644
 
324
    n := 0;
645
PROCEDURE IntByte(bytecode, intcode: UTILS.STRING; n: INTEGER);
325
    WHILE ~ODD(x) DO
646
BEGIN
326
        x := x DIV 2;
647
  IF (n <= 127) & (n >= -128) THEN
327
        INC(n)
-
 
328
    END;
-
 
329
 
648
    OutCode(bytecode);
330
    IF x # 1 THEN
649
    OutByte(n)
331
        n := -1
650
  ELSE
332
    END
Line 651... Line -...
651
    OutCode(intcode);
-
 
652
    OutInt(n)
-
 
653
  END
333
 
-
 
334
    RETURN n
-
 
335
END log2;
654
END IntByte;
336
 
-
 
337
 
-
 
338
PROCEDURE cond* (op: INTEGER): INTEGER;
-
 
339
VAR
-
 
340
    res: INTEGER;
-
 
341
 
-
 
342
BEGIN
-
 
343
    CASE op OF
-
 
344
    |CODE.opGT, CODE.opGTR, CODE.opLTL: res := jg
-
 
345
    |CODE.opGE, CODE.opGER, CODE.opLEL: res := jge
-
 
346
    |CODE.opLT, CODE.opLTR, CODE.opGTL: res := jl
-
 
347
    |CODE.opLE, CODE.opLER, CODE.opGEL: res := jle
-
 
348
    |CODE.opEQ, CODE.opEQR, CODE.opEQL: res := je
-
 
349
    |CODE.opNE, CODE.opNER, CODE.opNEL: res := jne
-
 
350
    END
-
 
351
 
-
 
352
    RETURN res
-
 
353
END cond;
-
 
354
 
-
 
355
 
-
 
356
PROCEDURE inv1* (op: INTEGER): INTEGER;
-
 
357
BEGIN
-
 
358
    IF ODD(op) THEN
-
 
359
        DEC(op)
-
 
360
    ELSE
-
 
361
        INC(op)
-
 
362
    END
-
 
363
 
-
 
364
    RETURN op
-
 
365
END inv1;
-
 
366
 
-
 
367
 
655
 
368
PROCEDURE Reloc* (op, value: INTEGER);
-
 
369
VAR
-
 
370
    reloc: RELOC;
-
 
371
 
-
 
372
BEGIN
-
 
373
    NEW(reloc);
-
 
374
    reloc.op := op;
-
 
375
    reloc.value := value;
-
 
376
    LISTS.push(CodeList, reloc)
-
 
377
END Reloc;
-
 
378
 
-
 
379
 
-
 
380
PROCEDURE jcc* (cc, label: INTEGER);
656
PROCEDURE DropFpu*(long: BOOLEAN);
381
VAR
-
 
382
    j: JCC;
-
 
383
 
657
BEGIN
384
BEGIN
-
 
385
    NEW(j);
-
 
386
    j.label := label;
-
 
387
    j.jmp   := cc;
-
 
388
    j.short := FALSE;
-
 
389
    LISTS.push(CodeList, j)
-
 
390
END jcc;
658
  IF long THEN
391
 
-
 
392
 
659
    OutCode("83EC08DD1C24")
393
PROCEDURE jmp* (label: INTEGER);
660
  ELSE
394
VAR
-
 
395
    j: JMP;
-
 
396
 
-
 
397
BEGIN
-
 
398
    NEW(j);
-
 
399
    j.label := label;
-
 
400
    j.short := FALSE;
-
 
401
    LISTS.push(CodeList, j)
-
 
402
END jmp;
-
 
403
 
-
 
404
 
-
 
405
PROCEDURE call* (label: INTEGER);
-
 
406
VAR
-
 
407
    c: CALL;
-
 
408
 
661
    OutCode("83EC04D91C24")
409
BEGIN
-
 
410
    NEW(c);
-
 
411
    c.label := label;
-
 
412
    c.short := TRUE;
-
 
413
    LISTS.push(CodeList, c)
-
 
414
END call;
-
 
415
 
-
 
416
 
-
 
417
PROCEDURE Pic (reg, opcode, value: INTEGER);
Line 662... Line -...
662
  END;
-
 
663
  DEC(fpu)
-
 
664
END DropFpu;
418
BEGIN
-
 
419
    OutByte(0E8H); OutInt(0); // call L
-
 
420
                              // L:
-
 
421
    pop(reg);
-
 
422
    OutByte2(081H, 0C0H + reg);  // add reg, ...
665
 
423
    Reloc(opcode, value)
-
 
424
END Pic;
-
 
425
 
-
 
426
 
-
 
427
PROCEDURE CallRTL (pic: BOOLEAN; proc: INTEGER);
-
 
428
VAR
-
 
429
    label: INTEGER;
-
 
430
    reg1:  INTEGER;
666
PROCEDURE AfterRet(func, float: BOOLEAN; callconv, parsize: INTEGER);
431
 
-
 
432
BEGIN
-
 
433
    label := CODE.codes.rtl[proc];
-
 
434
 
667
BEGIN
435
    IF label < 0 THEN
-
 
436
        label := -label;
-
 
437
        IF pic THEN
-
 
438
            reg1 := REG.GetAnyReg(R);
668
  IF callconv = cdecl THEN
439
            Pic(reg1, BIN.PICIMP, label);
-
 
440
            OutByte2(0FFH, 010H + reg1);  // call dword[reg1]
-
 
441
            drop
-
 
442
        ELSE
-
 
443
            OutByte2(0FFH, 015H);  // call dword[label]
669
    OutCode("81C4");
444
            Reloc(BIN.RIMP, label)
670
    OutInt(parsize)
445
        END
-
 
446
    ELSE
-
 
447
        call(label)
-
 
448
    END
-
 
449
END CallRTL;
671
  END;
450
 
672
  IF func THEN
451
 
673
    IF float THEN
-
 
674
      OutCode("83EC08DD1C24")
-
 
675
    ELSE
-
 
676
      PushEAX
-
 
677
    END
-
 
Line -... Line 452...
-
 
452
PROCEDURE SetLabel* (label: INTEGER);
-
 
453
VAR
-
 
454
    L: LABEL;
-
 
455
 
-
 
456
BEGIN
-
 
457
    NEW(L);
-
 
458
    L.label := label;
-
 
459
    LISTS.push(CodeList, L)
-
 
460
END SetLabel;
-
 
461
 
-
 
462
 
-
 
463
PROCEDURE fixup*;
-
 
464
VAR
-
 
465
    code:      ANYCODE;
-
 
466
    count, i:  INTEGER;
-
 
467
    shorted:   BOOLEAN;
-
 
468
    jump:      JUMP;
-
 
469
 
-
 
470
BEGIN
-
 
471
 
-
 
472
    REPEAT
-
 
473
 
-
 
474
        shorted := FALSE;
-
 
475
        count := 0;
-
 
476
 
-
 
477
        code := CodeList.first(ANYCODE);
-
 
478
        WHILE code # NIL DO
-
 
479
            code.offset := count;
-
 
480
 
-
 
481
            CASE code OF
-
 
482
            |TCODE:  INC(count, code.length)
-
 
483
            |LABEL:  BIN.SetLabel(program, code.label, count)
-
 
484
            |JMP:    IF code.short THEN INC(count, 2) ELSE INC(count, 5) END; code.offset := count
-
 
485
            |JCC:    IF code.short THEN INC(count, 2) ELSE INC(count, 6) END; code.offset := count
-
 
486
            |CALL:   INC(count, 5); code.offset := count
-
 
487
            |RELOC:  INC(count, 4)
-
 
488
            END;
-
 
489
 
-
 
490
            code := code.next(ANYCODE)
-
 
491
        END;
-
 
492
 
-
 
493
        code := CodeList.first(ANYCODE);
-
 
494
        WHILE code # NIL DO
-
 
495
 
-
 
496
            IF code IS JUMP THEN
-
 
497
                jump := code(JUMP);
-
 
498
                jump.diff := BIN.GetLabel(program, jump.label) - code.offset;
-
 
499
                IF ~jump.short & isByte(jump.diff) THEN
-
 
500
                    jump.short := TRUE;
-
 
501
                    shorted := TRUE
-
 
502
                END
-
 
503
            END;
-
 
504
 
678
  END
505
            code := code.next(ANYCODE)
679
END AfterRet;
506
        END
680
 
-
 
681
PROCEDURE FpuSave(local: INTEGER);
-
 
682
VAR i: INTEGER;
-
 
683
BEGIN
-
 
684
  IF fpu > maxfpu THEN
-
 
685
    maxfpu := fpu
-
 
686
  END;
-
 
687
  FOR i := 1 TO fpu DO
507
 
688
    IntByte("DD5D", "DD9D", -local - i * 8)
508
    UNTIL ~shorted;
Line -... Line 509...
-
 
509
 
689
  END
510
    code := CodeList.first(ANYCODE);
690
END FpuSave;
511
    WHILE code # NIL DO
691
 
512
 
692
PROCEDURE Incfpu;
-
 
693
BEGIN
513
        CASE code OF
-
 
514
 
Line 694... Line 515...
694
  IF fpu >= FREGS THEN
515
        |TCODE:
695
    UTILS.ErrMsgPos(SCAN.coord.line, SCAN.coord.col, 97);
516
                FOR i := 0 TO code.length - 1 DO
696
    UTILS.HALT(1)
-
 
697
  END;
-
 
698
  INC(fpu);
-
 
699
  isfpu := TRUE
-
 
700
END Incfpu;
-
 
701
 
-
 
702
PROCEDURE FpuLoad(local: INTEGER; float: BOOLEAN);
-
 
703
VAR i: INTEGER;
-
 
704
BEGIN
517
                    BIN.PutCode(program, code.code[i])
705
  FOR i := fpu TO 1 BY -1 DO
518
                END
706
    IntByte("DD45", "DD85", -local - i * 8)
-
 
707
  END;
-
 
708
  IF float THEN
-
 
709
    Incfpu;
-
 
710
    OutCode("DD042483C408")
519
 
Line -... Line 520...
-
 
520
        |LABEL:
711
  END
521
                BIN.SetLabel(program, code.label, code.offset)
-
 
522
 
-
 
523
        |JMP:
-
 
524
                IF code.short THEN
-
 
525
                    BIN.PutCode(program, 0EBH);
-
 
526
                    BIN.PutCode(program, Byte(code.diff))
-
 
527
                ELSE
-
 
528
                    BIN.PutCode(program, 0E9H);
712
END FpuLoad;
529
                    BIN.PutCode32LE(program, code.diff)
-
 
530
                END
-
 
531
 
-
 
532
        |JCC:
-
 
533
                IF code.short THEN
-
 
534
                    BIN.PutCode(program, code.jmp - 16);
-
 
535
                    BIN.PutCode(program, Byte(code.diff))
713
 
536
                ELSE
-
 
537
                    BIN.PutCode(program, 0FH);
-
 
538
                    BIN.PutCode(program, code.jmp);
-
 
539
                    BIN.PutCode32LE(program, code.diff)
-
 
540
                END
-
 
541
 
714
PROCEDURE Call*(proc: INTEGER; func, float: BOOLEAN; callconv, ccall, bases, level, parsize, local: INTEGER);
542
        |CALL:
-
 
543
                BIN.PutCode(program, 0E8H);
715
VAR i: INTEGER;
544
                BIN.PutCode32LE(program, code.diff)
Line 716... Line -...
716
BEGIN
-
 
717
  IF ccall # 0 THEN
-
 
718
    FOR i := level TO level - bases + ORD(ccall = 1) + 1 BY -1 DO
545
 
719
      IntByte("FF75", "FFB5", 4 * i + 4)
546
        |RELOC:
-
 
547
                BIN.PutReloc(program, code.op);
720
    END;
548
                BIN.PutCode32LE(program, code.value)
-
 
549
 
-
 
550
        END;
-
 
551
 
-
 
552
        code := code.next(ANYCODE)
-
 
553
    END
-
 
554
 
721
    IF ccall = 1 THEN
555
END fixup;
-
 
556
 
-
 
557
 
722
      OutByte(55H)
558
PROCEDURE UnOp (VAR reg: INTEGER);
-
 
559
BEGIN
-
 
560
    REG.UnOp(R, reg)
-
 
561
END UnOp;
-
 
562
 
-
 
563
 
-
 
564
PROCEDURE BinOp (VAR reg1, reg2: INTEGER);
-
 
565
BEGIN
-
 
566
    REG.BinOp(R, reg1, reg2)
723
    END
567
END BinOp;
-
 
568
 
724
  END;
569
 
725
  FpuSave(local);
570
PROCEDURE PushAll (NumberOfParameters: INTEGER);
-
 
571
BEGIN
-
 
572
    REG.PushAll(R);
-
 
573
    R.pushed := R.pushed - NumberOfParameters
-
 
574
END PushAll;
-
 
575
 
-
 
576
 
-
 
577
PROCEDURE NewLabel (): INTEGER;
-
 
578
BEGIN
-
 
579
    BIN.NewLabel(program)
-
 
580
    RETURN CODE.NewLabel()
-
 
581
END NewLabel;
726
  jmplong(CALL, proc);
582
 
727
  AfterRet(func, float, callconv, parsize);
-
 
728
  FpuLoad(local, func & float)
-
 
729
END Call;
583
 
730
 
584
PROCEDURE GetRegA;
731
PROCEDURE CallRTL(Proc: INTEGER);
585
BEGIN
732
BEGIN
586
    ASSERT(REG.GetReg(R, eax))
733
  New;
587
END GetRegA;
734
  current.clen := 5;
-
 
735
  Code[ccount] := CALL;
588
 
736
  INC(ccount);
-
 
Line -... Line 589...
-
 
589
 
737
  current.codeadr := sys.ADR(Code[ccount]);
590
PROCEDURE translate (code: CODE.CODES; pic: BOOLEAN; stroffs: INTEGER);
-
 
591
VAR
-
 
592
    cmd: COMMAND;
-
 
593
 
-
 
594
    reg1, reg2: INTEGER;
-
 
595
 
738
  current.varadr := sys.ADR(RtlProc[Proc]);
596
    n, a, b, label, cc: INTEGER;
-
 
597
 
739
  current.tcmd := JCMD;
598
    param1, param2: INTEGER;
-
 
599
 
740
  INC(ccount, 4)
600
    float: REAL;
741
END CallRTL;
601
 
-
 
602
BEGIN
-
 
603
    cmd := code.commands.first(COMMAND);
-
 
604
 
-
 
605
    WHILE cmd # NIL DO
-
 
606
 
-
 
607
        param1 := cmd.param1;
-
 
608
        param2 := cmd.param2;
-
 
609
 
-
 
610
        CASE cmd.opcode OF
-
 
611
 
-
 
612
        |CODE.opJMP:
-
 
613
            jmp(param1)
742
 
614
 
-
 
615
        |CODE.opCALL:
-
 
616
            call(param1)
-
 
617
 
-
 
618
        |CODE.opCALLI:
-
 
619
            IF pic THEN
743
PROCEDURE PushInt*(n: INTEGER);
620
                reg1 := REG.GetAnyReg(R);
-
 
621
                Pic(reg1, BIN.PICIMP, param1);
-
 
622
                OutByte2(0FFH, 010H + reg1);  // call dword[reg1]
-
 
623
                drop
-
 
624
            ELSE
-
 
625
                OutByte2(0FFH, 015H);  // call dword[L]
-
 
626
                Reloc(BIN.RIMP, param1)
-
 
627
            END
-
 
628
 
-
 
629
        |CODE.opCALLP:
-
 
630
            UnOp(reg1);
-
 
631
            OutByte2(0FFH, 0D0H + reg1);    // call reg1
-
 
632
            drop;
-
 
633
            ASSERT(R.top = -1)
-
 
634
 
-
 
635
        |CODE.opPRECALL:
744
BEGIN
636
            n := param2;
-
 
637
            IF (param1 # 0) & (n # 0) THEN
745
  OutByte(68H);
638
                subrc(esp, 8)
746
  CmdN(n)
639
            END;
747
END PushInt;
640
            WHILE n > 0 DO
748
 
641
                subrc(esp, 8);
749
PROCEDURE Prolog*(exename: UTILS.STRING);
-
 
Line -... Line 642...
-
 
642
                OutByte3(0DDH, 01CH, 024H); // fstp qword[esp]
750
BEGIN
643
                DEC(n)
-
 
644
            END;
751
  ExecName := exename;
645
            PushAll(0)
752
  Labels[hInstance] := -dcount;
646
 
753
  dataint(0);
647
        |CODE.opALIGN16:
-
 
648
            ASSERT(eax IN R.regs);
-
 
649
            mov(eax, esp);
-
 
650
            andrc(esp, -16);
754
  Labels[SELFNAME] := -dcount;
651
            n := (3 - param2 MOD 4) * 4;
Line 755... Line 652...
755
  datastr(exename);
652
            IF n > 0 THEN
-
 
653
                subrc(esp, n)
-
 
654
            END;
-
 
655
            push(eax)
-
 
656
 
-
 
657
        |CODE.opRES:
-
 
658
            ASSERT(R.top = -1);
-
 
659
            GetRegA;
-
 
660
            n := param2;
756
  Label(START);
661
            WHILE n > 0 DO
-
 
662
                OutByte3(0DDH, 004H, 024H); // fld qword[esp]
-
 
663
                addrc(esp, 8);
757
  IF dll THEN
664
                DEC(n)
-
 
665
            END
-
 
666
 
-
 
667
        |CODE.opRESF:
-
 
668
            n := param2;
-
 
669
            IF n > 0 THEN
-
 
670
                OutByte3(0DDH, 5CH + long(n * 8), 24H);
-
 
671
                OutIntByte(n * 8); // fstp qword[esp + n*8]
-
 
672
                INC(n)
758
    OutCode("558BEC837D0C007507");
673
            END;
-
 
674
 
759
    CallRTL(_close);
675
            WHILE n > 0 DO
-
 
676
                OutByte3(0DDH, 004H, 024H); // fld qword[esp]
-
 
677
                addrc(esp, 8);
-
 
678
                DEC(n)
-
 
679
            END
-
 
680
 
-
 
681
        |CODE.opENTER:
-
 
682
            ASSERT(R.top = -1);
-
 
683
 
-
 
684
            SetLabel(param1);
-
 
685
 
760
    OutCode("EB06837D0C017409B801000000C9C20C00")
686
            push(ebp);
-
 
687
            mov(ebp, esp);
-
 
688
 
-
 
689
            n := param2;
-
 
690
            IF n > 4 THEN
-
 
691
                movrc(ecx, n);
-
 
692
                pushc(0);             // @@: push 0
-
 
693
                OutByte2(0E2H, 0FCH)  // loop @b
-
 
694
            ELSE
-
 
695
                WHILE n > 0 DO
-
 
696
                    pushc(0);
-
 
697
                    DEC(n)
-
 
698
                END
-
 
699
            END
-
 
700
 
-
 
701
        |CODE.opLEAVE, CODE.opLEAVER, CODE.opLEAVEF:
-
 
702
            IF cmd.opcode = CODE.opLEAVER THEN
-
 
703
                UnOp(reg1);
-
 
704
                IF reg1 # eax THEN
-
 
705
                    GetRegA;
-
 
706
                    ASSERT(REG.Exchange(R, reg1, eax));
-
 
707
                    drop
-
 
708
                END;
-
 
709
                drop
-
 
710
            END;
-
 
711
 
-
 
712
            ASSERT(R.top = -1);
-
 
713
 
-
 
714
            mov(esp, ebp);
-
 
715
            pop(ebp);
-
 
716
 
-
 
717
            n := param2;
-
 
718
            IF n > 0 THEN
-
 
719
                n := n * 4;
-
 
720
                OutByte(0C2H); OutWord(Word(n)) // ret n
-
 
721
            ELSE
-
 
722
                OutByte(0C3H) // ret
-
 
723
            END
-
 
724
 
-
 
725
        |CODE.opERRC:
-
 
726
            pushc(param2)
-
 
727
 
-
 
728
        |CODE.opPARAM:
-
 
729
            n := param2;
-
 
730
            IF n = 1 THEN
-
 
731
                UnOp(reg1);
-
 
732
                push(reg1);
761
  ELSIF obj THEN
733
                drop
-
 
734
            ELSE
-
 
735
                ASSERT(R.top + 1 <= n);
-
 
736
                PushAll(n)
-
 
737
            END
762
    OutCode("558BEC")
738
 
-
 
739
        |CODE.opCLEANUP:
-
 
740
            n := param2 * 4;
-
 
741
            IF n # 0 THEN
-
 
742
                addrc(esp, n)
-
 
743
            END
-
 
744
 
-
 
745
        |CODE.opPOPSP:
-
 
746
            pop(esp)
-
 
747
 
-
 
748
        |CODE.opCONST:
-
 
749
            reg1 := REG.GetAnyReg(R);
-
 
750
            movrc(reg1, param2)
-
 
751
 
-
 
752
        |CODE.opLABEL:
-
 
753
            SetLabel(param2) // L:
-
 
754
 
-
 
755
        |CODE.opNOP:
-
 
756
 
-
 
757
        |CODE.opGADR:
-
 
758
            reg1 := REG.GetAnyReg(R);
-
 
759
            IF pic THEN
-
 
760
                Pic(reg1, BIN.PICBSS, param2)
-
 
761
            ELSE
-
 
762
                OutByte(0B8H + reg1);  // mov reg1, _bss + param2
-
 
763
                Reloc(BIN.RBSS, param2)
-
 
764
            END
-
 
765
 
763
  END;
766
        |CODE.opLADR:
-
 
767
            n := param2 * 4;
-
 
768
            reg1 := REG.GetAnyReg(R);
-
 
769
            OutByte2(8DH, 45H + reg1 * 8 + long(n));  // lea reg1, dword[ebp + n]
-
 
770
            OutIntByte(n)
-
 
771
 
-
 
772
        |CODE.opVADR:
-
 
773
            n := param2 * 4;
-
 
774
            reg1 := REG.GetAnyReg(R);
-
 
775
            OutByte2(8BH, 45H + reg1 * 8 + long(n));  // mov reg1, dword[ebp + n]
-
 
776
            OutIntByte(n)
-
 
777
 
-
 
778
        |CODE.opSADR:
-
 
779
            reg1 := REG.GetAnyReg(R);
-
 
780
            IF pic THEN
764
  start := asmlist.Last(ASMLINE)
781
                Pic(reg1, BIN.PICDATA, stroffs + param2);
-
 
782
            ELSE
-
 
783
                OutByte(0B8H + reg1);  // mov reg1, _data + stroffs + param2
765
END Prolog;
784
                Reloc(BIN.RDATA, stroffs + param2)
-
 
785
            END
-
 
786
 
-
 
787
        |CODE.opSAVEC:
-
 
788
            UnOp(reg1);
-
 
789
            OutByte2(0C7H, reg1); OutInt(param2);  // mov dword[reg1], param2
-
 
790
            drop
-
 
791
 
-
 
792
        |CODE.opSAVE8C:
766
 
793
            UnOp(reg1);
-
 
794
            OutByte3(0C6H, reg1, Byte(param2));  // mov byte[reg1], param2
-
 
795
            drop
-
 
796
 
-
 
797
        |CODE.opSAVE16C:
-
 
798
            UnOp(reg1);
-
 
799
            OutByte3(66H, 0C7H, reg1); OutWord(Word(param2));  // mov word[reg1], param2
-
 
800
            drop
-
 
801
 
-
 
802
        |CODE.opVLOAD32:
-
 
803
            n := param2 * 4;
-
 
804
            reg1 := REG.GetAnyReg(R);
767
PROCEDURE AddRec*(base: INTEGER);
805
            OutByte2(8BH, 45H + reg1 * 8 + long(n));  // mov reg1, dword[ebp + n]
-
 
806
            OutIntByte(n);
-
 
807
            OutByte2(8BH, reg1 * 9)  // mov reg1, dword[reg1]
768
BEGIN
808
 
-
 
809
        |CODE.opGLOAD32:
-
 
810
            reg1 := REG.GetAnyReg(R);
-
 
811
            IF pic THEN
-
 
812
                Pic(reg1, BIN.PICBSS, param2);
-
 
813
                OutByte2(8BH, reg1 * 9)       // mov reg1, dword[reg1]
-
 
814
            ELSE
-
 
815
                OutByte2(08BH, 05H + reg1 * 8);  // mov reg1, dword[_bss + param2]
-
 
816
                Reloc(BIN.RBSS, param2)
-
 
817
            END
-
 
818
 
-
 
819
        |CODE.opLLOAD32:
-
 
820
            n := param2 * 4;
-
 
821
            reg1 := REG.GetAnyReg(R);
-
 
822
            OutByte2(8BH, 45H + reg1 * 8 + long(n));  // mov reg1, dword[ebp + n]
-
 
823
            OutIntByte(n)
-
 
824
 
-
 
825
        |CODE.opLOAD32:
-
 
826
            UnOp(reg1);
-
 
827
            OutByte2(8BH, reg1 * 9)  // mov reg1, dword[reg1]
-
 
828
 
-
 
829
        |CODE.opVLOAD8:
-
 
830
            n := param2 * 4;
-
 
831
            reg1 := REG.GetAnyReg(R);
-
 
832
            OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
-
 
833
            OutIntByte(n);
-
 
834
            OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
-
 
835
 
-
 
836
        |CODE.opGLOAD8:
-
 
837
            reg1 := REG.GetAnyReg(R);
-
 
838
            IF pic THEN
769
  INC(reccount);
839
                Pic(reg1, BIN.PICBSS, param2);
-
 
840
                OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
770
  recarray[reccount] := base
841
            ELSE
-
 
842
                OutByte3(00FH, 0B6H, 05H + reg1 * 8);  // movzx reg1, byte[_bss + param2]
-
 
843
                Reloc(BIN.RBSS, param2)
-
 
844
            END
-
 
845
 
-
 
846
        |CODE.opLLOAD8:
-
 
847
            n := param2 * 4;
-
 
848
            reg1 := REG.GetAnyReg(R);
-
 
849
            OutByte3(0FH, 0B6H, 45H + reg1 * 8 + long(n)); // movzx reg1, byte[ebp + n]
-
 
850
            OutIntByte(n)
-
 
851
 
-
 
852
        |CODE.opLOAD8:
-
 
853
            UnOp(reg1);
-
 
854
            OutByte3(0FH, 0B6H, reg1 * 9) // movzx reg1, byte[reg1]
-
 
855
 
-
 
856
        |CODE.opVLOAD16:
-
 
857
            n := param2 * 4;
771
END AddRec;
858
            reg1 := REG.GetAnyReg(R);
-
 
859
            OutByte2(8BH, 45H + reg1 * 8 + long(n)); // mov reg1, dword[ebp + n]
-
 
860
            OutIntByte(n);
772
 
861
            OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
-
 
862
 
-
 
863
        |CODE.opGLOAD16:
-
 
864
            reg1 := REG.GetAnyReg(R);
-
 
865
            IF pic THEN
-
 
866
                Pic(reg1, BIN.PICBSS, param2);
-
 
867
                OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
-
 
868
            ELSE
-
 
869
                OutByte3(00FH, 0B7H, 05H + reg1 * 8);  // movzx reg1, word[_bss + param2]
-
 
870
                Reloc(BIN.RBSS, param2)
-
 
871
            END
-
 
872
 
773
PROCEDURE CmpOpt(inv: BOOLEAN): INTEGER;
873
        |CODE.opLLOAD16:
774
VAR cur: ASMLINE; c: INTEGER;
-
 
775
BEGIN
-
 
776
  c := ORD(Code[current.Prev.Prev(ASMLINE).cmd]);
-
 
Line 777... Line -...
777
  IF inv THEN
-
 
778
    IF ODD(c) THEN
-
 
779
      DEC(c)
874
            n := param2 * 4;
780
    ELSE
-
 
Line -... Line 875...
-
 
875
            reg1 := REG.GetAnyReg(R);
781
      INC(c)
876
            OutByte3(0FH, 0B7H, 45H + reg1 * 8 + long(n)); // movzx reg1, word[ebp + n]
-
 
877
            OutIntByte(n)
-
 
878
 
782
    END
879
        |CODE.opLOAD16:
-
 
880
            UnOp(reg1);
-
 
881
            OutByte3(0FH, 0B7H, reg1 * 9) // movzx reg1, word[reg1]
783
  END;
882
 
784
  cur := current;
883
        |CODE.opUMINUS:
Line 785... Line 884...
785
  REPEAT
884
            UnOp(reg1);
786
    cur.tcmd := 0;
-
 
787
    cur.clen := 0;
885
            neg(reg1)
788
    cur := cur.Prev(ASMLINE)
886
 
789
  UNTIL cur.tcmd = ICMP1;
887
        |CODE.opADD:
790
  cur.tcmd := 0;
888
            BinOp(reg1, reg2);
791
  cur.clen := 0
-
 
792
  RETURN c - 16
889
            add(reg1, reg2);
-
 
890
            drop
-
 
891
 
793
END CmpOpt;
892
        |CODE.opADDL, CODE.opADDR:
794
 
893
            IF param2 # 0 THEN
795
PROCEDURE ifwh*(L: INTEGER);
-
 
Line -... Line 894...
-
 
894
                UnOp(reg1);
-
 
895
                IF param2 = 1 THEN
-
 
896
                    OutByte(40H + reg1) // inc reg1
-
 
897
                ELSIF param2 = -1 THEN
-
 
898
                    OutByte(48H + reg1) // dec reg1
-
 
899
                ELSE
796
VAR c: INTEGER;
900
                    addrc(reg1, param2)
-
 
901
                END
797
BEGIN
902
            END
-
 
903
 
798
  IF current.Prev(ASMLINE).tcmd = ICMP2 THEN
904
        |CODE.opSUB:
-
 
905
            BinOp(reg1, reg2);
-
 
906
            OutByte2(29H, 0C0H + reg2 * 8 + reg1); // sub reg1, reg2
-
 
907
            drop
-
 
908
 
799
    c := CmpOpt(TRUE);
909
        |CODE.opSUBR, CODE.opSUBL:
-
 
910
            UnOp(reg1);
-
 
911
            n := param2;
-
 
912
            IF n = 1 THEN
-
 
913
                OutByte(48H + reg1) // dec reg1
800
    OutCode("5A583BC2");
914
            ELSIF n = -1 THEN
-
 
915
                OutByte(40H + reg1) // inc reg1
-
 
916
            ELSIF n # 0 THEN
-
 
917
                subrc(reg1, n)
801
    jmp(CHR(c), L)
918
            END;
802
  ELSE
919
            IF cmd.opcode = CODE.opSUBL THEN
-
 
920
                neg(reg1)
-
 
921
            END
-
 
922
 
803
    PopECX;
923
        |CODE.opMULC:
804
    OutCode("85C9");
924
            UnOp(reg1);
-
 
925
 
-
 
926
            a := param2;
805
    jmp(JE, L)
927
            IF a > 1 THEN
806
  END
-
 
807
END ifwh;
928
                n := log2(a)
808
 
-
 
809
PROCEDURE PushConst*(Number: INTEGER);
-
 
Line 810... Line 929...
810
BEGIN
929
            ELSIF a < -1 THEN
811
  IntByte("6A", "68", Number);
930
                n := log2(-a)
812
  current.Prev(ASMLINE).varadr := Number
-
 
813
END PushConst;
931
            ELSE
814
 
932
                n := -1
815
PROCEDURE IfWhile*(L: INTEGER; orop: BOOLEAN);
933
            END;
816
VAR c, L1: INTEGER;
934
 
817
BEGIN
935
            IF a = 1 THEN
818
  L1 := NewLabel();
936
 
819
  IF current.Prev(ASMLINE).tcmd = ICMP2 THEN
937
            ELSIF a = -1 THEN
-
 
938
                neg(reg1)
820
    c := CmpOpt(orop);
939
            ELSIF a = 0 THEN
-
 
940
                OutByte2(31H, 0C0H + reg1 * 9) // xor reg1, reg1
821
    OutCode("5A583BC2");
941
            ELSE
-
 
942
                IF n > 0 THEN
-
 
943
                    IF a < 0 THEN
822
    jmp(CHR(c), L1);
944
                        neg(reg1)
-
 
945
                    END;
823
    PushConst(ORD(orop))
946
 
824
  ELSE
947
                    IF n # 1 THEN
-
 
948
                        OutByte3(0C1H, 0E0H + reg1, n)   // shl reg1, n
-
 
949
                    ELSE
825
    PopECX;
950
                        OutByte2(0D1H, 0E0H + reg1)      // shl reg1, 1
-
 
951
                    END
-
 
952
                ELSE
826
    OutCode("85C9");
953
                    OutByte2(69H + short(a), 0C0H + reg1 * 9); // imul reg1, a
-
 
954
                    OutIntByte(a)
827
    IF orop THEN
955
                END
-
 
956
            END
-
 
957
 
828
      jmp(JE, L1)
958
        |CODE.opMUL:
829
    ELSE
959
            BinOp(reg1, reg2);
830
      jmp(JNE, L1)
960
            OutByte3(0FH, 0AFH, 0C0H + reg1 * 8 + reg2); // imul reg1, reg2
831
    END;
961
            drop
-
 
962
 
-
 
963
        |CODE.opSAVE, CODE.opSAVE32:
-
 
964
            BinOp(reg2, reg1);
-
 
965
            OutByte2(89H, reg2 * 8 + reg1); // mov dword[reg1], reg2
-
 
966
            drop;
-
 
967
            drop
-
 
968
 
-
 
969
        |CODE.opSAVE8:
-
 
970
            BinOp(reg2, reg1);
-
 
971
            OutByte2(88H, reg2 * 8 + reg1); // mov byte[reg1], reg2
-
 
972
            drop;
-
 
973
            drop
-
 
974
 
-
 
975
        |CODE.opSAVE16:
-
 
976
            BinOp(reg2, reg1);
-
 
977
            OutByte3(66H, 89H, reg2 * 8 + reg1); // mov word[reg1], reg2
-
 
978
            drop;
-
 
979
            drop
-
 
980
 
-
 
981
        |CODE.opSAVEP:
-
 
982
            UnOp(reg1);
-
 
983
            IF pic THEN
-
 
984
                reg2 := REG.GetAnyReg(R);
-
 
985
                Pic(reg2, BIN.PICCODE, param2);
-
 
986
                OutByte2(089H, reg2 * 8 + reg1); // mov dword[reg1], reg2
-
 
987
                drop
-
 
988
            ELSE
-
 
989
                OutByte2(0C7H, reg1);  // mov dword[reg1], L
-
 
990
                Reloc(BIN.RCODE, param2)
-
 
991
            END;
-
 
992
            drop
-
 
993
 
-
 
994
        |CODE.opSAVEIP:
-
 
995
            UnOp(reg1);
-
 
996
            IF pic THEN
-
 
997
                reg2 := REG.GetAnyReg(R);
-
 
998
                Pic(reg2, BIN.PICIMP, param2);
-
 
999
                OutByte2(0FFH, 30H + reg2);   // push dword[reg2]
832
    PushECX
1000
                OutByte2(08FH, reg1);         // pop dword[reg1]
833
  END;
1001
                drop
834
  jmp(JMP, L);
-
 
835
  Label(L1)
-
 
836
END IfWhile;
1002
            ELSE
837
 
-
 
Line -... Line 1003...
-
 
1003
                OutByte2(0FFH, 035H);  // push dword[L]
838
PROCEDURE newrec*;
1004
                Reloc(BIN.RIMP, param2);
839
BEGIN
-
 
840
  CallRTL(_newrec)
1005
                OutByte2(08FH, reg1)   // pop dword[reg1]
841
END newrec;
1006
            END;
842
 
-
 
Line 843... Line 1007...
843
PROCEDURE disprec*;
1007
            drop
-
 
1008
 
-
 
1009
        |CODE.opPUSHP:
-
 
1010
            reg1 := REG.GetAnyReg(R);
-
 
1011
            IF pic THEN
-
 
1012
                Pic(reg1, BIN.PICCODE, param2)
-
 
1013
            ELSE
-
 
1014
                OutByte(0B8H + reg1);  // mov reg1, L
-
 
1015
                Reloc(BIN.RCODE, param2)
-
 
1016
            END
-
 
1017
 
-
 
1018
        |CODE.opPUSHIP:
-
 
1019
            reg1 := REG.GetAnyReg(R);
-
 
1020
            IF pic THEN
-
 
1021
                Pic(reg1, BIN.PICIMP, param2);
-
 
1022
                OutByte2(08BH, reg1 * 9)         // mov reg1, dword[reg1]
-
 
1023
            ELSE
-
 
1024
                OutByte2(08BH, 05H + reg1 * 8);  // mov reg1, dword[L]
-
 
1025
                Reloc(BIN.RIMP, param2)
-
 
1026
            END
-
 
1027
 
-
 
1028
        |CODE.opNOT:
-
 
1029
            UnOp(reg1);
-
 
1030
            test(reg1);
-
 
1031
            setcc(sete, reg1);
-
 
1032
            andrc(reg1, 1)
-
 
1033
 
-
 
1034
        |CODE.opORD:
-
 
1035
            UnOp(reg1);
-
 
1036
            test(reg1);
-
 
1037
            setcc(setne, reg1);
-
 
1038
            andrc(reg1, 1)
-
 
1039
 
-
 
1040
        |CODE.opSBOOL:
-
 
1041
            BinOp(reg2, reg1);
-
 
1042
            test(reg2);
-
 
1043
            setcc(setne, reg2);
-
 
1044
            OutByte2(88H, reg2 * 8 + reg1); // mov byte[reg1], reg2
-
 
1045
            drop;
844
BEGIN
1046
            drop
-
 
1047
 
-
 
1048
        |CODE.opSBOOLC:
-
 
1049
            UnOp(reg1);
-
 
1050
            OutByte3(0C6H, reg1, ORD(param2 # 0)); // mov byte[reg1], 0/1
845
  CallRTL(_disprec)
1051
            drop
-
 
1052
 
-
 
1053
        |CODE.opODD:
-
 
1054
            UnOp(reg1);
-
 
1055
            andrc(reg1, 1)
-
 
1056
 
-
 
1057
        |CODE.opGTR, CODE.opLTL, CODE.opGER, CODE.opLEL,
-
 
1058
         CODE.opLER, CODE.opGEL, CODE.opLTR, CODE.opGTL,
-
 
1059
         CODE.opEQR, CODE.opEQL, CODE.opNER, CODE.opNEL:
846
END disprec;
1060
            UnOp(reg1);
-
 
1061
            IF param2 = 0 THEN
847
 
1062
                test(reg1)
-
 
1063
            ELSE
-
 
1064
                cmprc(reg1, param2)
-
 
1065
            END;
-
 
1066
            drop;
-
 
1067
            cc := cond(cmd.opcode);
-
 
1068
 
-
 
1069
            IF cmd.next(COMMAND).opcode = CODE.opJE THEN
-
 
1070
                label := cmd.next(COMMAND).param1;
848
PROCEDURE String*(Number, Len: INTEGER; str: UTILS.STRING);
1071
                jcc(cc, label);
-
 
1072
                cmd := cmd.next(COMMAND)
-
 
1073
 
-
 
1074
            ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
-
 
1075
                label := cmd.next(COMMAND).param1;
-
 
1076
                jcc(inv1(cc), label);
-
 
1077
                cmd := cmd.next(COMMAND)
-
 
1078
 
-
 
1079
            ELSE
-
 
1080
                reg1 := REG.GetAnyReg(R);
-
 
1081
                setcc(cc + 16, reg1);
-
 
1082
                andrc(reg1, 1)
-
 
1083
            END;
-
 
1084
 
-
 
1085
        |CODE.opGT, CODE.opGE, CODE.opLT,
-
 
1086
         CODE.opLE, CODE.opEQ, CODE.opNE:
-
 
1087
            BinOp(reg1, reg2);
-
 
1088
            cmprr(reg1, reg2);
-
 
1089
            drop;
-
 
1090
            drop;
-
 
1091
            cc := cond(cmd.opcode);
-
 
1092
 
849
BEGIN
1093
            IF cmd.next(COMMAND).opcode = CODE.opJE THEN
850
  Labels[Number] := -dcount;
1094
                label := cmd.next(COMMAND).param1;
851
  IF Len > 1 THEN
1095
                jcc(cc, label);
-
 
1096
                cmd := cmd.next(COMMAND)
852
    datastr(str)
1097
 
853
  ELSIF Len = 1 THEN
1098
            ELSIF cmd.next(COMMAND).opcode = CODE.opJNE THEN
-
 
1099
                label := cmd.next(COMMAND).param1;
-
 
1100
                jcc(inv1(cc), label);
854
    dataint(ORD(str[0]))
1101
                cmd := cmd.next(COMMAND)
855
  ELSE
1102
 
856
    dataint(0)
1103
            ELSE
857
  END
-
 
Line 858... Line -...
858
END String;
-
 
859
 
-
 
860
PROCEDURE InsertFpuInit;
-
 
861
VAR t: ASMLINE;
1104
                reg1 := REG.GetAnyReg(R);
862
BEGIN
-
 
Line 863... Line 1105...
863
  IF isfpu THEN
1105
                setcc(cc + 16, reg1);
864
    t := current;
-
 
865
    current := fpucmd;
1106
                andrc(reg1, 1)
866
    IF maxfpu > 0 THEN
1107
            END
Line 867... Line -...
867
      OutCode("83EC");
-
 
868
      OutByte(maxfpu * 8)
-
 
869
    END;
-
 
870
    OutCode("DBE3");
1108
 
871
    current := t
1109
        |CODE.opEQB, CODE.opNEB:
872
  END
1110
            BinOp(reg1, reg2);
873
END InsertFpuInit;
-
 
874
 
-
 
Line 875... Line 1111...
875
PROCEDURE ProcBeg*(Number, Local: INTEGER; Module: BOOLEAN);
1111
            drop;
876
VAR i: INTEGER;
-
 
877
BEGIN
1112
            drop;
878
  IF Module THEN
1113
 
879
    OutCode("EB0C");
1114
            test(reg1);
Line 880... Line 1115...
880
    Label(Number + 3);
1115
            OutByte2(74H, 5);  // je @f
881
    PushInt(Number + 2);
-
 
882
    jmplong(JMP, HALT);
-
 
883
    Label(Number + 1)
1116
            movrc(reg1, 1);    // mov reg1, 1
884
  ELSE
-
 
885
    Label(Number)
-
 
Line 886... Line -...
886
  END;
-
 
887
  OutCode("558BEC");
-
 
888
  IF Local > 12 THEN
1117
                               // @@:
889
    IntByte("83EC", "81EC", Local);
1118
            test(reg2);
890
    OutCode("8BD733C08BFCB9");
1119
            OutByte2(74H, 5);  // je @f
891
    OutInt(ASR(Local, 2));
1120
            movrc(reg2, 1);    // mov reg2, 1
Line 892... Line 1121...
892
    OutCode("9CFCF3AB8BFA9D")
1121
                               // @@:
893
  ELSE
-
 
894
    FOR i := 4 TO Local BY 4 DO
1122
 
-
 
1123
            cmprr(reg1, reg2);
895
      OutCode("6A00")
1124
            reg1 := REG.GetAnyReg(R);
Line -... Line 1125...
-
 
1125
            IF cmd.opcode = CODE.opEQB THEN
-
 
1126
                setcc(sete, reg1)
-
 
1127
            ELSE
-
 
1128
                setcc(setne, reg1)
-
 
1129
            END;
-
 
1130
            andrc(reg1, 1)
-
 
1131
 
-
 
1132
        |CODE.opDROP:
-
 
1133
            UnOp(reg1);
-
 
1134
            drop
-
 
1135
 
896
    END
1136
        |CODE.opJNZ:
-
 
1137
            UnOp(reg1);
-
 
1138
            test(reg1);
897
  END;
1139
            jcc(jne, param1)
898
  fpucmd := current;
1140
 
-
 
1141
        |CODE.opJZ:
-
 
1142
            UnOp(reg1);
-
 
1143
            test(reg1);
899
  fpu := 0;
1144
            jcc(je, param1)
900
  maxfpu := 0;
1145
 
901
  isfpu := FALSE
1146
        |CODE.opJE:
-
 
1147
            UnOp(reg1);
902
END ProcBeg;
1148
            test(reg1);
-
 
1149
            jcc(jne, param1);
-
 
1150
            drop;
903
 
1151
 
-
 
1152
        |CODE.opJNE:
-
 
1153
            UnOp(reg1);
-
 
1154
            test(reg1);
-
 
1155
            jcc(je, param1);
-
 
1156
            drop;
-
 
1157
 
-
 
1158
        |CODE.opSWITCH:
-
 
1159
            UnOp(reg1);
-
 
1160
            IF param2 = 0 THEN
-
 
1161
                reg2 := eax
-
 
1162
            ELSE
-
 
1163
                reg2 := ecx
-
 
1164
            END;
-
 
1165
            IF reg1 # reg2 THEN
-
 
1166
                ASSERT(REG.GetReg(R, reg2));
-
 
1167
                ASSERT(REG.Exchange(R, reg1, reg2));
-
 
1168
                drop
-
 
1169
            END;
-
 
1170
            drop
-
 
1171
 
-
 
1172
        |CODE.opENDSW:
-
 
1173
 
-
 
1174
        |CODE.opCASEL:
-
 
1175
            cmprc(eax, param1);
-
 
1176
            jcc(jl, param2)
-
 
1177
 
-
 
1178
        |CODE.opCASER:
-
 
1179
            cmprc(eax, param1);
904
PROCEDURE Leave*;
1180
            jcc(jg, param2)
905
BEGIN
-
 
Line -... Line 1181...
-
 
1181
 
-
 
1182
        |CODE.opCASELR:
906
  OutByte(0C9H);
1183
            cmprc(eax, param1);
-
 
1184
            jcc(jl, param2);
-
 
1185
            jcc(jg, cmd.param3)
907
  InsertFpuInit
1186
 
-
 
1187
        |CODE.opCODE:
-
 
1188
            OutByte(param2)
-
 
1189
 
-
 
1190
        |CODE.opGET:
908
END Leave;
1191
            BinOp(reg1, reg2);
-
 
1192
            drop;
-
 
1193
            drop;
-
 
1194
 
-
 
1195
            CASE param2 OF
-
 
1196
            |1:
-
 
1197
                OutByte2(8AH, reg1 * 9);       // mov reg1, byte[reg1]
-
 
1198
                OutByte2(88H, reg1 * 8 + reg2) // mov byte[reg2], reg1
-
 
1199
 
-
 
1200
            |2:
-
 
1201
                OutByte3(66H, 8BH, reg1 * 9);       // mov reg1, word[reg1]
-
 
1202
                OutByte3(66H, 89H, reg1 * 8 + reg2) // mov word[reg2], reg1
-
 
1203
 
909
 
1204
            |4:
-
 
1205
                OutByte2(8BH, reg1 * 9);        // mov reg1, dword[reg1]
-
 
1206
                OutByte2(89H, reg1 * 8 + reg2)  // mov dword[reg2], reg1
-
 
1207
 
-
 
1208
            |8:
-
 
1209
                PushAll(0);
910
PROCEDURE ProcEnd*(Number, Param: INTEGER; func, float: BOOLEAN);
1210
                push(reg2);
-
 
1211
                push(reg1);
-
 
1212
                pushc(8);
911
BEGIN
1213
                CallRTL(pic, CODE._move)
-
 
1214
 
-
 
1215
            END
-
 
1216
 
-
 
1217
        |CODE.opSAVES:
-
 
1218
            UnOp(reg1);
-
 
1219
            drop;
-
 
1220
            PushAll(0);
-
 
1221
            push(reg1);
-
 
1222
 
-
 
1223
            IF pic THEN
-
 
1224
                Pic(reg1, BIN.PICDATA, stroffs + param2);
912
  IF func & ~float THEN
1225
                push(reg1)
-
 
1226
            ELSE
-
 
1227
                OutByte(068H);  // push _data + stroffs + param2
-
 
1228
                Reloc(BIN.RDATA, stroffs + param2);
-
 
1229
            END;
-
 
1230
 
-
 
1231
            pushc(param1);
-
 
1232
            CallRTL(pic, CODE._move)
-
 
1233
 
-
 
1234
        |CODE.opCHKBYTE:
-
 
1235
            BinOp(reg1, reg2);
-
 
1236
            cmprc(reg1, 256);
-
 
1237
            jcc(jb, param1)
-
 
1238
 
-
 
1239
        |CODE.opCHKIDX:
-
 
1240
            UnOp(reg1);
913
    PopEAX
1241
            cmprc(reg1, param2);
-
 
1242
            jcc(jb, param1)
-
 
1243
 
-
 
1244
        |CODE.opCHKIDX2:
-
 
1245
            BinOp(reg1, reg2);
914
  END;
1246
            IF param2 # -1 THEN
-
 
1247
                cmprr(reg2, reg1);
-
 
1248
                mov(reg1, reg2);
-
 
1249
                drop;
-
 
1250
                jcc(jb, param1)
-
 
1251
            ELSE
-
 
1252
                INCL(R.regs, reg1);
-
 
1253
                DEC(R.top);
915
  OutByte(0C9H);
1254
                R.stk[R.top] := reg2
-
 
1255
            END
916
  IF Param = 0 THEN
1256
 
917
    OutByte(0C3H)
1257
        |CODE.opLEN:
918
  ELSE
1258
            n := param2;
919
    OutByte(0C2H);
-
 
Line 920... Line 1259...
920
    OutByte(Param MOD 256);
1259
            UnOp(reg1);
921
    OutByte(ASR(Param, 8))
-
 
922
  END;
1260
            drop;
-
 
1261
            EXCL(R.regs, reg1);
923
  InsertFpuInit
1262
 
Line -... Line 1263...
-
 
1263
            WHILE n > 0 DO
-
 
1264
                UnOp(reg2);
-
 
1265
                drop;
-
 
1266
                DEC(n)
-
 
1267
            END;
-
 
1268
 
-
 
1269
            INCL(R.regs, reg1);
-
 
1270
            ASSERT(REG.GetReg(R, reg1))
-
 
1271
 
-
 
1272
        |CODE.opINC1:
-
 
1273
            UnOp(reg1);
-
 
1274
            OutByte2(0FFH, reg1); // inc dword[reg1]
-
 
1275
            drop
-
 
1276
 
-
 
1277
        |CODE.opDEC1:
-
 
1278
            UnOp(reg1);
-
 
1279
            OutByte2(0FFH, 8 + reg1); // dec dword[reg1]
-
 
1280
            drop
-
 
1281
 
-
 
1282
        |CODE.opINCC:
-
 
1283
            UnOp(reg1);
-
 
1284
            n := param2;
-
 
1285
            OutByte2(81H + short(n), reg1); OutIntByte(n); // add dword[reg1], n
-
 
1286
            drop
-
 
1287
 
-
 
1288
        |CODE.opDECC:
-
 
1289
            UnOp(reg1);
-
 
1290
            n := param2;
-
 
1291
            OutByte2(81H + short(n), 28H + reg1); OutIntByte(n); // sub dword[reg1], n
-
 
1292
            drop
-
 
1293
 
-
 
1294
        |CODE.opINC:
-
 
1295
            BinOp(reg1, reg2);
-
 
1296
            OutByte2(01H, reg1 * 8 + reg2); // add dword[reg2], reg1
-
 
1297
            drop;
-
 
1298
            drop
-
 
1299
 
-
 
1300
        |CODE.opDEC:
-
 
1301
            BinOp(reg1, reg2);
-
 
1302
            OutByte2(29H, reg1 * 8 + reg2); // sub dword[reg2], reg1
-
 
1303
            drop;
-
 
1304
            drop
-
 
1305
 
-
 
1306
        |CODE.opINC1B:
-
 
1307
            UnOp(reg1);
-
 
1308
            OutByte2(0FEH, reg1); // inc byte[reg1]
-
 
1309
            drop
-
 
1310
 
924
END ProcEnd;
1311
        |CODE.opDEC1B:
-
 
1312
            UnOp(reg1);
-
 
1313
            OutByte2(0FEH, 08H + reg1); // dec byte[reg1]
-
 
1314
            drop
-
 
1315
 
-
 
1316
        |CODE.opINCCB:
-
 
1317
            UnOp(reg1);
-
 
1318
            OutByte3(80H, reg1, Byte(param2)); // add byte[reg1], n
-
 
1319
            drop
925
 
1320
 
-
 
1321
        |CODE.opDECCB:
926
PROCEDURE Module*(Name: UTILS.STRING; Number: INTEGER);
1322
            UnOp(reg1);
-
 
1323
            OutByte3(80H, 28H + reg1, Byte(param2)); // sub byte[reg1], n
927
BEGIN
1324
            drop
-
 
1325
 
-
 
1326
        |CODE.opINCB, CODE.opDECB:
-
 
1327
            BinOp(reg1, reg2);
-
 
1328
            IF cmd.opcode = CODE.opINCB THEN
928
  String(Number + 2, LENGTH(Name), Name);
1329
                OutByte2(00H, reg1 * 8 + reg2) // add byte[reg2], reg1
-
 
1330
            ELSE
-
 
1331
                OutByte2(28H, reg1 * 8 + reg2) // sub byte[reg2], reg1
-
 
1332
            END;
-
 
1333
            drop;
-
 
1334
            drop
-
 
1335
 
-
 
1336
        |CODE.opMULS:
-
 
1337
            BinOp(reg1, reg2);
-
 
1338
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); // and reg1, reg2
-
 
1339
            drop
-
 
1340
 
-
 
1341
        |CODE.opMULSC:
929
  jmplong(JMP, Number + 1)
1342
            UnOp(reg1);
-
 
1343
            andrc(reg1, param2)
-
 
1344
 
-
 
1345
        |CODE.opDIVS:
-
 
1346
            BinOp(reg1, reg2);
-
 
1347
            OutByte2(31H, 0C0H + reg2 * 8 + reg1); // xor reg1, reg2
-
 
1348
            drop
930
END Module;
1349
 
-
 
1350
        |CODE.opDIVSC:
-
 
1351
            UnOp(reg1);
-
 
1352
            OutByte2(81H + short(param2), 0F0H + reg1);  // xor reg1, n
-
 
1353
            OutIntByte(param2)
-
 
1354
 
-
 
1355
        |CODE.opADDS:
-
 
1356
            BinOp(reg1, reg2);
-
 
1357
            OutByte2(9H, 0C0H + reg2 * 8 + reg1); // or reg1, reg2
931
 
1358
            drop
932
PROCEDURE Asm*(s: UTILS.STRING);
1359
 
933
BEGIN
1360
        |CODE.opSUBS:
934
  OutCode(s)
1361
            BinOp(reg1, reg2);
935
END Asm;
1362
            not(reg2);
936
 
1363
            OutByte2(21H, 0C0H + reg2 * 8 + reg1); // and reg1, reg2
937
PROCEDURE GlobalAdr*(offset: INTEGER);
1364
            drop
938
BEGIN
1365
 
939
  OutByte(0BAH);
-
 
940
  OutInt(offset);
-
 
941
  current.codeadr := sys.ADR(Code[ccount - 4]);
1366
        |CODE.opADDSL, CODE.opADDSR:
942
  current.tcmd := GCMD;
-
 
Line 1917... Line -...
1917
PROCEDURE OutStringZ(str: ARRAY OF CHAR);
-
 
1918
VAR i: INTEGER;
-
 
1919
BEGIN
-
 
1920
  New;
-
 
Line 1921... Line -...
1921
  current.clen := LENGTH(str);
-
 
1922
  FOR i := 0 TO current.clen - 1 DO
-
 
1923
    Code[ccount] := str[i];
2325
        BIN.PutData(program, CHL.GetByte(code.data, i))
1924
    INC(ccount)
2326
    END;