Rev 8097 | Rev 9847 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 8097 | Rev 8859 | ||
---|---|---|---|
1 | (* |
1 | (* |
2 | BSD 2-Clause License |
2 | BSD 2-Clause License |
3 | 3 | ||
4 | Copyright (c) 2018-2020, Anton Krotov |
4 | Copyright (c) 2018-2021, Anton Krotov |
5 | All rights reserved. |
5 | All rights reserved. |
6 | *) |
6 | *) |
7 | 7 | ||
8 | MODULE AMD64; |
8 | MODULE AMD64; |
9 | 9 | ||
10 | IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG, TARGETS, |
10 | IMPORT IL, BIN, WR := WRITER, CHL := CHUNKLISTS, LISTS, PATHS, PROG, TARGETS, |
11 | REG, UTILS, S := STRINGS, PE32, ELF, X86, ERRORS; |
11 | REG, UTILS, S := STRINGS, PE32, ELF, X86, ERRORS; |
12 | 12 | ||
13 | 13 | ||
14 | CONST |
14 | CONST |
15 | 15 | ||
16 | rax = REG.R0; |
16 | rax = REG.R0; |
17 | r10 = REG.R10; |
17 | r10 = REG.R10; |
18 | r11 = REG.R11; |
18 | r11 = REG.R11; |
19 | 19 | ||
20 | rcx = REG.R1; |
20 | rcx = REG.R1; |
21 | rdx = REG.R2; |
21 | rdx = REG.R2; |
22 | r8 = REG.R8; |
22 | r8 = REG.R8; |
23 | r9 = REG.R9; |
23 | r9 = REG.R9; |
24 | 24 | ||
25 | rsp = 4; |
25 | rsp = 4; |
26 | rbp = 5; |
26 | rbp = 5; |
27 | rsi = 6; |
27 | rsi = 6; |
28 | rdi = 7; |
28 | rdi = 7; |
29 | 29 | ||
30 | MAX_XMM = 5; |
30 | MAX_XMM = 5; |
31 | 31 | ||
32 | je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; |
32 | je = 84H; jne = 85H; jl = 8CH; jge = 8DH; jle = 8EH; jg = 8FH; jb = 82H; |
33 | 33 | ||
34 | sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H; |
34 | sete = 94H; setne = 95H; setl = 9CH; setge = 9DH; setle = 9EH; setg = 9FH; setc = 92H; setnc = 93H; |
35 | 35 | ||
36 | shl = IL.opLSL2; shr = IL.opLSR2; sar = IL.opASR2; ror = IL.opROR2; |
36 | shl = IL.opLSL2; shr = IL.opLSR2; sar = IL.opASR2; ror = IL.opROR2; |
37 | 37 | ||
38 | sCODE = BIN.PICCODE; |
38 | sCODE = BIN.PICCODE; |
39 | sDATA = BIN.PICDATA; |
39 | sDATA = BIN.PICDATA; |
40 | sBSS = BIN.PICBSS; |
40 | sBSS = BIN.PICBSS; |
41 | sIMP = BIN.PICIMP; |
41 | sIMP = BIN.PICIMP; |
42 | 42 | ||
43 | FPR_ERR = 41; |
43 | FPR_ERR = 41; |
44 | 44 | ||
45 | 45 | ||
46 | TYPE |
46 | TYPE |
47 | 47 | ||
48 | COMMAND = IL.COMMAND; |
48 | COMMAND = IL.COMMAND; |
49 | 49 | ||
50 | Number = POINTER TO RECORD (LISTS.ITEM) value: INTEGER END; |
50 | Number = POINTER TO RECORD (LISTS.ITEM) value: INTEGER END; |
51 | 51 | ||
52 | OPRR = PROCEDURE (reg1, reg2: INTEGER); |
52 | OPRR = PROCEDURE (reg1, reg2: INTEGER); |
53 | 53 | ||
54 | 54 | ||
55 | VAR |
55 | VAR |
56 | 56 | ||
57 | R: REG.REGS; |
57 | R: REG.REGS; |
58 | 58 | ||
59 | Numbers: LISTS.LIST; |
59 | Numbers: LISTS.LIST; |
60 | Numbers_Count: INTEGER; |
60 | Numbers_Count: INTEGER; |
61 | Numbers_Offs: INTEGER; |
61 | Numbers_Offs: INTEGER; |
62 | 62 | ||
63 | prog: BIN.PROGRAM; |
63 | prog: BIN.PROGRAM; |
64 | 64 | ||
65 | tcount: INTEGER; |
65 | tcount: INTEGER; |
66 | 66 | ||
67 | dllret, sofinit: INTEGER; |
67 | dllret, sofinit: INTEGER; |
68 | 68 | ||
69 | Win64RegPar: ARRAY 4 OF INTEGER; |
69 | Win64RegPar: ARRAY 4 OF INTEGER; |
70 | SystemVRegPar: ARRAY 6 OF INTEGER; |
70 | SystemVRegPar: ARRAY 6 OF INTEGER; |
71 | 71 | ||
72 | Xmm: ARRAY 1000 OF INTEGER; |
72 | Xmm: ARRAY 1000 OF INTEGER; |
73 | 73 | ||
74 | fname: PATHS.PATH; |
74 | fname: PATHS.PATH; |
75 | 75 | ||
76 | 76 | ||
77 | PROCEDURE OutByte (b: BYTE); |
77 | PROCEDURE OutByte (b: BYTE); |
78 | BEGIN |
78 | BEGIN |
79 | X86.OutByte(b) |
79 | X86.OutByte(b) |
80 | END OutByte; |
80 | END OutByte; |
81 | 81 | ||
82 | 82 | ||
83 | PROCEDURE OutByte2 (a, b: BYTE); |
83 | PROCEDURE OutByte2 (a, b: BYTE); |
84 | BEGIN |
84 | BEGIN |
85 | X86.OutByte(a); |
85 | X86.OutByte(a); |
86 | X86.OutByte(b) |
86 | X86.OutByte(b) |
87 | END OutByte2; |
87 | END OutByte2; |
88 | 88 | ||
89 | 89 | ||
90 | PROCEDURE OutByte3 (a, b, c: BYTE); |
90 | PROCEDURE OutByte3 (a, b, c: BYTE); |
91 | BEGIN |
91 | BEGIN |
92 | X86.OutByte(a); |
92 | X86.OutByte(a); |
93 | X86.OutByte(b); |
93 | X86.OutByte(b); |
94 | X86.OutByte(c) |
94 | X86.OutByte(c) |
95 | END OutByte3; |
95 | END OutByte3; |
96 | 96 | ||
97 | 97 | ||
98 | PROCEDURE OutInt (n: INTEGER); |
98 | PROCEDURE OutInt (n: INTEGER); |
99 | BEGIN |
99 | BEGIN |
100 | X86.OutByte(n MOD 256); |
100 | X86.OutByte(n MOD 256); |
101 | X86.OutByte(UTILS.Byte(n, 1)); |
101 | X86.OutByte(UTILS.Byte(n, 1)); |
102 | X86.OutByte(UTILS.Byte(n, 2)); |
102 | X86.OutByte(UTILS.Byte(n, 2)); |
103 | X86.OutByte(UTILS.Byte(n, 3)) |
103 | X86.OutByte(UTILS.Byte(n, 3)) |
104 | END OutInt; |
104 | END OutInt; |
105 | 105 | ||
106 | 106 | ||
107 | PROCEDURE short (n: INTEGER): INTEGER; |
107 | PROCEDURE short (n: INTEGER): INTEGER; |
108 | RETURN 2 * ORD(X86.isByte(n)) |
108 | RETURN 2 * ORD(X86.isByte(n)) |
109 | END short; |
109 | END short; |
110 | 110 | ||
111 | 111 | ||
112 | PROCEDURE long (n: INTEGER): INTEGER; |
112 | PROCEDURE long (n: INTEGER): INTEGER; |
113 | RETURN 40H * ORD(~X86.isByte(n)) |
113 | RETURN 40H * ORD(~X86.isByte(n)) |
114 | END long; |
114 | END long; |
115 | 115 | ||
116 | 116 | ||
117 | PROCEDURE OutIntByte (n: INTEGER); |
117 | PROCEDURE OutIntByte (n: INTEGER); |
118 | BEGIN |
118 | BEGIN |
119 | IF X86.isByte(n) THEN |
119 | IF X86.isByte(n) THEN |
120 | OutByte(n MOD 256) |
120 | OutByte(n MOD 256) |
121 | ELSE |
121 | ELSE |
122 | OutInt(n) |
122 | OutInt(n) |
123 | END |
123 | END |
124 | END OutIntByte; |
124 | END OutIntByte; |
125 | 125 | ||
126 | 126 | ||
127 | PROCEDURE isLong (n: INTEGER): BOOLEAN; |
127 | PROCEDURE isLong (n: INTEGER): BOOLEAN; |
128 | RETURN (n > UTILS.max32) OR (n < UTILS.min32) |
128 | RETURN (n > UTILS.max32) OR (n < UTILS.min32) |
129 | END isLong; |
129 | END isLong; |
130 | 130 | ||
131 | 131 | ||
132 | PROCEDURE NewNumber (value: INTEGER); |
132 | PROCEDURE NewNumber (value: INTEGER); |
133 | VAR |
133 | VAR |
134 | number: Number; |
134 | number: Number; |
135 | 135 | ||
136 | BEGIN |
136 | BEGIN |
137 | NEW(number); |
137 | NEW(number); |
138 | number.value := value; |
138 | number.value := value; |
139 | LISTS.push(Numbers, number); |
139 | LISTS.push(Numbers, number); |
140 | INC(Numbers_Count) |
140 | INC(Numbers_Count) |
141 | END NewNumber; |
141 | END NewNumber; |
142 | 142 | ||
143 | 143 | ||
144 | PROCEDURE NewLabel (): INTEGER; |
144 | PROCEDURE NewLabel (): INTEGER; |
145 | BEGIN |
145 | BEGIN |
146 | BIN.NewLabel(prog) |
146 | BIN.NewLabel(prog) |
147 | RETURN IL.NewLabel() |
147 | RETURN IL.NewLabel() |
148 | END NewLabel; |
148 | END NewLabel; |
149 | 149 | ||
150 | 150 | ||
151 | PROCEDURE Rex (reg1, reg2: INTEGER); |
151 | PROCEDURE Rex (reg1, reg2: INTEGER); |
152 | BEGIN |
152 | BEGIN |
153 | OutByte(48H + reg1 DIV 8 + 4 * (reg2 DIV 8)) |
153 | OutByte(48H + reg1 DIV 8 + 4 * (reg2 DIV 8)) |
154 | END Rex; |
154 | END Rex; |
155 | 155 | ||
156 | 156 | ||
157 | PROCEDURE lea (reg, offset, section: INTEGER); |
157 | PROCEDURE lea (reg, offset, section: INTEGER); |
158 | BEGIN |
158 | BEGIN |
159 | Rex(0, reg); |
159 | Rex(0, reg); |
160 | OutByte2(8DH, 05H + 8 * (reg MOD 8)); (* lea reg, [rip + offset] *) |
160 | OutByte2(8DH, 05H + 8 * (reg MOD 8)); (* lea reg, [rip + offset] *) |
161 | X86.Reloc(section, offset) |
161 | X86.Reloc(section, offset) |
162 | END lea; |
162 | END lea; |
163 | 163 | ||
164 | 164 | ||
165 | PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *) |
165 | PROCEDURE oprr (op: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *) |
166 | BEGIN |
166 | BEGIN |
167 | Rex(reg1, reg2); |
167 | Rex(reg1, reg2); |
168 | OutByte2(op, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8) |
168 | OutByte2(op, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8) |
169 | END oprr; |
169 | END oprr; |
170 | 170 | ||
171 | 171 | ||
172 | PROCEDURE oprr2 (op1, op2: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *) |
172 | PROCEDURE oprr2 (op1, op2: BYTE; reg1, reg2: INTEGER); (* op reg1, reg2 *) |
173 | BEGIN |
173 | BEGIN |
174 | Rex(reg1, reg2); |
174 | Rex(reg1, reg2); |
175 | OutByte3(op1, op2, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8) |
175 | OutByte3(op1, op2, 0C0H + 8 * (reg2 MOD 8) + reg1 MOD 8) |
176 | END oprr2; |
176 | END oprr2; |
177 | 177 | ||
178 | 178 | ||
179 | PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *) |
179 | PROCEDURE mov (reg1, reg2: INTEGER); (* mov reg1, reg2 *) |
180 | BEGIN |
180 | BEGIN |
181 | oprr(89H, reg1, reg2) |
181 | oprr(89H, reg1, reg2) |
182 | END mov; |
182 | END mov; |
183 | 183 | ||
184 | 184 | ||
185 | PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *) |
185 | PROCEDURE xor (reg1, reg2: INTEGER); (* xor reg1, reg2 *) |
186 | BEGIN |
186 | BEGIN |
187 | oprr(31H, reg1, reg2) |
187 | oprr(31H, reg1, reg2) |
188 | END xor; |
188 | END xor; |
189 | 189 | ||
190 | 190 | ||
191 | PROCEDURE and (reg1, reg2: INTEGER); (* and reg1, reg2 *) |
191 | PROCEDURE and (reg1, reg2: INTEGER); (* and reg1, reg2 *) |
192 | BEGIN |
192 | BEGIN |
193 | oprr(21H, reg1, reg2) |
193 | oprr(21H, reg1, reg2) |
194 | END and; |
194 | END and; |
195 | 195 | ||
196 | 196 | ||
197 | PROCEDURE _or (reg1, reg2: INTEGER); (* or reg1, reg2 *) |
197 | PROCEDURE _or (reg1, reg2: INTEGER); (* or reg1, reg2 *) |
198 | BEGIN |
198 | BEGIN |
199 | oprr(09H, reg1, reg2) |
199 | oprr(09H, reg1, reg2) |
200 | END _or; |
200 | END _or; |
201 | 201 | ||
202 | 202 | ||
203 | PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *) |
203 | PROCEDURE add (reg1, reg2: INTEGER); (* add reg1, reg2 *) |
204 | BEGIN |
204 | BEGIN |
205 | oprr(01H, reg1, reg2) |
205 | oprr(01H, reg1, reg2) |
206 | END add; |
206 | END add; |
207 | 207 | ||
208 | 208 | ||
209 | PROCEDURE sub (reg1, reg2: INTEGER); (* sub reg1, reg2 *) |
209 | PROCEDURE sub (reg1, reg2: INTEGER); (* sub reg1, reg2 *) |
210 | BEGIN |
210 | BEGIN |
211 | oprr(29H, reg1, reg2) |
211 | oprr(29H, reg1, reg2) |
212 | END sub; |
212 | END sub; |
213 | 213 | ||
214 | 214 | ||
215 | PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *) |
215 | PROCEDURE xchg (reg1, reg2: INTEGER); (* xchg reg1, reg2 *) |
216 | BEGIN |
216 | BEGIN |
217 | IF rax IN {reg1, reg2} THEN |
217 | IF rax IN {reg1, reg2} THEN |
218 | Rex(reg1 + reg2, 0); |
218 | Rex(reg1 + reg2, 0); |
219 | OutByte(90H + (reg1 + reg2) MOD 8) |
219 | OutByte(90H + (reg1 + reg2) MOD 8) |
220 | ELSE |
220 | ELSE |
221 | oprr(87H, reg1, reg2) |
221 | oprr(87H, reg1, reg2) |
222 | END |
222 | END |
223 | END xchg; |
223 | END xchg; |
224 | 224 | ||
225 | 225 | ||
226 | PROCEDURE cmprr (reg1, reg2: INTEGER); (* cmp reg1, reg2 *) |
226 | PROCEDURE cmprr (reg1, reg2: INTEGER); (* cmp reg1, reg2 *) |
227 | BEGIN |
227 | BEGIN |
228 | oprr(39H, reg1, reg2) |
228 | oprr(39H, reg1, reg2) |
229 | END cmprr; |
229 | END cmprr; |
230 | 230 | ||
231 | 231 | ||
232 | PROCEDURE pop (reg: INTEGER); (* pop reg *) |
232 | PROCEDURE pop (reg: INTEGER); (* pop reg *) |
233 | BEGIN |
233 | BEGIN |
234 | IF reg >= 8 THEN |
234 | IF reg >= 8 THEN |
235 | OutByte(41H) |
235 | OutByte(41H) |
236 | END; |
236 | END; |
237 | OutByte(58H + reg MOD 8) |
237 | OutByte(58H + reg MOD 8) |
238 | END pop; |
238 | END pop; |
239 | 239 | ||
240 | 240 | ||
241 | PROCEDURE push (reg: INTEGER); (* push reg *) |
241 | PROCEDURE push (reg: INTEGER); (* push reg *) |
242 | BEGIN |
242 | BEGIN |
243 | IF reg >= 8 THEN |
243 | IF reg >= 8 THEN |
244 | OutByte(41H) |
244 | OutByte(41H) |
245 | END; |
245 | END; |
246 | OutByte(50H + reg MOD 8) |
246 | OutByte(50H + reg MOD 8) |
247 | END push; |
247 | END push; |
248 | 248 | ||
249 | 249 | ||
250 | PROCEDURE decr (reg: INTEGER); |
250 | PROCEDURE decr (reg: INTEGER); |
251 | BEGIN |
251 | BEGIN |
252 | Rex(reg, 0); |
252 | Rex(reg, 0); |
253 | OutByte2(0FFH, 0C8H + reg MOD 8) (* dec reg1 *) |
253 | OutByte2(0FFH, 0C8H + reg MOD 8) (* dec reg1 *) |
254 | END decr; |
254 | END decr; |
255 | 255 | ||
256 | 256 | ||
257 | PROCEDURE incr (reg: INTEGER); |
257 | PROCEDURE incr (reg: INTEGER); |
258 | BEGIN |
258 | BEGIN |
259 | Rex(reg, 0); |
259 | Rex(reg, 0); |
260 | OutByte2(0FFH, 0C0H + reg MOD 8) (* inc reg1 *) |
260 | OutByte2(0FFH, 0C0H + reg MOD 8) (* inc reg1 *) |
261 | END incr; |
261 | END incr; |
262 | 262 | ||
263 | 263 | ||
264 | PROCEDURE drop; |
264 | PROCEDURE drop; |
265 | BEGIN |
265 | BEGIN |
266 | REG.Drop(R) |
266 | REG.Drop(R) |
267 | END drop; |
267 | END drop; |
268 | 268 | ||
269 | 269 | ||
270 | PROCEDURE GetAnyReg (): INTEGER; |
270 | PROCEDURE GetAnyReg (): INTEGER; |
271 | RETURN REG.GetAnyReg(R) |
271 | RETURN REG.GetAnyReg(R) |
272 | END GetAnyReg; |
272 | END GetAnyReg; |
273 | 273 | ||
274 | - | ||
275 | PROCEDURE GetVarReg (offs: INTEGER): INTEGER; |
- | |
276 | RETURN REG.GetVarReg(R, offs) |
- | |
277 | END GetVarReg; |
- | |
278 | - | ||
279 | 274 | ||
280 | PROCEDURE callimp (label: INTEGER); |
275 | PROCEDURE callimp (label: INTEGER); |
281 | BEGIN |
276 | BEGIN |
282 | OutByte2(0FFH, 15H); (* call qword[rip + label + IMP] *) |
277 | OutByte2(0FFH, 15H); (* call qword[rip + label + IMP] *) |
283 | X86.Reloc(sIMP, label) |
278 | X86.Reloc(sIMP, label) |
284 | END callimp; |
279 | END callimp; |
285 | 280 | ||
286 | 281 | ||
287 | PROCEDURE pushDA (offs: INTEGER); |
282 | PROCEDURE pushDA (offs: INTEGER); |
288 | VAR |
283 | VAR |
289 | reg: INTEGER; |
284 | reg: INTEGER; |
290 | 285 | ||
291 | BEGIN |
286 | BEGIN |
292 | reg := GetAnyReg(); |
287 | reg := GetAnyReg(); |
293 | lea(reg, offs, sDATA); |
288 | lea(reg, offs, sDATA); |
294 | push(reg); |
289 | push(reg); |
295 | drop |
290 | drop |
296 | END pushDA; |
291 | END pushDA; |
297 | 292 | ||
298 | 293 | ||
299 | PROCEDURE CallRTL (proc: INTEGER); |
294 | PROCEDURE CallRTL (proc: INTEGER); |
300 | VAR |
295 | VAR |
301 | label: INTEGER; |
296 | label: INTEGER; |
302 | 297 | ||
303 | BEGIN |
298 | BEGIN |
304 | REG.Store(R); |
- | |
305 | label := IL.codes.rtl[proc]; |
299 | label := IL.codes.rtl[proc]; |
306 | IF label < 0 THEN |
300 | IF label < 0 THEN |
307 | callimp(-label) |
301 | callimp(-label) |
308 | ELSE |
302 | ELSE |
309 | X86.call(label) |
303 | X86.call(label) |
310 | END; |
304 | END |
311 | REG.Restore(R) |
- | |
312 | END CallRTL; |
305 | END CallRTL; |
313 | 306 | ||
314 | 307 | ||
315 | PROCEDURE UnOp (VAR reg: INTEGER); |
308 | PROCEDURE UnOp (VAR reg: INTEGER); |
316 | BEGIN |
309 | BEGIN |
317 | REG.UnOp(R, reg) |
310 | REG.UnOp(R, reg) |
318 | END UnOp; |
311 | END UnOp; |
319 | 312 | ||
320 | 313 | ||
321 | PROCEDURE BinOp (VAR reg1, reg2: INTEGER); |
314 | PROCEDURE BinOp (VAR reg1, reg2: INTEGER); |
322 | BEGIN |
315 | BEGIN |
323 | REG.BinOp(R, reg1, reg2) |
316 | REG.BinOp(R, reg1, reg2) |
324 | END BinOp; |
317 | END BinOp; |
325 | 318 | ||
326 | 319 | ||
327 | PROCEDURE PushAll (NumberOfParameters: INTEGER); |
320 | PROCEDURE PushAll (NumberOfParameters: INTEGER); |
328 | BEGIN |
321 | BEGIN |
329 | REG.PushAll(R); |
322 | REG.PushAll(R); |
330 | DEC(R.pushed, NumberOfParameters) |
323 | DEC(R.pushed, NumberOfParameters) |
331 | END PushAll; |
324 | END PushAll; |
332 | 325 | ||
333 | 326 | ||
334 | PROCEDURE movabs (reg, n: INTEGER); |
327 | PROCEDURE movabs (reg, n: INTEGER); |
335 | VAR |
328 | VAR |
336 | i: INTEGER; |
329 | i: INTEGER; |
337 | 330 | ||
338 | BEGIN |
331 | BEGIN |
339 | Rex(reg, 0); |
332 | Rex(reg, 0); |
340 | OutByte(0B8H + reg MOD 8); (* movabs reg, n *) |
333 | OutByte(0B8H + reg MOD 8); (* movabs reg, n *) |
341 | FOR i := 0 TO 7 DO |
334 | FOR i := 0 TO 7 DO |
342 | OutByte(UTILS.Byte(n, i)) |
335 | OutByte(UTILS.Byte(n, i)) |
343 | END |
336 | END |
344 | END movabs; |
337 | END movabs; |
345 | 338 | ||
346 | 339 | ||
347 | PROCEDURE movrc (reg, n: INTEGER); (* mov reg, n *) |
340 | PROCEDURE movrc (reg, n: INTEGER); (* mov reg, n *) |
348 | BEGIN |
341 | BEGIN |
349 | IF isLong(n) THEN |
342 | IF isLong(n) THEN |
350 | movabs(reg, n) |
343 | movabs(reg, n) |
351 | ELSIF n = 0 THEN |
344 | ELSIF n = 0 THEN |
352 | xor(reg, reg) |
345 | xor(reg, reg) |
353 | ELSE |
346 | ELSE |
354 | Rex(reg, 0); |
347 | Rex(reg, 0); |
355 | OutByte2(0C7H, 0C0H + reg MOD 8); |
348 | OutByte2(0C7H, 0C0H + reg MOD 8); |
356 | OutInt(n) |
349 | OutInt(n) |
357 | END |
350 | END |
358 | END movrc; |
351 | END movrc; |
359 | 352 | ||
360 | 353 | ||
361 | PROCEDURE test (reg: INTEGER); (* test reg, reg *) |
354 | PROCEDURE test (reg: INTEGER); (* test reg, reg *) |
362 | BEGIN |
355 | BEGIN |
363 | oprr(85H, reg, reg) |
356 | oprr(85H, reg, reg) |
364 | END test; |
357 | END test; |
365 | 358 | ||
366 | 359 | ||
367 | PROCEDURE oprlongc (reg, n: INTEGER; oprr: OPRR); |
360 | PROCEDURE oprlongc (reg, n: INTEGER; oprr: OPRR); |
368 | VAR |
361 | VAR |
369 | reg2: INTEGER; |
362 | reg2: INTEGER; |
370 | 363 | ||
371 | BEGIN |
364 | BEGIN |
372 | reg2 := GetAnyReg(); |
365 | reg2 := GetAnyReg(); |
373 | ASSERT(reg2 # reg); |
366 | ASSERT(reg2 # reg); |
374 | movabs(reg2, n); |
367 | movabs(reg2, n); |
375 | oprr(reg, reg2); |
368 | oprr(reg, reg2); |
376 | drop |
369 | drop |
377 | END oprlongc; |
370 | END oprlongc; |
378 | 371 | ||
379 | 372 | ||
380 | PROCEDURE oprc (op, reg, n: INTEGER; oprr: OPRR); |
373 | PROCEDURE oprc (op, reg, n: INTEGER; oprr: OPRR); |
381 | BEGIN |
374 | BEGIN |
382 | IF isLong(n) THEN |
375 | IF isLong(n) THEN |
383 | oprlongc(reg, n, oprr) |
376 | oprlongc(reg, n, oprr) |
384 | ELSE |
377 | ELSE |
385 | Rex(reg, 0); |
378 | Rex(reg, 0); |
386 | X86.oprc(op, reg, n) |
379 | X86.oprc(op, reg, n) |
387 | END |
380 | END |
388 | END oprc; |
381 | END oprc; |
389 | 382 | ||
390 | 383 | ||
391 | PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *) |
384 | PROCEDURE cmprc (reg, n: INTEGER); (* cmp reg, n *) |
392 | BEGIN |
385 | BEGIN |
393 | IF n = 0 THEN |
386 | IF n = 0 THEN |
394 | test(reg) |
387 | test(reg) |
395 | ELSE |
388 | ELSE |
396 | oprc(0F8H, reg, n, cmprr) |
389 | oprc(0F8H, reg, n, cmprr) |
397 | END |
390 | END |
398 | END cmprc; |
391 | END cmprc; |
399 | 392 | ||
400 | 393 | ||
401 | PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *) |
394 | PROCEDURE addrc (reg, n: INTEGER); (* add reg, n *) |
402 | BEGIN |
395 | BEGIN |
403 | oprc(0C0H, reg, n, add) |
396 | oprc(0C0H, reg, n, add) |
404 | END addrc; |
397 | END addrc; |
405 | 398 | ||
406 | 399 | ||
407 | PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *) |
400 | PROCEDURE subrc (reg, n: INTEGER); (* sub reg, n *) |
408 | BEGIN |
401 | BEGIN |
409 | oprc(0E8H, reg, n, sub) |
402 | oprc(0E8H, reg, n, sub) |
410 | END subrc; |
403 | END subrc; |
411 | 404 | ||
412 | 405 | ||
413 | PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *) |
406 | PROCEDURE andrc (reg, n: INTEGER); (* and reg, n *) |
414 | BEGIN |
407 | BEGIN |
415 | oprc(0E0H, reg, n, and) |
408 | oprc(0E0H, reg, n, and) |
416 | END andrc; |
409 | END andrc; |
417 | 410 | ||
418 | 411 | ||
419 | PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *) |
412 | PROCEDURE orrc (reg, n: INTEGER); (* or reg, n *) |
420 | BEGIN |
413 | BEGIN |
421 | oprc(0C8H, reg, n, _or) |
414 | oprc(0C8H, reg, n, _or) |
422 | END orrc; |
415 | END orrc; |
423 | 416 | ||
424 | 417 | ||
425 | PROCEDURE xorrc (reg, n: INTEGER); (* xor reg, n *) |
418 | PROCEDURE xorrc (reg, n: INTEGER); (* xor reg, n *) |
426 | BEGIN |
419 | BEGIN |
427 | oprc(0F0H, reg, n, xor) |
420 | oprc(0F0H, reg, n, xor) |
428 | END xorrc; |
421 | END xorrc; |
429 | 422 | ||
430 | 423 | ||
431 | PROCEDURE pushc (n: INTEGER); |
424 | PROCEDURE pushc (n: INTEGER); |
432 | VAR |
425 | VAR |
433 | reg2: INTEGER; |
426 | reg2: INTEGER; |
434 | 427 | ||
435 | BEGIN |
428 | BEGIN |
436 | IF isLong(n) THEN |
429 | IF isLong(n) THEN |
437 | reg2 := GetAnyReg(); |
430 | reg2 := GetAnyReg(); |
438 | movabs(reg2, n); |
431 | movabs(reg2, n); |
439 | push(reg2); |
432 | push(reg2); |
440 | drop |
433 | drop |
441 | ELSE |
434 | ELSE |
442 | X86.pushc(n) |
435 | X86.pushc(n) |
443 | END |
436 | END |
444 | END pushc; |
437 | END pushc; |
445 | 438 | ||
446 | 439 | ||
447 | PROCEDURE not (reg: INTEGER); (* not reg *) |
440 | PROCEDURE not (reg: INTEGER); (* not reg *) |
448 | BEGIN |
441 | BEGIN |
449 | Rex(reg, 0); |
442 | Rex(reg, 0); |
450 | OutByte2(0F7H, 0D0H + reg MOD 8) |
443 | OutByte2(0F7H, 0D0H + reg MOD 8) |
451 | END not; |
444 | END not; |
452 | 445 | ||
453 | 446 | ||
454 | PROCEDURE neg (reg: INTEGER); (* neg reg *) |
447 | PROCEDURE neg (reg: INTEGER); (* neg reg *) |
455 | BEGIN |
448 | BEGIN |
456 | Rex(reg, 0); |
449 | Rex(reg, 0); |
457 | OutByte2(0F7H, 0D8H + reg MOD 8) |
450 | OutByte2(0F7H, 0D8H + reg MOD 8) |
458 | END neg; |
451 | END neg; |
459 | 452 | ||
460 | 453 | ||
461 | PROCEDURE movzx (reg1, reg2, offs: INTEGER; word: BOOLEAN); (* movzx reg1, byte/word[reg2 + offs] *) |
454 | PROCEDURE movzx (reg1, reg2, offs: INTEGER; word: BOOLEAN); (* movzx reg1, byte/word[reg2 + offs] *) |
462 | BEGIN |
455 | BEGIN |
463 | Rex(reg2, reg1); |
456 | Rex(reg2, reg1); |
464 | X86.movzx(reg1, reg2, offs, word) |
457 | X86.movzx(reg1, reg2, offs, word) |
465 | END movzx; |
458 | END movzx; |
466 | 459 | ||
467 | 460 | ||
468 | PROCEDURE movmr32 (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2_32 *) |
461 | PROCEDURE movmr32 (reg1, offs, reg2: INTEGER); (* mov dword[reg1+offs], reg2_32 *) |
469 | BEGIN |
462 | BEGIN |
470 | X86._movrm(reg2, reg1, offs, 32, TRUE) |
463 | X86._movrm(reg2, reg1, offs, 32, TRUE) |
471 | END movmr32; |
464 | END movmr32; |
472 | 465 | ||
473 | 466 | ||
474 | PROCEDURE movrm32 (reg1, reg2, offs: INTEGER); (* mov reg1_32, dword[reg2+offs] *) |
467 | PROCEDURE movrm32 (reg1, reg2, offs: INTEGER); (* mov reg1_32, dword[reg2+offs] *) |
475 | BEGIN |
468 | BEGIN |
476 | X86._movrm(reg1, reg2, offs, 32, FALSE) |
469 | X86._movrm(reg1, reg2, offs, 32, FALSE) |
477 | END movrm32; |
470 | END movrm32; |
478 | 471 | ||
479 | 472 | ||
480 | PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov qword[reg1+offs], reg2 *) |
473 | PROCEDURE movmr (reg1, offs, reg2: INTEGER); (* mov qword[reg1+offs], reg2 *) |
481 | BEGIN |
474 | BEGIN |
482 | X86._movrm(reg2, reg1, offs, 64, TRUE) |
475 | X86._movrm(reg2, reg1, offs, 64, TRUE) |
483 | END movmr; |
476 | END movmr; |
484 | 477 | ||
485 | 478 | ||
486 | PROCEDURE movrm (reg1, reg2, offs: INTEGER); (* mov reg1, qword[reg2+offs] *) |
479 | PROCEDURE movrm (reg1, reg2, offs: INTEGER); (* mov reg1, qword[reg2+offs] *) |
487 | BEGIN |
480 | BEGIN |
488 | X86._movrm(reg1, reg2, offs, 64, FALSE) |
481 | X86._movrm(reg1, reg2, offs, 64, FALSE) |
489 | END movrm; |
482 | END movrm; |
490 | 483 | ||
491 | 484 | ||
492 | PROCEDURE comisd (xmm1, xmm2: INTEGER); (* comisd xmm1, xmm2 *) |
485 | PROCEDURE comisd (xmm1, xmm2: INTEGER); (* comisd xmm1, xmm2 *) |
493 | BEGIN |
486 | BEGIN |
494 | OutByte(66H); |
487 | OutByte(66H); |
495 | IF (xmm1 >= 8) OR (xmm2 >= 8) THEN |
488 | IF (xmm1 >= 8) OR (xmm2 >= 8) THEN |
496 | OutByte(40H + (xmm1 DIV 8) * 4 + xmm2 DIV 8) |
489 | OutByte(40H + (xmm1 DIV 8) * 4 + xmm2 DIV 8) |
497 | END; |
490 | END; |
498 | OutByte3(0FH, 2FH, 0C0H + (xmm1 MOD 8) * 8 + xmm2 MOD 8) |
491 | OutByte3(0FH, 2FH, 0C0H + (xmm1 MOD 8) * 8 + xmm2 MOD 8) |
499 | END comisd; |
492 | END comisd; |
500 | 493 | ||
501 | 494 | ||
502 | PROCEDURE _movsdrm (xmm, reg, offs: INTEGER; mr: BOOLEAN); |
495 | PROCEDURE _movsdrm (xmm, reg, offs: INTEGER; mr: BOOLEAN); |
503 | VAR |
496 | VAR |
504 | b: BYTE; |
497 | b: BYTE; |
505 | 498 | ||
506 | BEGIN |
499 | BEGIN |
507 | OutByte(0F2H); |
500 | OutByte(0F2H); |
508 | IF (xmm >= 8) OR (reg >= 8) THEN |
501 | IF (xmm >= 8) OR (reg >= 8) THEN |
509 | OutByte(40H + (xmm DIV 8) * 4 + reg DIV 8) |
502 | OutByte(40H + (xmm DIV 8) * 4 + reg DIV 8) |
510 | END; |
503 | END; |
511 | OutByte2(0FH, 10H + ORD(mr)); |
504 | OutByte2(0FH, 10H + ORD(mr)); |
512 | IF (offs = 0) & (reg # rbp) THEN |
505 | IF (offs = 0) & (reg # rbp) THEN |
513 | b := 0 |
506 | b := 0 |
514 | ELSE |
507 | ELSE |
515 | b := 40H + long(offs) |
508 | b := 40H + long(offs) |
516 | END; |
509 | END; |
517 | OutByte(b + (xmm MOD 8) * 8 + reg MOD 8); |
510 | OutByte(b + (xmm MOD 8) * 8 + reg MOD 8); |
518 | IF reg = rsp THEN |
511 | IF reg = rsp THEN |
519 | OutByte(24H) |
512 | OutByte(24H) |
520 | END; |
513 | END; |
521 | IF b # 0 THEN |
514 | IF b # 0 THEN |
522 | OutIntByte(offs) |
515 | OutIntByte(offs) |
523 | END |
516 | END |
524 | END _movsdrm; |
517 | END _movsdrm; |
525 | 518 | ||
526 | 519 | ||
527 | PROCEDURE movsdrm (xmm, reg, offs: INTEGER); (* movsd xmm, qword[reg+offs] *) |
520 | PROCEDURE movsdrm (xmm, reg, offs: INTEGER); (* movsd xmm, qword[reg+offs] *) |
528 | BEGIN |
521 | BEGIN |
529 | _movsdrm(xmm, reg, offs, FALSE) |
522 | _movsdrm(xmm, reg, offs, FALSE) |
530 | END movsdrm; |
523 | END movsdrm; |
531 | 524 | ||
532 | 525 | ||
533 | PROCEDURE movsdmr (reg, offs, xmm: INTEGER); (* movsd qword[reg+offs], xmm *) |
526 | PROCEDURE movsdmr (reg, offs, xmm: INTEGER); (* movsd qword[reg+offs], xmm *) |
534 | BEGIN |
527 | BEGIN |
535 | _movsdrm(xmm, reg, offs, TRUE) |
528 | _movsdrm(xmm, reg, offs, TRUE) |
536 | END movsdmr; |
529 | END movsdmr; |
537 | 530 | ||
538 | 531 | ||
539 | PROCEDURE opxx (op, xmm1, xmm2: INTEGER); |
532 | PROCEDURE opxx (op, xmm1, xmm2: INTEGER); |
540 | BEGIN |
533 | BEGIN |
541 | OutByte(0F2H); |
534 | OutByte(0F2H); |
542 | IF (xmm1 >= 8) OR (xmm2 >= 8) THEN |
535 | IF (xmm1 >= 8) OR (xmm2 >= 8) THEN |
543 | OutByte(40H + (xmm1 DIV 8) * 4 + xmm2 DIV 8) |
536 | OutByte(40H + (xmm1 DIV 8) * 4 + xmm2 DIV 8) |
544 | END; |
537 | END; |
545 | OutByte3(0FH, op, 0C0H + (xmm1 MOD 8) * 8 + xmm2 MOD 8) |
538 | OutByte3(0FH, op, 0C0H + (xmm1 MOD 8) * 8 + xmm2 MOD 8) |
546 | END opxx; |
539 | END opxx; |
547 | 540 | ||
548 | 541 | ||
549 | PROCEDURE jcc (cc, label: INTEGER); (* jcc label *) |
542 | PROCEDURE jcc (cc, label: INTEGER); (* jcc label *) |
550 | BEGIN |
543 | BEGIN |
551 | X86.jcc(cc, label) |
544 | X86.jcc(cc, label) |
552 | END jcc; |
545 | END jcc; |
553 | 546 | ||
554 | 547 | ||
555 | PROCEDURE shiftrc (op, reg, n: INTEGER); |
548 | PROCEDURE shiftrc (op, reg, n: INTEGER); |
556 | BEGIN |
549 | BEGIN |
557 | Rex(reg, 0); |
550 | Rex(reg, 0); |
558 | IF n = 1 THEN |
551 | IF n = 1 THEN |
559 | OutByte(0D1H) |
552 | OutByte(0D1H) |
560 | ELSE |
553 | ELSE |
561 | OutByte(0C1H) |
554 | OutByte(0C1H) |
562 | END; |
555 | END; |
563 | X86.shift(op, reg MOD 8); |
556 | X86.shift(op, reg MOD 8); |
564 | IF n # 1 THEN |
557 | IF n # 1 THEN |
565 | OutByte(n) |
558 | OutByte(n) |
566 | END |
559 | END |
567 | END shiftrc; |
560 | END shiftrc; |
568 | 561 | ||
569 | - | ||
570 | PROCEDURE getVar (variables: LISTS.LIST; offset: INTEGER): IL.LOCALVAR; |
- | |
571 | VAR |
- | |
572 | cur: IL.LOCALVAR; |
- | |
573 | - | ||
574 | BEGIN |
- | |
575 | cur := variables.first(IL.LOCALVAR); |
- | |
576 | WHILE (cur # NIL) & (cur.offset # offset) DO |
- | |
577 | cur := cur.next(IL.LOCALVAR) |
- | |
578 | END |
- | |
579 | - | ||
580 | RETURN cur |
- | |
581 | END getVar; |
- | |
582 | - | ||
583 | - | ||
584 | PROCEDURE allocReg (cmd: COMMAND); |
- | |
585 | VAR |
- | |
586 | leave: BOOLEAN; |
- | |
587 | leaf: BOOLEAN; |
- | |
588 | cur: COMMAND; |
- | |
589 | variables: LISTS.LIST; |
- | |
590 | lvar, rvar: IL.LOCALVAR; |
- | |
591 | reg: INTEGER; |
- | |
592 | max: INTEGER; |
- | |
593 | loop: INTEGER; |
- | |
594 | - | ||
595 | BEGIN |
- | |
596 | loop := 1; |
- | |
597 | variables := cmd.variables; |
- | |
598 | leave := FALSE; |
- | |
599 | leaf := TRUE; |
- | |
600 | - | ||
601 | cur := cmd.next(COMMAND); |
- | |
602 | REPEAT |
- | |
603 | CASE cur.opcode OF |
- | |
604 | |IL.opLLOAD64, |
- | |
605 | IL.opLLOAD8, |
- | |
606 | IL.opLLOAD16, |
- | |
607 | IL.opLLOAD32, |
- | |
608 | IL.opLLOAD64_PARAM, |
- | |
609 | IL.opLLOAD32_PARAM, |
- | |
610 | IL.opLADR_SAVE, |
- | |
611 | IL.opLADR_INC, |
- | |
612 | IL.opLADR_DEC, |
- | |
613 | IL.opLADR_INCB, |
- | |
614 | IL.opLADR_DECB, |
- | |
615 | IL.opLADR_INCL, |
- | |
616 | IL.opLADR_EXCL, |
- | |
617 | IL.opLADR_UNPK: |
- | |
618 | lvar := getVar(variables, cur.param2); |
- | |
619 | IF (lvar # NIL) & (lvar.count # -1) THEN |
- | |
620 | INC(lvar.count, loop) |
- | |
621 | END |
- | |
622 | - | ||
623 | |IL.opLADR_SAVEC, |
- | |
624 | IL.opLADR_INCC, |
- | |
625 | IL.opLADR_INCCB, |
- | |
626 | IL.opLADR_DECCB, |
- | |
627 | IL.opLADR_INCLC, |
- | |
628 | IL.opLADR_EXCLC: |
- | |
629 | lvar := getVar(variables, cur.param1); |
- | |
630 | IF (lvar # NIL) & (lvar.count # -1) THEN |
- | |
631 | INC(lvar.count, loop) |
- | |
632 | END |
- | |
633 | - | ||
634 | |IL.opLADR: |
- | |
635 | lvar := getVar(variables, cur.param2); |
- | |
636 | IF (lvar # NIL) & (lvar.count # -1) THEN |
- | |
637 | lvar.count := -1 |
- | |
638 | END |
- | |
639 | - | ||
640 | |IL.opLOOP: |
- | |
641 | INC(loop, 10) |
- | |
642 | - | ||
643 | |IL.opENDLOOP: |
- | |
644 | DEC(loop, 10) |
- | |
645 | - | ||
646 | |IL.opLEAVE, |
- | |
647 | IL.opLEAVER, |
- | |
648 | IL.opLEAVEF: |
- | |
649 | leave := TRUE |
- | |
650 | - | ||
651 | |IL.opCALL, IL.opCALLP, IL.opCALLI, |
- | |
652 | IL.opWIN64CALL, IL.opWIN64CALLP, IL.opWIN64CALLI, |
- | |
653 | IL.opSYSVCALL, IL.opSYSVCALLP, IL.opSYSVCALLI, |
- | |
654 | - | ||
655 | IL.opSAVES, IL.opRSET, IL.opRSETR, |
- | |
656 | IL.opRSETL, IL.opRSET1, |
- | |
657 | IL.opEQS .. IL.opGES, |
- | |
658 | IL.opEQSW .. IL.opGESW, |
- | |
659 | IL.opCOPY, IL.opMOVE, IL.opCOPYA, |
- | |
660 | IL.opCOPYS, IL.opROT, |
- | |
661 | IL.opNEW, IL.opDISP, IL.opISREC, |
- | |
662 | IL.opIS, IL.opTYPEGR, IL.opTYPEGP, |
- | |
663 | IL.opTYPEGD, IL.opCASET, IL.opDIV, |
- | |
664 | IL.opDIVL, IL.opMOD, |
- | |
665 | IL.opMODL, IL.opLENGTH, IL.opLENGTHW: |
- | |
666 | leaf := FALSE |
- | |
667 | - | ||
668 | |IL.opDIVR, IL.opMODR: |
- | |
669 | leaf := UTILS.Log2(cur.param2) >= 0 |
- | |
670 | - | ||
671 | ELSE |
- | |
672 | - | ||
673 | END; |
- | |
674 | cur := cur.next(COMMAND) |
- | |
675 | UNTIL leave OR ~leaf; |
- | |
676 | - | ||
677 | IF leaf THEN |
- | |
678 | REPEAT |
- | |
679 | reg := -1; |
- | |
680 | max := -1; |
- | |
681 | rvar := NIL; |
- | |
682 | lvar := variables.first(IL.LOCALVAR); |
- | |
683 | WHILE lvar # NIL DO |
- | |
684 | IF lvar.count > max THEN |
- | |
685 | max := lvar.count; |
- | |
686 | rvar := lvar |
- | |
687 | END; |
- | |
688 | lvar := lvar.next(IL.LOCALVAR) |
- | |
689 | END; |
- | |
690 | - | ||
691 | IF rvar # NIL THEN |
- | |
692 | reg := REG.GetAnyVarReg(R); |
- | |
693 | IF reg # -1 THEN |
- | |
694 | REG.Lock(R, reg, rvar.offset, rvar.size); |
- | |
695 | REG.Load(R, reg); |
- | |
696 | rvar.count := -1 |
- | |
697 | END |
- | |
698 | END |
- | |
699 | - | ||
700 | UNTIL (rvar = NIL) OR (reg = -1) |
- | |
701 | END |
- | |
702 | - | ||
703 | END allocReg; |
- | |
704 | - | ||
705 | 562 | ||
706 | PROCEDURE GetRegA; |
563 | PROCEDURE GetRegA; |
707 | BEGIN |
564 | BEGIN |
708 | ASSERT(REG.GetReg(R, rax)) |
565 | ASSERT(REG.GetReg(R, rax)) |
709 | END GetRegA; |
566 | END GetRegA; |
710 | 567 | ||
711 | 568 | ||
712 | PROCEDURE Win64Passing (params: INTEGER); |
569 | PROCEDURE Win64Passing (params: INTEGER); |
713 | VAR |
570 | VAR |
714 | n, i: INTEGER; |
571 | n, i: INTEGER; |
715 | 572 | ||
716 | BEGIN |
573 | BEGIN |
717 | n := params MOD 32; |
574 | n := params MOD 32; |
718 | params := params DIV 32; |
575 | params := params DIV 32; |
719 | FOR i := 0 TO n - 1 DO |
576 | FOR i := 0 TO n - 1 DO |
720 | IF i IN BITS(params) THEN |
577 | IF i IN BITS(params) THEN |
721 | movsdrm(i, rsp, i * 8) |
578 | movsdrm(i, rsp, i * 8) |
722 | ELSE |
579 | ELSE |
723 | movrm(Win64RegPar[i], rsp, i * 8) |
580 | movrm(Win64RegPar[i], rsp, i * 8) |
724 | END |
581 | END |
725 | END |
582 | END |
726 | END Win64Passing; |
583 | END Win64Passing; |
727 | 584 | ||
728 | 585 | ||
729 | PROCEDURE SysVPassing (params: INTEGER); |
586 | PROCEDURE SysVPassing (params: INTEGER); |
730 | VAR |
587 | VAR |
731 | n, i, s, p, ofs: INTEGER; |
588 | n, i, s, p, ofs: INTEGER; |
732 | i_count, f_count: INTEGER; |
589 | i_count, f_count: INTEGER; |
733 | reg: BOOLEAN; |
590 | reg: BOOLEAN; |
734 | 591 | ||
735 | BEGIN |
592 | BEGIN |
736 | ASSERT(r10 IN R.regs); |
593 | ASSERT(r11 IN R.regs); |
737 | n := params MOD 32; |
594 | n := params MOD 32; |
738 | params := params DIV 32; |
595 | params := params DIV 32; |
739 | s := 0; |
596 | s := 0; |
740 | 597 | ||
741 | i_count := 0; |
598 | i_count := 0; |
742 | f_count := 0; |
599 | f_count := 0; |
743 | FOR i := 0 TO n - 1 DO |
600 | FOR i := 0 TO n - 1 DO |
744 | IF i IN BITS(params) THEN |
601 | IF i IN BITS(params) THEN |
745 | INC(f_count) |
602 | INC(f_count) |
746 | ELSE |
603 | ELSE |
747 | INC(i_count) |
604 | INC(i_count) |
748 | END |
605 | END |
749 | END; |
606 | END; |
750 | 607 | ||
751 | s := MAX(0, f_count - 8) + MAX(0, i_count - 6); |
608 | s := MAX(0, f_count - 8) + MAX(0, i_count - 6); |
752 | p := 0; |
609 | p := 0; |
753 | 610 | ||
754 | subrc(rsp, s * 8); |
611 | subrc(rsp, s * 8); |
755 | 612 | ||
756 | i_count := 0; |
613 | i_count := 0; |
757 | f_count := 0; |
614 | f_count := 0; |
758 | FOR i := 0 TO n - 1 DO |
615 | FOR i := 0 TO n - 1 DO |
759 | ofs := (i + s) * 8; |
616 | ofs := (i + s) * 8; |
760 | IF i IN BITS(params) THEN |
617 | IF i IN BITS(params) THEN |
761 | reg := f_count <= 7; |
618 | reg := f_count <= 7; |
762 | IF reg THEN |
619 | IF reg THEN |
763 | movsdrm(f_count, rsp, ofs); |
620 | movsdrm(f_count, rsp, ofs); |
764 | INC(f_count) |
621 | INC(f_count) |
765 | END |
622 | END |
766 | ELSE |
623 | ELSE |
767 | reg := i_count <= 5; |
624 | reg := i_count <= 5; |
768 | IF reg THEN |
625 | IF reg THEN |
769 | movrm(SystemVRegPar[i_count], rsp, ofs); |
626 | movrm(SystemVRegPar[i_count], rsp, ofs); |
770 | INC(i_count) |
627 | INC(i_count) |
771 | END |
628 | END |
772 | END; |
629 | END; |
773 | 630 | ||
774 | IF ~reg THEN |
631 | IF ~reg THEN |
775 | movrm(r10, rsp, ofs); |
632 | movrm(r11, rsp, ofs); |
776 | movmr(rsp, p, r10); |
633 | movmr(rsp, p, r11); |
777 | INC(p, 8) |
634 | INC(p, 8) |
778 | END |
635 | END |
779 | END |
636 | END |
780 | END SysVPassing; |
637 | END SysVPassing; |
781 | 638 | ||
782 | 639 | ||
783 | PROCEDURE fcmp (op: INTEGER; xmm: INTEGER); |
640 | PROCEDURE fcmp (op: INTEGER; xmm: INTEGER); |
784 | VAR |
641 | VAR |
785 | cc, reg: INTEGER; |
642 | cc, reg: INTEGER; |
786 | 643 | ||
787 | BEGIN |
644 | BEGIN |
788 | reg := GetAnyReg(); |
645 | reg := GetAnyReg(); |
789 | xor(reg, reg); |
646 | xor(reg, reg); |
790 | CASE op OF |
647 | CASE op OF |
791 | |IL.opEQF: |
648 | |IL.opEQF: |
792 | comisd(xmm - 1, xmm); |
649 | comisd(xmm - 1, xmm); |
793 | cc := sete |
650 | cc := sete |
794 | 651 | ||
795 | |IL.opNEF: |
652 | |IL.opNEF: |
796 | comisd(xmm - 1, xmm); |
653 | comisd(xmm - 1, xmm); |
797 | cc := setne |
654 | cc := setne |
798 | 655 | ||
799 | |IL.opLTF: |
656 | |IL.opLTF: |
800 | comisd(xmm - 1, xmm); |
657 | comisd(xmm - 1, xmm); |
801 | cc := setc |
658 | cc := setc |
802 | 659 | ||
803 | |IL.opGTF: |
660 | |IL.opGTF: |
804 | comisd(xmm, xmm - 1); |
661 | comisd(xmm, xmm - 1); |
805 | cc := setc |
662 | cc := setc |
806 | 663 | ||
807 | |IL.opLEF: |
664 | |IL.opLEF: |
808 | comisd(xmm, xmm - 1); |
665 | comisd(xmm, xmm - 1); |
809 | cc := setnc |
666 | cc := setnc |
810 | 667 | ||
811 | |IL.opGEF: |
668 | |IL.opGEF: |
812 | comisd(xmm - 1, xmm); |
669 | comisd(xmm - 1, xmm); |
813 | cc := setnc |
670 | cc := setnc |
814 | END; |
671 | END; |
815 | OutByte2(7AH, 3 + reg DIV 8); (* jp L *) |
672 | OutByte2(7AH, 3 + reg DIV 8); (* jp L *) |
816 | X86.setcc(cc, reg) |
673 | X86.setcc(cc, reg) |
817 | (* L: *) |
674 | (* L: *) |
818 | END fcmp; |
675 | END fcmp; |
819 | 676 | ||
820 | 677 | ||
821 | PROCEDURE translate (commands: LISTS.LIST; stroffs: INTEGER); |
678 | PROCEDURE translate (commands: LISTS.LIST; stroffs: INTEGER); |
822 | VAR |
679 | VAR |
823 | cmd, next: COMMAND; |
680 | cmd, next: COMMAND; |
824 | 681 | ||
825 | opcode, param1, param2, param3, a, b, c, n, label, L, i, cc: INTEGER; |
682 | opcode, param1, param2, param3, a, b, c, n, label, L, i, cc: INTEGER; |
826 | 683 | ||
827 | reg1, reg2, xmm: INTEGER; |
684 | reg1, reg2, xmm: INTEGER; |
828 | 685 | ||
829 | float: REAL; |
686 | float: REAL; |
830 | - | ||
831 | regVar: BOOLEAN; |
- | |
832 | 687 | ||
833 | BEGIN |
688 | BEGIN |
834 | xmm := -1; |
689 | xmm := -1; |
835 | cmd := commands.first(COMMAND); |
690 | cmd := commands.first(COMMAND); |
836 | WHILE cmd # NIL DO |
691 | WHILE cmd # NIL DO |
837 | 692 | ||
838 | param1 := cmd.param1; |
693 | param1 := cmd.param1; |
839 | param2 := cmd.param2; |
694 | param2 := cmd.param2; |
840 | 695 | ||
841 | opcode := cmd.opcode; |
696 | opcode := cmd.opcode; |
842 | 697 | ||
843 | CASE opcode OF |
698 | CASE opcode OF |
844 | 699 | ||
845 | |IL.opJMP: |
700 | |IL.opJMP: |
846 | X86.jmp(param1) |
701 | X86.jmp(param1) |
847 | 702 | ||
848 | |IL.opCALL, IL.opWIN64CALL, IL.opSYSVCALL: |
703 | |IL.opCALL, IL.opWIN64CALL, IL.opSYSVCALL: |
849 | REG.Store(R); |
- | |
850 | CASE opcode OF |
704 | CASE opcode OF |
851 | |IL.opCALL: |
705 | |IL.opCALL: |
852 | |IL.opWIN64CALL: Win64Passing(param2) |
706 | |IL.opWIN64CALL: Win64Passing(param2) |
853 | |IL.opSYSVCALL: SysVPassing(param2) |
707 | |IL.opSYSVCALL: SysVPassing(param2) |
854 | END; |
708 | END; |
855 | X86.call(param1); |
709 | X86.call(param1) |
856 | REG.Restore(R) |
- | |
857 | 710 | ||
858 | |IL.opCALLP, IL.opWIN64CALLP, IL.opSYSVCALLP: |
711 | |IL.opCALLP, IL.opWIN64CALLP, IL.opSYSVCALLP: |
859 | UnOp(reg1); |
712 | UnOp(reg1); |
860 | IF reg1 # rax THEN |
713 | IF reg1 # rax THEN |
861 | GetRegA; |
714 | mov(rax, reg1) |
862 | ASSERT(REG.Exchange(R, reg1, rax)); |
- | |
863 | drop |
- | |
864 | END; |
715 | END; |
865 | drop; |
716 | drop; |
866 | REG.Store(R); |
- | |
867 | CASE opcode OF |
717 | CASE opcode OF |
868 | |IL.opCALLP: |
718 | |IL.opCALLP: |
869 | |IL.opWIN64CALLP: Win64Passing(param2) |
719 | |IL.opWIN64CALLP: Win64Passing(param2) |
870 | |IL.opSYSVCALLP: SysVPassing(param2) |
720 | |IL.opSYSVCALLP: SysVPassing(param2) |
871 | END; |
721 | END; |
872 | OutByte2(0FFH, 0D0H); (* call rax *) |
722 | OutByte2(0FFH, 0D0H); (* call rax *) |
873 | REG.Restore(R); |
- | |
874 | ASSERT(R.top = -1) |
723 | ASSERT(R.top = -1) |
875 | 724 | ||
876 | |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI: |
725 | |IL.opCALLI, IL.opWIN64CALLI, IL.opSYSVCALLI: |
877 | REG.Store(R); |
- | |
878 | CASE opcode OF |
726 | CASE opcode OF |
879 | |IL.opCALLI: |
727 | |IL.opCALLI: |
880 | |IL.opWIN64CALLI: Win64Passing(param2) |
728 | |IL.opWIN64CALLI: Win64Passing(param2) |
881 | |IL.opSYSVCALLI: SysVPassing(param2) |
729 | |IL.opSYSVCALLI: SysVPassing(param2) |
882 | END; |
730 | END; |
883 | callimp(param1); |
731 | callimp(param1) |
884 | REG.Restore(R) |
- | |
885 | 732 | ||
886 | |IL.opLABEL: |
733 | |IL.opLABEL: |
887 | X86.SetLabel(param1) |
734 | X86.SetLabel(param1) |
888 | 735 | ||
889 | |IL.opERR: |
736 | |IL.opERR: |
890 | CallRTL(IL._error) |
737 | CallRTL(IL._error) |
891 | 738 | ||
892 | |IL.opONERR: |
739 | |IL.opONERR: |
893 | pushc(param2); |
740 | pushc(param2); |
894 | X86.jmp(param1) |
741 | X86.jmp(param1) |
895 | 742 | ||
896 | |IL.opPUSHC: |
743 | |IL.opPUSHC: |
897 | pushc(param2) |
744 | pushc(param2) |
898 | 745 | ||
899 | |IL.opPRECALL: |
746 | |IL.opPRECALL: |
900 | PushAll(0); |
747 | PushAll(0); |
901 | IF (param2 # 0) & (xmm >= 0) THEN |
748 | IF (param2 # 0) & (xmm >= 0) THEN |
902 | subrc(rsp, 8) |
749 | subrc(rsp, 8) |
903 | END; |
750 | END; |
904 | INC(Xmm[0]); |
751 | INC(Xmm[0]); |
905 | Xmm[Xmm[0]] := xmm + 1; |
752 | Xmm[Xmm[0]] := xmm + 1; |
906 | WHILE xmm >= 0 DO |
753 | WHILE xmm >= 0 DO |
907 | subrc(rsp, 8); |
754 | subrc(rsp, 8); |
908 | movsdmr(rsp, 0, xmm); |
755 | movsdmr(rsp, 0, xmm); |
909 | DEC(xmm) |
756 | DEC(xmm) |
910 | END; |
757 | END; |
911 | ASSERT(xmm = -1) |
758 | ASSERT(xmm = -1) |
912 | 759 | ||
913 | |IL.opWIN64ALIGN16: |
760 | |IL.opWIN64ALIGN16: |
914 | ASSERT(rax IN R.regs); |
761 | ASSERT(rax IN R.regs); |
915 | mov(rax, rsp); |
762 | mov(rax, rsp); |
916 | andrc(rsp, -16); |
763 | andrc(rsp, -16); |
917 | push(rax); |
764 | push(rax); |
918 | subrc(rsp, (MAX(param2 - 4, 0) MOD 2 + MAX(4 - param2, 0) + 1) * 8) |
765 | subrc(rsp, (MAX(param2 - 4, 0) MOD 2 + MAX(4 - param2, 0) + 1) * 8) |
919 | 766 | ||
920 | |IL.opSYSVALIGN16: |
767 | |IL.opSYSVALIGN16: |
921 | ASSERT(rax IN R.regs); |
768 | ASSERT(rax IN R.regs); |
922 | mov(rax, rsp); |
769 | mov(rax, rsp); |
923 | andrc(rsp, -16); |
770 | andrc(rsp, -16); |
924 | push(rax); |
771 | push(rax); |
925 | IF ~ODD(param2) THEN |
772 | IF ~ODD(param2) THEN |
926 | push(rax) |
773 | push(rax) |
927 | END |
774 | END |
928 | 775 | ||
929 | |IL.opRESF, IL.opRES: |
776 | |IL.opRESF, IL.opRES: |
930 | ASSERT(R.top = -1); |
777 | ASSERT(R.top = -1); |
931 | ASSERT(xmm = -1); |
778 | ASSERT(xmm = -1); |
932 | n := Xmm[Xmm[0]]; DEC(Xmm[0]); |
779 | n := Xmm[Xmm[0]]; DEC(Xmm[0]); |
933 | 780 | ||
934 | IF opcode = IL.opRESF THEN |
781 | IF opcode = IL.opRESF THEN |
935 | INC(xmm); |
782 | INC(xmm); |
936 | IF n > 0 THEN |
783 | IF n > 0 THEN |
937 | movsdmr(rsp, n * 8, 0); |
784 | movsdmr(rsp, n * 8, 0); |
938 | DEC(xmm); |
785 | DEC(xmm); |
939 | INC(n) |
786 | INC(n) |
940 | END; |
787 | END; |
941 | 788 | ||
942 | IF xmm + n > MAX_XMM THEN |
789 | IF xmm + n > MAX_XMM THEN |
943 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
790 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
944 | END |
791 | END |
945 | ELSE |
792 | ELSE |
946 | GetRegA |
793 | GetRegA |
947 | END; |
794 | END; |
948 | 795 | ||
949 | WHILE n > 0 DO |
796 | WHILE n > 0 DO |
950 | INC(xmm); |
797 | INC(xmm); |
951 | movsdrm(xmm, rsp, 0); |
798 | movsdrm(xmm, rsp, 0); |
952 | addrc(rsp, 8); |
799 | addrc(rsp, 8); |
953 | DEC(n) |
800 | DEC(n) |
954 | END |
801 | END |
955 | 802 | ||
956 | |IL.opENTER: |
803 | |IL.opENTER: |
957 | ASSERT(R.top = -1); |
804 | ASSERT(R.top = -1); |
958 | 805 | ||
959 | X86.SetLabel(param1); |
806 | X86.SetLabel(param1); |
960 | 807 | ||
961 | param3 := cmd.param3; |
808 | param3 := cmd.param3; |
962 | 809 | ||
963 | IF param3 > 0 THEN |
810 | IF param3 > 0 THEN |
964 | push(rbp); |
811 | push(rbp); |
965 | mov(rbp, rsp); |
812 | mov(rbp, rsp); |
966 | 813 | ||
967 | n := param3 MOD 32; |
814 | n := param3 MOD 32; |
968 | param3 := param3 DIV 32; |
815 | param3 := param3 DIV 32; |
969 | 816 | ||
970 | FOR i := 0 TO n - 1 DO |
817 | FOR i := 0 TO n - 1 DO |
971 | IF i IN BITS(param3) THEN |
818 | IF i IN BITS(param3) THEN |
972 | movsdmr(rbp, i * 8 + 16, i) |
819 | movsdmr(rbp, i * 8 + 16, i) |
973 | ELSE |
820 | ELSE |
974 | movmr(rbp, i * 8 + 16, Win64RegPar[i]) |
821 | movmr(rbp, i * 8 + 16, Win64RegPar[i]) |
975 | END |
822 | END |
976 | END |
823 | END |
977 | ELSIF param3 < 0 THEN |
824 | ELSIF param3 < 0 THEN |
978 | param3 := -param3; |
825 | param3 := -param3; |
979 | n := (param3 MOD 32) * 8; |
826 | n := (param3 MOD 32) * 8; |
980 | param3 := param3 DIV 32; |
827 | param3 := param3 DIV 32; |
981 | pop(r10); |
828 | pop(r11); |
982 | subrc(rsp, n); |
829 | subrc(rsp, n); |
983 | push(r10); |
830 | push(r11); |
984 | push(rbp); |
831 | push(rbp); |
985 | mov(rbp, rsp); |
832 | mov(rbp, rsp); |
986 | 833 | ||
987 | a := 0; |
834 | a := 0; |
988 | b := 0; |
835 | b := 0; |
989 | c := 0; |
836 | c := 0; |
990 | 837 | ||
991 | INC(n, 16); |
838 | INC(n, 16); |
992 | 839 | ||
993 | FOR i := 16 TO n - 8 BY 8 DO |
840 | FOR i := 16 TO n - 8 BY 8 DO |
994 | IF ODD(param3) THEN |
841 | IF ODD(param3) THEN |
995 | IF b <= 7 THEN |
842 | IF b <= 7 THEN |
996 | movsdmr(rbp, i, b); |
843 | movsdmr(rbp, i, b); |
997 | INC(b) |
844 | INC(b) |
998 | ELSE |
845 | ELSE |
999 | movrm(r10, rbp, n + c); |
846 | movrm(r11, rbp, n + c); |
1000 | movmr(rbp, i, r10); |
847 | movmr(rbp, i, r11); |
1001 | INC(c, 8) |
848 | INC(c, 8) |
1002 | END |
849 | END |
1003 | ELSE |
850 | ELSE |
1004 | IF a <= 5 THEN |
851 | IF a <= 5 THEN |
1005 | movmr(rbp, i, SystemVRegPar[a]); |
852 | movmr(rbp, i, SystemVRegPar[a]); |
1006 | INC(a) |
853 | INC(a) |
1007 | ELSE |
854 | ELSE |
1008 | movrm(r10, rbp, n + c); |
855 | movrm(r11, rbp, n + c); |
1009 | movmr(rbp, i, r10); |
856 | movmr(rbp, i, r11); |
1010 | INC(c, 8) |
857 | INC(c, 8) |
1011 | END |
858 | END |
1012 | END; |
859 | END; |
1013 | param3 := param3 DIV 2 |
860 | param3 := param3 DIV 2 |
1014 | END |
861 | END |
1015 | ELSE |
862 | ELSE |
1016 | push(rbp); |
863 | push(rbp); |
1017 | mov(rbp, rsp) |
864 | mov(rbp, rsp) |
1018 | END; |
865 | END; |
1019 | 866 | ||
1020 | n := param2; |
867 | n := param2; |
1021 | IF n > 4 THEN |
868 | IF n > 4 THEN |
1022 | movrc(rcx, n); |
869 | movrc(rcx, n); |
1023 | (* L: *) |
870 | (* L: *) |
1024 | pushc(0); |
871 | pushc(0); |
1025 | OutByte2(0E2H, 0FCH) (* loop L *) |
872 | OutByte2(0E2H, 0FCH) (* loop L *) |
1026 | ELSE |
873 | ELSE |
1027 | WHILE n > 0 DO |
874 | WHILE n > 0 DO |
1028 | pushc(0); |
875 | pushc(0); |
1029 | DEC(n) |
876 | DEC(n) |
1030 | END |
877 | END |
1031 | END; |
- | |
1032 | - | ||
1033 | IF cmd.allocReg THEN |
- | |
1034 | allocReg(cmd) |
- | |
1035 | END |
878 | END |
1036 | 879 | ||
1037 | |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF: |
880 | |IL.opLEAVE, IL.opLEAVER, IL.opLEAVEF: |
1038 | IF opcode = IL.opLEAVER THEN |
881 | IF opcode = IL.opLEAVER THEN |
1039 | UnOp(reg1); |
882 | UnOp(reg1); |
1040 | IF reg1 # rax THEN |
883 | IF reg1 # rax THEN |
1041 | GetRegA; |
884 | mov(rax, reg1) |
1042 | ASSERT(REG.Exchange(R, reg1, rax)); |
- | |
1043 | drop |
- | |
1044 | END; |
885 | END; |
1045 | drop |
886 | drop |
1046 | END; |
887 | END; |
1047 | 888 | ||
1048 | ASSERT(R.top = -1); |
889 | ASSERT(R.top = -1); |
1049 | 890 | ||
1050 | IF opcode = IL.opLEAVEF THEN |
891 | IF opcode = IL.opLEAVEF THEN |
1051 | DEC(xmm) |
892 | DEC(xmm) |
1052 | END; |
893 | END; |
1053 | 894 | ||
1054 | ASSERT(xmm = -1); |
895 | ASSERT(xmm = -1); |
1055 | 896 | ||
1056 | IF param1 > 0 THEN |
897 | IF param1 > 0 THEN |
1057 | mov(rsp, rbp) |
898 | mov(rsp, rbp) |
1058 | END; |
899 | END; |
1059 | 900 | ||
1060 | pop(rbp); |
901 | pop(rbp); |
1061 | IF param2 > 0 THEN |
902 | IF param2 > 0 THEN |
1062 | OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256) (* ret param2 *) |
903 | OutByte3(0C2H, (param2 * 8) MOD 256, (param2 * 8) DIV 256) (* ret param2*8 *) |
1063 | ELSE |
904 | ELSE |
1064 | X86.ret |
905 | X86.ret |
1065 | END; |
906 | END |
1066 | REG.Reset(R) |
- | |
1067 | 907 | ||
1068 | |IL.opSAVES: |
908 | |IL.opSAVES: |
1069 | UnOp(reg1); |
909 | UnOp(reg1); |
1070 | REG.PushAll_1(R); |
910 | REG.PushAll_1(R); |
1071 | pushDA(stroffs + param2); |
911 | pushDA(stroffs + param2); |
1072 | push(reg1); |
912 | push(reg1); |
1073 | drop; |
913 | drop; |
1074 | pushc(param1); |
914 | pushc(param1); |
1075 | CallRTL(IL._move) |
915 | CallRTL(IL._move) |
1076 | 916 | ||
1077 | |IL.opSADR: |
917 | |IL.opSADR: |
1078 | lea(GetAnyReg(), stroffs + param2, sDATA) |
918 | lea(GetAnyReg(), stroffs + param2, sDATA) |
1079 | 919 | ||
1080 | |IL.opLOAD8: |
920 | |IL.opLOAD8: |
1081 | UnOp(reg1); |
921 | UnOp(reg1); |
1082 | movzx(reg1, reg1, 0, FALSE) |
922 | movzx(reg1, reg1, 0, FALSE) |
1083 | 923 | ||
1084 | |IL.opLOAD16: |
924 | |IL.opLOAD16: |
1085 | UnOp(reg1); |
925 | UnOp(reg1); |
1086 | movzx(reg1, reg1, 0, TRUE) |
926 | movzx(reg1, reg1, 0, TRUE) |
1087 | 927 | ||
1088 | |IL.opLOAD32: |
928 | |IL.opLOAD32: |
1089 | UnOp(reg1); |
929 | UnOp(reg1); |
1090 | movrm32(reg1, reg1, 0); |
930 | movrm32(reg1, reg1, 0); |
1091 | shiftrc(shl, reg1, 32); |
931 | shiftrc(shl, reg1, 32); |
1092 | shiftrc(shr, reg1, 32) |
932 | shiftrc(shr, reg1, 32) |
1093 | 933 | ||
1094 | |IL.opLOAD64: |
934 | |IL.opLOAD64: |
1095 | UnOp(reg1); |
935 | UnOp(reg1); |
1096 | movrm(reg1, reg1, 0) |
936 | movrm(reg1, reg1, 0) |
1097 | 937 | ||
1098 | |IL.opLLOAD64: |
938 | |IL.opLLOAD64: |
1099 | reg1 := GetAnyReg(); |
939 | reg1 := GetAnyReg(); |
1100 | reg2 := GetVarReg(param2); |
- | |
1101 | IF reg2 # -1 THEN |
- | |
1102 | mov(reg1, reg2) |
- | |
1103 | ELSE |
- | |
1104 | movrm(reg1, rbp, param2 * 8) |
940 | movrm(reg1, rbp, param2 * 8) |
1105 | END |
- | |
1106 | 941 | ||
1107 | |IL.opLLOAD8, |
942 | |IL.opLLOAD8, |
1108 | IL.opLLOAD16: |
943 | IL.opLLOAD16: |
1109 | reg1 := GetAnyReg(); |
944 | reg1 := GetAnyReg(); |
1110 | reg2 := GetVarReg(param2); |
- | |
1111 | IF reg2 # -1 THEN |
- | |
1112 | mov(reg1, reg2) |
- | |
1113 | ELSE |
- | |
1114 | movzx(reg1, rbp, param2 * 8, opcode = IL.opLLOAD16) |
945 | movzx(reg1, rbp, param2 * 8, opcode = IL.opLLOAD16) |
1115 | END |
- | |
1116 | 946 | ||
1117 | |IL.opLLOAD32: |
947 | |IL.opLLOAD32: |
1118 | reg1 := GetAnyReg(); |
948 | reg1 := GetAnyReg(); |
1119 | reg2 := GetVarReg(param2); |
- | |
1120 | IF reg2 # -1 THEN |
- | |
1121 | mov(reg1, reg2) |
- | |
1122 | ELSE |
- | |
1123 | movrm32(reg1, rbp, param2 * 8) |
949 | movrm32(reg1, rbp, param2 * 8); |
1124 | END; |
- | |
1125 | shiftrc(shl, reg1, 32); |
950 | shiftrc(shl, reg1, 32); |
1126 | shiftrc(shr, reg1, 32) |
951 | shiftrc(shr, reg1, 32) |
1127 | 952 | ||
1128 | |IL.opGLOAD64: |
953 | |IL.opGLOAD64: |
1129 | reg1 := GetAnyReg(); |
954 | reg1 := GetAnyReg(); |
1130 | Rex(0, reg1); (* mov reg1, qword[rip + param2 + BSS] *) |
955 | Rex(0, reg1); (* mov reg1, qword[rip + param2 + BSS] *) |
1131 | OutByte2(8BH, 05H + 8 * (reg1 MOD 8)); |
956 | OutByte2(8BH, 05H + 8 * (reg1 MOD 8)); |
1132 | X86.Reloc(sBSS, param2) |
957 | X86.Reloc(sBSS, param2) |
1133 | 958 | ||
1134 | |IL.opGLOAD8, IL.opGLOAD16: |
959 | |IL.opGLOAD8, IL.opGLOAD16: |
1135 | reg1 := GetAnyReg(); |
960 | reg1 := GetAnyReg(); |
1136 | Rex(0, reg1); (* movzx reg1, byte/word[rip + param2 + BSS] *) |
961 | Rex(0, reg1); (* movzx reg1, byte/word[rip + param2 + BSS] *) |
1137 | OutByte3(0FH, 0B6H + ORD(opcode = IL.opGLOAD16), 05H + 8 * (reg1 MOD 8)); |
962 | OutByte3(0FH, 0B6H + ORD(opcode = IL.opGLOAD16), 05H + 8 * (reg1 MOD 8)); |
1138 | X86.Reloc(sBSS, param2) |
963 | X86.Reloc(sBSS, param2) |
1139 | 964 | ||
1140 | |IL.opGLOAD32: |
965 | |IL.opGLOAD32: |
1141 | reg1 := GetAnyReg(); |
966 | reg1 := GetAnyReg(); |
1142 | lea(reg1, param2, sBSS); |
967 | lea(reg1, param2, sBSS); |
1143 | movrm32(reg1, reg1, 0); |
968 | movrm32(reg1, reg1, 0); |
1144 | shiftrc(shl, reg1, 32); |
969 | shiftrc(shl, reg1, 32); |
1145 | shiftrc(shr, reg1, 32) |
970 | shiftrc(shr, reg1, 32) |
1146 | 971 | ||
1147 | |IL.opVLOAD64: |
972 | |IL.opVLOAD64: |
1148 | reg1 := GetAnyReg(); |
973 | reg1 := GetAnyReg(); |
1149 | movrm(reg1, rbp, param2 * 8); |
974 | movrm(reg1, rbp, param2 * 8); |
1150 | movrm(reg1, reg1, 0) |
975 | movrm(reg1, reg1, 0) |
1151 | 976 | ||
1152 | |IL.opVLOAD8, |
977 | |IL.opVLOAD8, |
1153 | IL.opVLOAD16: |
978 | IL.opVLOAD16: |
1154 | reg1 := GetAnyReg(); |
979 | reg1 := GetAnyReg(); |
1155 | movrm(reg1, rbp, param2 * 8); |
980 | movrm(reg1, rbp, param2 * 8); |
1156 | movzx(reg1, reg1, 0, opcode = IL.opVLOAD16) |
981 | movzx(reg1, reg1, 0, opcode = IL.opVLOAD16) |
1157 | 982 | ||
1158 | |IL.opVLOAD32: |
983 | |IL.opVLOAD32: |
1159 | reg1 := GetAnyReg(); |
984 | reg1 := GetAnyReg(); |
1160 | reg2 := GetAnyReg(); |
985 | reg2 := GetAnyReg(); |
1161 | movrm(reg2, rbp, param2 * 8); |
986 | movrm(reg2, rbp, param2 * 8); |
1162 | movrm32(reg1, reg2, 0); |
987 | movrm32(reg1, reg2, 0); |
1163 | shiftrc(shl, reg1, 32); |
988 | shiftrc(shl, reg1, 32); |
1164 | shiftrc(shr, reg1, 32); |
989 | shiftrc(shr, reg1, 32); |
1165 | drop |
990 | drop |
1166 | 991 | ||
1167 | |IL.opLADR: |
992 | |IL.opLADR: |
1168 | n := param2 * 8; |
993 | n := param2 * 8; |
1169 | next := cmd.next(COMMAND); |
994 | next := cmd.next(COMMAND); |
1170 | IF (next.opcode = IL.opSAVEF) OR (next.opcode = IL.opSAVEFI) THEN |
995 | IF (next.opcode = IL.opSAVEF) OR (next.opcode = IL.opSAVEFI) THEN |
1171 | ASSERT(xmm >= 0); |
996 | ASSERT(xmm >= 0); |
1172 | movsdmr(rbp, n, xmm); |
997 | movsdmr(rbp, n, xmm); |
1173 | DEC(xmm); |
998 | DEC(xmm); |
1174 | cmd := next |
999 | cmd := next |
1175 | ELSIF next.opcode = IL.opLOADF THEN |
1000 | ELSIF next.opcode = IL.opLOADF THEN |
1176 | INC(xmm); |
1001 | INC(xmm); |
1177 | IF xmm > MAX_XMM THEN |
1002 | IF xmm > MAX_XMM THEN |
1178 | ERRORS.ErrorMsg(fname, next.param1, next.param2, FPR_ERR) |
1003 | ERRORS.ErrorMsg(fname, next.param1, next.param2, FPR_ERR) |
1179 | END; |
1004 | END; |
1180 | movsdrm(xmm, rbp, n); |
1005 | movsdrm(xmm, rbp, n); |
1181 | cmd := next |
1006 | cmd := next |
1182 | ELSE |
1007 | ELSE |
1183 | IF (next.opcode = IL.opADDC) & ~isLong(n + next.param2) THEN |
1008 | IF (next.opcode = IL.opADDC) & ~isLong(n + next.param2) THEN |
1184 | INC(n, next.param2); |
1009 | INC(n, next.param2); |
1185 | cmd := next |
1010 | cmd := next |
1186 | END; |
1011 | END; |
1187 | reg1 := GetAnyReg(); |
1012 | reg1 := GetAnyReg(); |
1188 | Rex(0, reg1); |
1013 | Rex(0, reg1); |
1189 | OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8); (* lea reg1, qword[rbp+n] *) |
1014 | OutByte2(8DH, 45H + long(n) + (reg1 MOD 8) * 8); (* lea reg1, qword[rbp+n] *) |
1190 | OutIntByte(n) |
1015 | OutIntByte(n) |
1191 | END |
1016 | END |
1192 | 1017 | ||
1193 | |IL.opGADR: |
1018 | |IL.opGADR: |
1194 | next := cmd.next(COMMAND); |
1019 | next := cmd.next(COMMAND); |
1195 | IF (next.opcode = IL.opADDC) & ~isLong(param2 + next.param2) THEN |
1020 | IF (next.opcode = IL.opADDC) & ~isLong(param2 + next.param2) THEN |
1196 | INC(param2, next.param2); |
1021 | INC(param2, next.param2); |
1197 | cmd := next |
1022 | cmd := next |
1198 | END; |
1023 | END; |
1199 | lea(GetAnyReg(), param2, sBSS) |
1024 | lea(GetAnyReg(), param2, sBSS) |
1200 | 1025 | ||
1201 | |IL.opVADR: |
1026 | |IL.opVADR: |
1202 | movrm(GetAnyReg(), rbp, param2 * 8) |
1027 | movrm(GetAnyReg(), rbp, param2 * 8) |
1203 | 1028 | ||
1204 | |IL.opSAVE8C: |
1029 | |IL.opSAVE8C: |
1205 | UnOp(reg1); |
1030 | UnOp(reg1); |
1206 | IF reg1 >= 8 THEN |
1031 | IF reg1 >= 8 THEN |
1207 | OutByte(41H) |
1032 | OutByte(41H) |
1208 | END; |
1033 | END; |
1209 | OutByte3(0C6H, reg1 MOD 8, param2); (* mov byte[reg1], param2 *) |
1034 | OutByte3(0C6H, reg1 MOD 8, param2); (* mov byte[reg1], param2 *) |
1210 | drop |
1035 | drop |
1211 | 1036 | ||
1212 | |IL.opSAVE16C: |
1037 | |IL.opSAVE16C: |
1213 | UnOp(reg1); |
1038 | UnOp(reg1); |
1214 | OutByte(66H); |
1039 | OutByte(66H); |
1215 | IF reg1 >= 8 THEN |
1040 | IF reg1 >= 8 THEN |
1216 | OutByte(41H) |
1041 | OutByte(41H) |
1217 | END; |
1042 | END; |
1218 | OutByte2(0C7H, reg1 MOD 8); |
1043 | OutByte2(0C7H, reg1 MOD 8); |
1219 | OutByte2(param2 MOD 256, param2 DIV 256); (* mov word[reg1], param2 *) |
1044 | OutByte2(param2 MOD 256, param2 DIV 256); (* mov word[reg1], param2 *) |
1220 | drop |
1045 | drop |
1221 | 1046 | ||
1222 | |IL.opSAVEC: |
1047 | |IL.opSAVEC: |
1223 | UnOp(reg1); |
1048 | UnOp(reg1); |
1224 | IF isLong(param2) THEN |
1049 | IF isLong(param2) THEN |
1225 | reg2 := GetAnyReg(); |
1050 | reg2 := GetAnyReg(); |
1226 | movrc(reg2, param2); |
1051 | movrc(reg2, param2); |
1227 | movmr(reg1, 0, reg2); |
1052 | movmr(reg1, 0, reg2); |
1228 | drop |
1053 | drop |
1229 | ELSE |
1054 | ELSE |
1230 | Rex(reg1, 0); |
1055 | Rex(reg1, 0); |
1231 | OutByte2(0C7H, reg1 MOD 8); (* mov qword[reg1], param2 *) |
1056 | OutByte2(0C7H, reg1 MOD 8); (* mov qword[reg1], param2 *) |
1232 | OutInt(param2) |
1057 | OutInt(param2) |
1233 | END; |
1058 | END; |
1234 | drop |
1059 | drop |
1235 | 1060 | ||
1236 | |IL.opRSET: |
1061 | |IL.opRSET: |
1237 | PushAll(2); |
1062 | PushAll(2); |
1238 | CallRTL(IL._set); |
1063 | CallRTL(IL._set); |
1239 | GetRegA |
1064 | GetRegA |
1240 | 1065 | ||
1241 | |IL.opRSETR: |
1066 | |IL.opRSETR: |
1242 | PushAll(1); |
1067 | PushAll(1); |
1243 | pushc(param2); |
1068 | pushc(param2); |
1244 | CallRTL(IL._set); |
1069 | CallRTL(IL._set); |
1245 | GetRegA |
1070 | GetRegA |
1246 | 1071 | ||
1247 | |IL.opRSETL: |
1072 | |IL.opRSETL: |
1248 | UnOp(reg1); |
1073 | UnOp(reg1); |
1249 | REG.PushAll_1(R); |
1074 | REG.PushAll_1(R); |
1250 | pushc(param2); |
1075 | pushc(param2); |
1251 | push(reg1); |
1076 | push(reg1); |
1252 | drop; |
1077 | drop; |
1253 | CallRTL(IL._set); |
1078 | CallRTL(IL._set); |
1254 | GetRegA |
1079 | GetRegA |
1255 | 1080 | ||
1256 | |IL.opRSET1: |
1081 | |IL.opRSET1: |
1257 | PushAll(1); |
1082 | PushAll(1); |
1258 | CallRTL(IL._set1); |
1083 | CallRTL(IL._set1); |
1259 | GetRegA |
1084 | GetRegA |
1260 | 1085 | ||
1261 | |IL.opINCL, IL.opEXCL: |
1086 | |IL.opINCL, IL.opEXCL: |
1262 | BinOp(reg1, reg2); |
1087 | BinOp(reg1, reg2); |
1263 | cmprc(reg1, 64); |
1088 | cmprc(reg1, 64); |
1264 | OutByte2(73H, 04H); (* jnb L *) |
1089 | OutByte2(73H, 04H); (* jnb L *) |
1265 | Rex(reg2, reg1); |
1090 | Rex(reg2, reg1); |
1266 | OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); (* bts/btr qword[reg2], reg1 *) |
1091 | OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opEXCL), 8 * (reg1 MOD 8) + reg2 MOD 8); (* bts/btr qword[reg2], reg1 *) |
1267 | (* L: *) |
1092 | (* L: *) |
1268 | drop; |
1093 | drop; |
1269 | drop |
1094 | drop |
1270 | 1095 | ||
1271 | |IL.opINCLC, IL.opEXCLC: |
1096 | |IL.opINCLC, IL.opEXCLC: |
1272 | UnOp(reg1); |
1097 | UnOp(reg1); |
1273 | Rex(reg1, 0); |
1098 | Rex(reg1, 0); |
1274 | OutByte2(0FH, 0BAH); (* bts/btr qword[reg1], param2 *) |
1099 | OutByte2(0FH, 0BAH); (* bts/btr qword[reg1], param2 *) |
1275 | OutByte2(28H + 8 * ORD(opcode = IL.opEXCLC) + reg1 MOD 8, param2); |
1100 | OutByte2(28H + 8 * ORD(opcode = IL.opEXCLC) + reg1 MOD 8, param2); |
1276 | drop |
1101 | drop |
1277 | 1102 | ||
1278 | |IL.opEQS .. IL.opGES: |
1103 | |IL.opEQS .. IL.opGES: |
1279 | PushAll(4); |
1104 | PushAll(4); |
1280 | pushc(opcode - IL.opEQS); |
1105 | pushc(opcode - IL.opEQS); |
1281 | CallRTL(IL._strcmp); |
1106 | CallRTL(IL._strcmp); |
1282 | GetRegA |
1107 | GetRegA |
1283 | 1108 | ||
1284 | |IL.opEQSW .. IL.opGESW: |
1109 | |IL.opEQSW .. IL.opGESW: |
1285 | PushAll(4); |
1110 | PushAll(4); |
1286 | pushc(opcode - IL.opEQSW); |
1111 | pushc(opcode - IL.opEQSW); |
1287 | CallRTL(IL._strcmpw); |
1112 | CallRTL(IL._strcmpw); |
1288 | GetRegA |
1113 | GetRegA |
1289 | 1114 | ||
1290 | |IL.opCONST: |
1115 | |IL.opCONST: |
1291 | movrc(GetAnyReg(), param2) |
1116 | movrc(GetAnyReg(), param2) |
1292 | 1117 | ||
1293 | |IL.opEQ..IL.opGE, |
1118 | |IL.opEQ..IL.opGE, |
1294 | IL.opEQC..IL.opGEC: |
1119 | IL.opEQC..IL.opGEC: |
1295 | 1120 | ||
1296 | IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN |
1121 | IF (IL.opEQ <= opcode) & (opcode <= IL.opGE) THEN |
1297 | BinOp(reg1, reg2); |
1122 | BinOp(reg1, reg2); |
1298 | cmprr(reg1, reg2); |
1123 | cmprr(reg1, reg2); |
1299 | drop |
1124 | drop |
1300 | ELSE |
1125 | ELSE |
1301 | UnOp(reg1); |
1126 | UnOp(reg1); |
1302 | cmprc(reg1, param2) |
1127 | cmprc(reg1, param2) |
1303 | END; |
1128 | END; |
1304 | 1129 | ||
1305 | drop; |
1130 | drop; |
1306 | cc := X86.cond(opcode); |
1131 | cc := X86.cond(opcode); |
1307 | 1132 | ||
1308 | next := cmd.next(COMMAND); |
1133 | next := cmd.next(COMMAND); |
1309 | IF next.opcode = IL.opJNZ THEN |
1134 | IF next.opcode = IL.opJNZ THEN |
1310 | jcc(cc, next.param1); |
1135 | jcc(cc, next.param1); |
1311 | cmd := next |
1136 | cmd := next |
1312 | ELSIF next.opcode = IL.opJZ THEN |
1137 | ELSIF next.opcode = IL.opJZ THEN |
1313 | jcc(X86.inv0(cc), next.param1); |
1138 | jcc(X86.inv0(cc), next.param1); |
1314 | cmd := next |
1139 | cmd := next |
1315 | ELSE |
1140 | ELSE |
1316 | reg1 := GetAnyReg(); |
1141 | reg1 := GetAnyReg(); |
1317 | X86.setcc(cc + 16, reg1); |
1142 | X86.setcc(cc + 16, reg1); |
1318 | andrc(reg1, 1) |
1143 | andrc(reg1, 1) |
1319 | END |
1144 | END |
1320 | 1145 | ||
1321 | |IL.opCODE: |
1146 | |IL.opCODE: |
1322 | OutByte(param2) |
1147 | OutByte(param2) |
1323 | 1148 | ||
1324 | |IL.opPUSHIP: |
1149 | |IL.opPUSHIP: |
1325 | reg1 := GetAnyReg(); |
1150 | reg1 := GetAnyReg(); |
1326 | lea(reg1, param2, sIMP); |
1151 | lea(reg1, param2, sIMP); |
1327 | movrm(reg1, reg1, 0) |
1152 | movrm(reg1, reg1, 0) |
1328 | 1153 | ||
1329 | |IL.opPARAM: |
1154 | |IL.opPARAM: |
1330 | n := param2; |
1155 | n := param2; |
1331 | IF n = 1 THEN |
1156 | IF n = 1 THEN |
1332 | UnOp(reg1); |
1157 | UnOp(reg1); |
1333 | push(reg1); |
1158 | push(reg1); |
1334 | drop |
1159 | drop |
1335 | ELSE |
1160 | ELSE |
1336 | ASSERT(R.top + 1 <= n); |
1161 | ASSERT(R.top + 1 <= n); |
1337 | PushAll(n) |
1162 | PushAll(n) |
1338 | END |
1163 | END |
1339 | 1164 | ||
1340 | |IL.opJNZ1: |
1165 | |IL.opJNZ1: |
1341 | UnOp(reg1); |
1166 | UnOp(reg1); |
1342 | test(reg1); |
1167 | test(reg1); |
1343 | jcc(jne, param1) |
1168 | jcc(jne, param1) |
1344 | 1169 | ||
1345 | |IL.opJG: |
1170 | |IL.opJG: |
1346 | UnOp(reg1); |
1171 | UnOp(reg1); |
1347 | test(reg1); |
1172 | test(reg1); |
1348 | jcc(jg, param1) |
1173 | jcc(jg, param1) |
1349 | 1174 | ||
1350 | |IL.opJNZ: |
1175 | |IL.opJNZ: |
1351 | UnOp(reg1); |
1176 | UnOp(reg1); |
1352 | test(reg1); |
1177 | test(reg1); |
1353 | jcc(jne, param1); |
1178 | jcc(jne, param1); |
1354 | drop |
1179 | drop |
1355 | 1180 | ||
1356 | |IL.opJZ: |
1181 | |IL.opJZ: |
1357 | UnOp(reg1); |
1182 | UnOp(reg1); |
1358 | test(reg1); |
1183 | test(reg1); |
1359 | jcc(je, param1); |
1184 | jcc(je, param1); |
1360 | drop |
1185 | drop |
1361 | 1186 | ||
1362 | |IL.opIN, IL.opINR: |
1187 | |IL.opIN, IL.opINR: |
1363 | IF opcode = IL.opINR THEN |
1188 | IF opcode = IL.opINR THEN |
1364 | reg2 := GetAnyReg(); |
1189 | reg2 := GetAnyReg(); |
1365 | movrc(reg2, param2) |
1190 | movrc(reg2, param2) |
1366 | END; |
1191 | END; |
1367 | label := NewLabel(); |
1192 | label := NewLabel(); |
1368 | L := NewLabel(); |
1193 | L := NewLabel(); |
1369 | BinOp(reg1, reg2); |
1194 | BinOp(reg1, reg2); |
1370 | cmprc(reg1, 64); |
1195 | cmprc(reg1, 64); |
1371 | jcc(jb, L); |
1196 | jcc(jb, L); |
1372 | xor(reg1, reg1); |
1197 | xor(reg1, reg1); |
1373 | X86.jmp(label); |
1198 | X86.jmp(label); |
1374 | X86.SetLabel(L); |
1199 | X86.SetLabel(L); |
1375 | Rex(reg2, reg1); |
1200 | Rex(reg2, reg1); |
1376 | OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); (* bt reg2, reg1 *) |
1201 | OutByte3(0FH, 0A3H, 0C0H + 8 * (reg1 MOD 8) + reg2 MOD 8); (* bt reg2, reg1 *) |
1377 | X86.setcc(setc, reg1); |
1202 | X86.setcc(setc, reg1); |
1378 | andrc(reg1, 1); |
1203 | andrc(reg1, 1); |
1379 | X86.SetLabel(label); |
1204 | X86.SetLabel(label); |
1380 | drop |
1205 | drop |
1381 | 1206 | ||
1382 | |IL.opINL: |
1207 | |IL.opINL: |
1383 | UnOp(reg1); |
1208 | UnOp(reg1); |
1384 | Rex(reg1, 0); |
1209 | Rex(reg1, 0); |
1385 | OutByte2(0FH, 0BAH); (* bt reg1, param2 *) |
1210 | OutByte2(0FH, 0BAH); (* bt reg1, param2 *) |
1386 | OutByte2(0E0H + reg1 MOD 8, param2); |
1211 | OutByte2(0E0H + reg1 MOD 8, param2); |
1387 | X86.setcc(setc, reg1); |
1212 | X86.setcc(setc, reg1); |
1388 | andrc(reg1, 1) |
1213 | andrc(reg1, 1) |
1389 | 1214 | ||
1390 | |IL.opNOT: |
1215 | |IL.opNOT: |
1391 | UnOp(reg1); |
1216 | UnOp(reg1); |
1392 | test(reg1); |
1217 | test(reg1); |
1393 | X86.setcc(sete, reg1); |
1218 | X86.setcc(sete, reg1); |
1394 | andrc(reg1, 1) |
1219 | andrc(reg1, 1) |
1395 | 1220 | ||
1396 | |IL.opORD: |
1221 | |IL.opORD: |
1397 | UnOp(reg1); |
1222 | UnOp(reg1); |
1398 | test(reg1); |
1223 | test(reg1); |
1399 | X86.setcc(setne, reg1); |
1224 | X86.setcc(setne, reg1); |
1400 | andrc(reg1, 1) |
1225 | andrc(reg1, 1) |
1401 | 1226 | ||
1402 | |IL.opABS: |
1227 | |IL.opABS: |
1403 | UnOp(reg1); |
1228 | UnOp(reg1); |
1404 | test(reg1); |
1229 | test(reg1); |
1405 | OutByte2(7DH, 03H); (* jge L *) |
1230 | OutByte2(7DH, 03H); (* jge L *) |
1406 | neg(reg1) |
1231 | neg(reg1) |
1407 | (* L: *) |
1232 | (* L: *) |
1408 | 1233 | ||
1409 | |IL.opEQB, IL.opNEB: |
1234 | |IL.opEQB, IL.opNEB: |
1410 | BinOp(reg1, reg2); |
1235 | BinOp(reg1, reg2); |
1411 | drop; |
1236 | drop; |
1412 | test(reg1); |
1237 | test(reg1); |
1413 | label := NewLabel(); |
1238 | label := NewLabel(); |
1414 | jcc(je, label); |
1239 | jcc(je, label); |
1415 | movrc(reg1, 1); |
1240 | movrc(reg1, 1); |
1416 | X86.SetLabel(label); |
1241 | X86.SetLabel(label); |
1417 | test(reg2); |
1242 | test(reg2); |
1418 | label := NewLabel(); |
1243 | label := NewLabel(); |
1419 | jcc(je, label); |
1244 | jcc(je, label); |
1420 | movrc(reg2, 1); |
1245 | movrc(reg2, 1); |
1421 | X86.SetLabel(label); |
1246 | X86.SetLabel(label); |
1422 | cmprr(reg1, reg2); |
1247 | cmprr(reg1, reg2); |
1423 | IF opcode = IL.opEQB THEN |
1248 | IF opcode = IL.opEQB THEN |
1424 | X86.setcc(sete, reg1) |
1249 | X86.setcc(sete, reg1) |
1425 | ELSE |
1250 | ELSE |
1426 | X86.setcc(setne, reg1) |
1251 | X86.setcc(setne, reg1) |
1427 | END; |
1252 | END; |
1428 | andrc(reg1, 1) |
1253 | andrc(reg1, 1) |
1429 | 1254 | ||
1430 | |IL.opMULSC: |
1255 | |IL.opMULSC: |
1431 | UnOp(reg1); |
1256 | UnOp(reg1); |
1432 | andrc(reg1, param2) |
1257 | andrc(reg1, param2) |
1433 | 1258 | ||
1434 | |IL.opDIVSC: |
1259 | |IL.opDIVSC: |
1435 | UnOp(reg1); |
1260 | UnOp(reg1); |
1436 | xorrc(reg1, param2) |
1261 | xorrc(reg1, param2) |
1437 | 1262 | ||
1438 | |IL.opADDSC: |
1263 | |IL.opADDSC: |
1439 | UnOp(reg1); |
1264 | UnOp(reg1); |
1440 | orrc(reg1, param2) |
1265 | orrc(reg1, param2) |
1441 | 1266 | ||
1442 | |IL.opSUBSL: |
1267 | |IL.opSUBSL: |
1443 | UnOp(reg1); |
1268 | UnOp(reg1); |
1444 | not(reg1); |
1269 | not(reg1); |
1445 | andrc(reg1, param2) |
1270 | andrc(reg1, param2) |
1446 | 1271 | ||
1447 | |IL.opSUBSR: |
1272 | |IL.opSUBSR: |
1448 | UnOp(reg1); |
1273 | UnOp(reg1); |
1449 | andrc(reg1, ORD(-BITS(param2))) |
1274 | andrc(reg1, ORD(-BITS(param2))) |
1450 | 1275 | ||
1451 | |IL.opMULS: |
1276 | |IL.opMULS: |
1452 | BinOp(reg1, reg2); |
1277 | BinOp(reg1, reg2); |
1453 | and(reg1, reg2); |
1278 | and(reg1, reg2); |
1454 | drop |
1279 | drop |
1455 | 1280 | ||
1456 | |IL.opDIVS: |
1281 | |IL.opDIVS: |
1457 | BinOp(reg1, reg2); |
1282 | BinOp(reg1, reg2); |
1458 | xor(reg1, reg2); |
1283 | xor(reg1, reg2); |
1459 | drop |
1284 | drop |
1460 | 1285 | ||
1461 | |IL.opUMINS: |
1286 | |IL.opUMINS: |
1462 | UnOp(reg1); |
1287 | UnOp(reg1); |
1463 | not(reg1) |
1288 | not(reg1) |
1464 | 1289 | ||
1465 | |IL.opCOPY: |
1290 | |IL.opCOPY: |
1466 | PushAll(2); |
1291 | PushAll(2); |
1467 | pushc(param2); |
1292 | pushc(param2); |
1468 | CallRTL(IL._move) |
1293 | CallRTL(IL._move) |
1469 | 1294 | ||
1470 | |IL.opMOVE: |
1295 | |IL.opMOVE: |
1471 | PushAll(3); |
1296 | PushAll(3); |
1472 | CallRTL(IL._move) |
1297 | CallRTL(IL._move) |
1473 | 1298 | ||
1474 | |IL.opCOPYA: |
1299 | |IL.opCOPYA: |
1475 | PushAll(4); |
1300 | PushAll(4); |
1476 | pushc(param2); |
1301 | pushc(param2); |
1477 | CallRTL(IL._arrcpy); |
1302 | CallRTL(IL._arrcpy); |
1478 | GetRegA |
1303 | GetRegA |
1479 | 1304 | ||
1480 | |IL.opCOPYS: |
1305 | |IL.opCOPYS: |
1481 | PushAll(4); |
1306 | PushAll(4); |
1482 | pushc(param2); |
1307 | pushc(param2); |
1483 | CallRTL(IL._strcpy) |
1308 | CallRTL(IL._strcpy) |
1484 | 1309 | ||
1485 | |IL.opROT: |
1310 | |IL.opROT: |
1486 | PushAll(0); |
1311 | PushAll(0); |
1487 | push(rsp); |
1312 | push(rsp); |
1488 | pushc(param2); |
1313 | pushc(param2); |
1489 | CallRTL(IL._rot) |
1314 | CallRTL(IL._rot) |
1490 | 1315 | ||
1491 | |IL.opNEW: |
1316 | |IL.opNEW: |
1492 | PushAll(1); |
1317 | PushAll(1); |
1493 | n := param2 + 16; |
1318 | n := param2 + 8; |
1494 | ASSERT(UTILS.Align(n, 64)); |
1319 | ASSERT(UTILS.Align(n, 8)); |
1495 | pushc(n); |
1320 | pushc(n); |
1496 | pushc(param1); |
1321 | pushc(param1); |
1497 | CallRTL(IL._new) |
1322 | CallRTL(IL._new) |
1498 | 1323 | ||
1499 | |IL.opDISP: |
1324 | |IL.opDISP: |
1500 | PushAll(1); |
1325 | PushAll(1); |
1501 | CallRTL(IL._dispose) |
1326 | CallRTL(IL._dispose) |
1502 | 1327 | ||
1503 | |IL.opPUSHT: |
1328 | |IL.opPUSHT: |
1504 | UnOp(reg1); |
1329 | UnOp(reg1); |
1505 | reg2 := GetAnyReg(); |
- | |
1506 | movrm(reg2, reg1, -8) |
1330 | movrm(GetAnyReg(), reg1, -8) |
1507 | 1331 | ||
1508 | |IL.opISREC: |
1332 | |IL.opISREC: |
1509 | PushAll(2); |
1333 | PushAll(2); |
1510 | pushc(param2 * tcount); |
1334 | pushc(param2 * tcount); |
1511 | CallRTL(IL._isrec); |
1335 | CallRTL(IL._isrec); |
1512 | GetRegA |
1336 | GetRegA |
1513 | 1337 | ||
1514 | |IL.opIS: |
1338 | |IL.opIS: |
1515 | PushAll(1); |
1339 | PushAll(1); |
1516 | pushc(param2 * tcount); |
1340 | pushc(param2 * tcount); |
1517 | CallRTL(IL._is); |
1341 | CallRTL(IL._is); |
1518 | GetRegA |
1342 | GetRegA |
1519 | 1343 | ||
1520 | |IL.opTYPEGR: |
1344 | |IL.opTYPEGR: |
1521 | PushAll(1); |
1345 | PushAll(1); |
1522 | pushc(param2 * tcount); |
1346 | pushc(param2 * tcount); |
1523 | CallRTL(IL._guardrec); |
1347 | CallRTL(IL._guardrec); |
1524 | GetRegA |
1348 | GetRegA |
1525 | 1349 | ||
1526 | |IL.opTYPEGP: |
1350 | |IL.opTYPEGP: |
1527 | UnOp(reg1); |
1351 | UnOp(reg1); |
1528 | PushAll(0); |
1352 | PushAll(0); |
1529 | push(reg1); |
1353 | push(reg1); |
1530 | pushc(param2 * tcount); |
1354 | pushc(param2 * tcount); |
1531 | CallRTL(IL._guard); |
1355 | CallRTL(IL._guard); |
1532 | GetRegA |
1356 | GetRegA |
1533 | 1357 | ||
1534 | |IL.opTYPEGD: |
1358 | |IL.opTYPEGD: |
1535 | UnOp(reg1); |
1359 | UnOp(reg1); |
1536 | PushAll(0); |
1360 | PushAll(0); |
1537 | X86.pushm(reg1, -8); |
1361 | X86.pushm(reg1, -8); |
1538 | pushc(param2 * tcount); |
1362 | pushc(param2 * tcount); |
1539 | CallRTL(IL._guardrec); |
1363 | CallRTL(IL._guardrec); |
1540 | GetRegA |
1364 | GetRegA |
1541 | 1365 | ||
1542 | |IL.opCASET: |
1366 | |IL.opCASET: |
1543 | push(r10); |
1367 | push(rcx); |
1544 | push(r10); |
1368 | push(rcx); |
1545 | pushc(param2 * tcount); |
1369 | pushc(param2 * tcount); |
1546 | CallRTL(IL._guardrec); |
1370 | CallRTL(IL._guardrec); |
1547 | pop(r10); |
1371 | pop(rcx); |
1548 | test(rax); |
1372 | test(rax); |
1549 | jcc(jne, param1) |
1373 | jcc(jne, param1) |
1550 | 1374 | ||
1551 | |IL.opSAVEP: |
1375 | |IL.opSAVEP: |
1552 | UnOp(reg1); |
1376 | UnOp(reg1); |
1553 | reg2 := GetAnyReg(); |
1377 | reg2 := GetAnyReg(); |
1554 | lea(reg2, param2, sCODE); |
1378 | lea(reg2, param2, sCODE); |
1555 | movmr(reg1, 0, reg2); |
1379 | movmr(reg1, 0, reg2); |
1556 | drop; |
1380 | drop; |
1557 | drop |
1381 | drop |
1558 | 1382 | ||
1559 | |IL.opPUSHP: |
1383 | |IL.opPUSHP: |
1560 | lea(GetAnyReg(), param2, sCODE) |
1384 | lea(GetAnyReg(), param2, sCODE) |
1561 | 1385 | ||
1562 | |IL.opINC, IL.opDEC: |
1386 | |IL.opINC, IL.opDEC: |
1563 | BinOp(reg1, reg2); |
1387 | BinOp(reg1, reg2); |
1564 | (* add/sub qword[reg2], reg1 *) |
1388 | (* add/sub qword[reg2], reg1 *) |
1565 | Rex(reg2, reg1); |
1389 | Rex(reg2, reg1); |
1566 | OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8); |
1390 | OutByte2(01H + 28H * ORD(opcode = IL.opDEC), reg2 MOD 8 + (reg1 MOD 8) * 8); |
1567 | drop; |
1391 | drop; |
1568 | drop |
1392 | drop |
1569 | 1393 | ||
1570 | |IL.opINCC: |
1394 | |IL.opINCC: |
1571 | UnOp(reg1); |
1395 | UnOp(reg1); |
1572 | IF isLong(param2) THEN |
1396 | IF isLong(param2) THEN |
1573 | reg2 := GetAnyReg(); |
1397 | reg2 := GetAnyReg(); |
1574 | movrc(reg2, param2); |
1398 | movrc(reg2, param2); |
1575 | (* add qword[reg1], reg2 *) |
1399 | (* add qword[reg1], reg2 *) |
1576 | Rex(reg1, reg2); |
1400 | Rex(reg1, reg2); |
1577 | OutByte2(01H, reg1 MOD 8 + (reg2 MOD 8) * 8); |
1401 | OutByte2(01H, reg1 MOD 8 + (reg2 MOD 8) * 8); |
1578 | drop |
1402 | drop |
1579 | ELSIF ABS(param2) = 1 THEN |
1403 | ELSIF ABS(param2) = 1 THEN |
1580 | Rex(reg1, 0); |
1404 | Rex(reg1, 0); |
1581 | OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(param2 = -1)) (* inc/dec qword[reg1] *) |
1405 | OutByte2(0FFH, reg1 MOD 8 + 8 * ORD(param2 = -1)) (* inc/dec qword[reg1] *) |
1582 | ELSE |
1406 | ELSE |
1583 | (* add qword[reg1], param2 *) |
1407 | (* add qword[reg1], param2 *) |
1584 | Rex(reg1, 0); |
1408 | Rex(reg1, 0); |
1585 | OutByte2(81H + short(param2), reg1 MOD 8); |
1409 | OutByte2(81H + short(param2), reg1 MOD 8); |
1586 | OutIntByte(param2) |
1410 | OutIntByte(param2) |
1587 | END; |
1411 | END; |
1588 | drop |
1412 | drop |
1589 | 1413 | ||
1590 | |IL.opDROP: |
1414 | |IL.opDROP: |
1591 | UnOp(reg1); |
1415 | UnOp(reg1); |
1592 | drop |
1416 | drop |
1593 | 1417 | ||
1594 | |IL.opSAVE, IL.opSAVE64: |
1418 | |IL.opSAVE, IL.opSAVE64: |
1595 | BinOp(reg2, reg1); |
1419 | BinOp(reg2, reg1); |
1596 | movmr(reg1, 0, reg2); |
1420 | movmr(reg1, 0, reg2); |
1597 | drop; |
1421 | drop; |
1598 | drop |
1422 | drop |
1599 | 1423 | ||
1600 | |IL.opSAVE8: |
1424 | |IL.opSAVE8: |
1601 | BinOp(reg2, reg1); |
1425 | BinOp(reg2, reg1); |
1602 | X86.movmr8(reg1, 0, reg2); |
1426 | X86.movmr8(reg1, 0, reg2); |
1603 | drop; |
1427 | drop; |
1604 | drop |
1428 | drop |
1605 | 1429 | ||
1606 | |IL.opSAVE16: |
1430 | |IL.opSAVE16: |
1607 | BinOp(reg2, reg1); |
1431 | BinOp(reg2, reg1); |
1608 | X86.movmr16(reg1, 0, reg2); |
1432 | X86.movmr16(reg1, 0, reg2); |
1609 | drop; |
1433 | drop; |
1610 | drop |
1434 | drop |
1611 | 1435 | ||
1612 | |IL.opSAVE32: |
1436 | |IL.opSAVE32: |
1613 | BinOp(reg2, reg1); |
1437 | BinOp(reg2, reg1); |
1614 | movmr32(reg1, 0, reg2); |
1438 | movmr32(reg1, 0, reg2); |
1615 | drop; |
1439 | drop; |
1616 | drop |
1440 | drop |
1617 | 1441 | ||
1618 | |IL.opMAX, IL.opMIN: |
1442 | |IL.opMAX, IL.opMIN: |
1619 | BinOp(reg1, reg2); |
1443 | BinOp(reg1, reg2); |
1620 | cmprr(reg1, reg2); |
1444 | cmprr(reg1, reg2); |
1621 | OutByte2(7DH + ORD(opcode = IL.opMIN), 3); (* jge/jle L *) |
1445 | OutByte2(7DH + ORD(opcode = IL.opMIN), 3); (* jge/jle L *) |
1622 | mov(reg1, reg2); |
1446 | mov(reg1, reg2); |
1623 | (* L: *) |
1447 | (* L: *) |
1624 | drop |
1448 | drop |
1625 | 1449 | ||
1626 | |IL.opMAXC, IL.opMINC: |
1450 | |IL.opMAXC, IL.opMINC: |
1627 | UnOp(reg1); |
1451 | UnOp(reg1); |
1628 | cmprc(reg1, param2); |
1452 | cmprc(reg1, param2); |
1629 | label := NewLabel(); |
1453 | label := NewLabel(); |
1630 | IF opcode = IL.opMINC THEN |
1454 | IF opcode = IL.opMINC THEN |
1631 | cc := jle |
1455 | cc := jle |
1632 | ELSE |
1456 | ELSE |
1633 | cc := jge |
1457 | cc := jge |
1634 | END; |
1458 | END; |
1635 | jcc(cc, label); |
1459 | jcc(cc, label); |
1636 | movrc(reg1, param2); |
1460 | movrc(reg1, param2); |
1637 | X86.SetLabel(label) |
1461 | X86.SetLabel(label) |
1638 | 1462 | ||
1639 | |IL.opSBOOL: |
1463 | |IL.opSBOOL: |
1640 | BinOp(reg2, reg1); |
1464 | BinOp(reg2, reg1); |
1641 | test(reg2); |
1465 | test(reg2); |
1642 | IF reg1 >= 8 THEN |
1466 | IF reg1 >= 8 THEN |
1643 | OutByte(41H) |
1467 | OutByte(41H) |
1644 | END; |
1468 | END; |
1645 | OutByte3(0FH, 95H, reg1 MOD 8); (* setne byte[reg1] *) |
1469 | OutByte3(0FH, 95H, reg1 MOD 8); (* setne byte[reg1] *) |
1646 | drop; |
1470 | drop; |
1647 | drop |
1471 | drop |
1648 | 1472 | ||
1649 | |IL.opSBOOLC: |
1473 | |IL.opSBOOLC: |
1650 | UnOp(reg1); |
1474 | UnOp(reg1); |
1651 | IF reg1 >= 8 THEN |
1475 | IF reg1 >= 8 THEN |
1652 | OutByte(41H) |
1476 | OutByte(41H) |
1653 | END; |
1477 | END; |
1654 | OutByte3(0C6H, reg1 MOD 8, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *) |
1478 | OutByte3(0C6H, reg1 MOD 8, ORD(param2 # 0)); (* mov byte[reg1], 0/1 *) |
1655 | drop |
1479 | drop |
1656 | 1480 | ||
1657 | |IL.opUMINUS: |
1481 | |IL.opUMINUS: |
1658 | UnOp(reg1); |
1482 | UnOp(reg1); |
1659 | neg(reg1) |
1483 | neg(reg1) |
1660 | 1484 | ||
1661 | |IL.opADD: |
1485 | |IL.opADD: |
1662 | BinOp(reg1, reg2); |
1486 | BinOp(reg1, reg2); |
1663 | add(reg1, reg2); |
1487 | add(reg1, reg2); |
1664 | drop |
1488 | drop |
1665 | 1489 | ||
1666 | |IL.opSUB: |
1490 | |IL.opSUB: |
1667 | BinOp(reg1, reg2); |
1491 | BinOp(reg1, reg2); |
1668 | sub(reg1, reg2); |
1492 | sub(reg1, reg2); |
1669 | drop |
1493 | drop |
1670 | 1494 | ||
1671 | |IL.opSUBR, IL.opSUBL: |
1495 | |IL.opSUBR, IL.opSUBL: |
1672 | UnOp(reg1); |
1496 | UnOp(reg1); |
1673 | IF param2 = 1 THEN |
1497 | IF param2 = 1 THEN |
1674 | decr(reg1) |
1498 | decr(reg1) |
1675 | ELSIF param2 = -1 THEN |
1499 | ELSIF param2 = -1 THEN |
1676 | incr(reg1) |
1500 | incr(reg1) |
1677 | ELSIF param2 # 0 THEN |
1501 | ELSIF param2 # 0 THEN |
1678 | subrc(reg1, param2) |
1502 | subrc(reg1, param2) |
1679 | END; |
1503 | END; |
1680 | IF opcode = IL.opSUBL THEN |
1504 | IF opcode = IL.opSUBL THEN |
1681 | neg(reg1) |
1505 | neg(reg1) |
1682 | END |
1506 | END |
1683 | 1507 | ||
1684 | |IL.opADDC: |
1508 | |IL.opADDC: |
1685 | IF (param2 # 0) & ~isLong(param2) THEN |
1509 | IF (param2 # 0) & ~isLong(param2) THEN |
1686 | UnOp(reg1); |
1510 | UnOp(reg1); |
1687 | next := cmd.next(COMMAND); |
1511 | next := cmd.next(COMMAND); |
1688 | CASE next.opcode OF |
1512 | CASE next.opcode OF |
1689 | |IL.opLOAD64: |
1513 | |IL.opLOAD64: |
1690 | movrm(reg1, reg1, param2); |
1514 | movrm(reg1, reg1, param2); |
1691 | cmd := next |
1515 | cmd := next |
1692 | |IL.opLOAD32: |
1516 | |IL.opLOAD32: |
1693 | movrm32(reg1, reg1, param2); |
1517 | movrm32(reg1, reg1, param2); |
1694 | shiftrc(shl, reg1, 32); |
1518 | shiftrc(shl, reg1, 32); |
1695 | shiftrc(shr, reg1, 32); |
1519 | shiftrc(shr, reg1, 32); |
1696 | cmd := next |
1520 | cmd := next |
1697 | |IL.opLOAD16: |
1521 | |IL.opLOAD16: |
1698 | movzx(reg1, reg1, param2, TRUE); |
1522 | movzx(reg1, reg1, param2, TRUE); |
1699 | cmd := next |
1523 | cmd := next |
1700 | |IL.opLOAD8: |
1524 | |IL.opLOAD8: |
1701 | movzx(reg1, reg1, param2, FALSE); |
1525 | movzx(reg1, reg1, param2, FALSE); |
1702 | cmd := next |
1526 | cmd := next |
1703 | |IL.opLOAD64_PARAM: |
1527 | |IL.opLOAD64_PARAM: |
1704 | X86.pushm(reg1, param2); |
1528 | X86.pushm(reg1, param2); |
1705 | drop; |
1529 | drop; |
1706 | cmd := next |
1530 | cmd := next |
1707 | ELSE |
1531 | ELSE |
1708 | IF param2 = 1 THEN |
1532 | IF param2 = 1 THEN |
1709 | incr(reg1) |
1533 | incr(reg1) |
1710 | ELSIF param2 = -1 THEN |
1534 | ELSIF param2 = -1 THEN |
1711 | decr(reg1) |
1535 | decr(reg1) |
1712 | ELSE |
1536 | ELSE |
1713 | addrc(reg1, param2) |
1537 | addrc(reg1, param2) |
1714 | END |
1538 | END |
1715 | END |
1539 | END |
1716 | ELSIF isLong(param2) THEN |
1540 | ELSIF isLong(param2) THEN |
- | 1541 | UnOp(reg1); |
|
1717 | addrc(reg1, param2) |
1542 | addrc(reg1, param2) |
1718 | END |
1543 | END |
1719 | 1544 | ||
1720 | |IL.opDIV: |
1545 | |IL.opDIV: |
1721 | PushAll(2); |
1546 | PushAll(2); |
1722 | CallRTL(IL._divmod); |
1547 | CallRTL(IL._divmod); |
1723 | GetRegA |
1548 | GetRegA |
1724 | 1549 | ||
1725 | |IL.opDIVR: |
1550 | |IL.opDIVR: |
1726 | n := UTILS.Log2(param2); |
1551 | n := UTILS.Log2(param2); |
1727 | IF n > 0 THEN |
1552 | IF n > 0 THEN |
1728 | UnOp(reg1); |
1553 | UnOp(reg1); |
1729 | shiftrc(sar, reg1, n) |
1554 | shiftrc(sar, reg1, n) |
1730 | ELSIF n < 0 THEN |
1555 | ELSIF n < 0 THEN |
1731 | PushAll(1); |
1556 | PushAll(1); |
1732 | pushc(param2); |
1557 | pushc(param2); |
1733 | CallRTL(IL._divmod); |
1558 | CallRTL(IL._divmod); |
1734 | GetRegA |
1559 | GetRegA |
1735 | END |
1560 | END |
1736 | 1561 | ||
1737 | |IL.opDIVL: |
1562 | |IL.opDIVL: |
1738 | UnOp(reg1); |
1563 | UnOp(reg1); |
1739 | REG.PushAll_1(R); |
1564 | REG.PushAll_1(R); |
1740 | pushc(param2); |
1565 | pushc(param2); |
1741 | push(reg1); |
1566 | push(reg1); |
1742 | drop; |
1567 | drop; |
1743 | CallRTL(IL._divmod); |
1568 | CallRTL(IL._divmod); |
1744 | GetRegA |
1569 | GetRegA |
1745 | 1570 | ||
1746 | |IL.opMOD: |
1571 | |IL.opMOD: |
1747 | PushAll(2); |
1572 | PushAll(2); |
1748 | CallRTL(IL._divmod); |
1573 | CallRTL(IL._divmod); |
1749 | mov(rax, rdx); |
1574 | mov(rax, rdx); |
1750 | GetRegA |
1575 | GetRegA |
1751 | 1576 | ||
1752 | |IL.opMODR: |
1577 | |IL.opMODR: |
1753 | n := UTILS.Log2(param2); |
1578 | n := UTILS.Log2(param2); |
1754 | IF n > 0 THEN |
1579 | IF n > 0 THEN |
1755 | UnOp(reg1); |
1580 | UnOp(reg1); |
1756 | andrc(reg1, param2 - 1); |
1581 | andrc(reg1, param2 - 1); |
1757 | ELSIF n < 0 THEN |
1582 | ELSIF n < 0 THEN |
1758 | PushAll(1); |
1583 | PushAll(1); |
1759 | pushc(param2); |
1584 | pushc(param2); |
1760 | CallRTL(IL._divmod); |
1585 | CallRTL(IL._divmod); |
1761 | mov(rax, rdx); |
1586 | mov(rax, rdx); |
1762 | GetRegA |
1587 | GetRegA |
1763 | ELSE |
1588 | ELSE |
1764 | UnOp(reg1); |
1589 | UnOp(reg1); |
1765 | xor(reg1, reg1) |
1590 | xor(reg1, reg1) |
1766 | END |
1591 | END |
1767 | 1592 | ||
1768 | |IL.opMODL: |
1593 | |IL.opMODL: |
1769 | UnOp(reg1); |
1594 | UnOp(reg1); |
1770 | REG.PushAll_1(R); |
1595 | REG.PushAll_1(R); |
1771 | pushc(param2); |
1596 | pushc(param2); |
1772 | push(reg1); |
1597 | push(reg1); |
1773 | drop; |
1598 | drop; |
1774 | CallRTL(IL._divmod); |
1599 | CallRTL(IL._divmod); |
1775 | mov(rax, rdx); |
1600 | mov(rax, rdx); |
1776 | GetRegA |
1601 | GetRegA |
1777 | 1602 | ||
1778 | |IL.opMUL: |
1603 | |IL.opMUL: |
1779 | BinOp(reg1, reg2); |
1604 | BinOp(reg1, reg2); |
1780 | oprr2(0FH, 0AFH, reg2, reg1); (* imul reg1, reg2 *) |
1605 | oprr2(0FH, 0AFH, reg2, reg1); (* imul reg1, reg2 *) |
1781 | drop |
1606 | drop |
1782 | 1607 | ||
1783 | |IL.opMULC: |
1608 | |IL.opMULC: |
1784 | IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN |
1609 | IF (cmd.next(COMMAND).opcode = IL.opADD) & ((param2 = 2) OR (param2 = 4) OR (param2 = 8)) THEN |
1785 | BinOp(reg1, reg2); |
1610 | BinOp(reg1, reg2); |
1786 | OutByte2(48H + 5 * (reg1 DIV 8) + 2 * (reg2 DIV 8), 8DH); (* lea reg1, [reg1 + reg2 * param2] *) |
1611 | OutByte2(48H + 5 * (reg1 DIV 8) + 2 * (reg2 DIV 8), 8DH); (* lea reg1, [reg1 + reg2 * param2] *) |
1787 | reg1 := reg1 MOD 8; |
1612 | reg1 := reg1 MOD 8; |
1788 | reg2 := reg2 MOD 8; |
1613 | reg2 := reg2 MOD 8; |
1789 | OutByte2(04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); |
1614 | OutByte2(04H + reg1 * 8, reg1 + reg2 * 8 + 40H * UTILS.Log2(param2)); |
1790 | drop; |
1615 | drop; |
1791 | cmd := cmd.next(COMMAND) |
1616 | cmd := cmd.next(COMMAND) |
1792 | ELSE |
1617 | ELSE |
1793 | UnOp(reg1); |
1618 | UnOp(reg1); |
1794 | 1619 | ||
1795 | a := param2; |
1620 | a := param2; |
1796 | IF a > 1 THEN |
1621 | IF a > 1 THEN |
1797 | n := UTILS.Log2(a) |
1622 | n := UTILS.Log2(a) |
1798 | ELSIF a < -1 THEN |
1623 | ELSIF a < -1 THEN |
1799 | n := UTILS.Log2(-a) |
1624 | n := UTILS.Log2(-a) |
1800 | ELSE |
1625 | ELSE |
1801 | n := -1 |
1626 | n := -1 |
1802 | END; |
1627 | END; |
1803 | 1628 | ||
1804 | IF a = 1 THEN |
1629 | IF a = 1 THEN |
1805 | 1630 | ||
1806 | ELSIF a = -1 THEN |
1631 | ELSIF a = -1 THEN |
1807 | neg(reg1) |
1632 | neg(reg1) |
1808 | ELSIF a = 0 THEN |
1633 | ELSIF a = 0 THEN |
1809 | xor(reg1, reg1) |
1634 | xor(reg1, reg1) |
1810 | ELSE |
1635 | ELSE |
1811 | IF n > 0 THEN |
1636 | IF n > 0 THEN |
1812 | IF a < 0 THEN |
1637 | IF a < 0 THEN |
1813 | neg(reg1) |
1638 | neg(reg1) |
1814 | END; |
1639 | END; |
1815 | shiftrc(shl, reg1, n) |
1640 | shiftrc(shl, reg1, n) |
1816 | ELSE |
1641 | ELSE |
1817 | IF isLong(a) THEN |
1642 | IF isLong(a) THEN |
1818 | reg2 := GetAnyReg(); |
1643 | reg2 := GetAnyReg(); |
1819 | movabs(reg2, a); |
1644 | movabs(reg2, a); |
1820 | ASSERT(reg1 # reg2); |
1645 | ASSERT(reg1 # reg2); |
1821 | oprr2(0FH, 0AFH, reg2, reg1); (* imul reg1, reg2 *) |
1646 | oprr2(0FH, 0AFH, reg2, reg1); (* imul reg1, reg2 *) |
1822 | drop |
1647 | drop |
1823 | ELSE |
1648 | ELSE |
1824 | (* imul reg1, a *) |
1649 | (* imul reg1, a *) |
1825 | Rex(reg1, reg1); |
1650 | Rex(reg1, reg1); |
1826 | OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9); |
1651 | OutByte2(69H + short(a), 0C0H + (reg1 MOD 8) * 9); |
1827 | OutIntByte(a) |
1652 | OutIntByte(a) |
1828 | END |
1653 | END |
1829 | END |
1654 | END |
1830 | END |
1655 | END |
1831 | END |
1656 | END |
1832 | 1657 | ||
1833 | |IL.opADDS: |
1658 | |IL.opADDS: |
1834 | BinOp(reg1, reg2); |
1659 | BinOp(reg1, reg2); |
1835 | _or(reg1, reg2); |
1660 | _or(reg1, reg2); |
1836 | drop |
1661 | drop |
1837 | 1662 | ||
1838 | |IL.opSUBS: |
1663 | |IL.opSUBS: |
1839 | BinOp(reg1, reg2); |
1664 | BinOp(reg1, reg2); |
1840 | not(reg2); |
1665 | not(reg2); |
1841 | and(reg1, reg2); |
1666 | and(reg1, reg2); |
1842 | drop |
1667 | drop |
1843 | 1668 | ||
1844 | |IL.opNOP, IL.opAND, IL.opOR: |
1669 | |IL.opNOP, IL.opAND, IL.opOR: |
1845 | 1670 | ||
1846 | |IL.opSWITCH: |
1671 | |IL.opSWITCH: |
1847 | UnOp(reg1); |
1672 | UnOp(reg1); |
1848 | IF param2 = 0 THEN |
1673 | IF param2 = 0 THEN |
1849 | reg2 := rax |
1674 | reg2 := rax |
1850 | ELSE |
1675 | ELSE |
1851 | reg2 := r10 |
1676 | reg2 := rcx |
1852 | END; |
1677 | END; |
1853 | IF reg1 # reg2 THEN |
1678 | IF reg1 # reg2 THEN |
1854 | ASSERT(REG.GetReg(R, reg2)); |
1679 | ASSERT(REG.GetReg(R, reg2)); |
1855 | ASSERT(REG.Exchange(R, reg1, reg2)); |
1680 | ASSERT(REG.Exchange(R, reg1, reg2)); |
1856 | drop |
1681 | drop |
1857 | END; |
1682 | END; |
1858 | drop |
1683 | drop |
1859 | 1684 | ||
1860 | |IL.opENDSW: |
1685 | |IL.opENDSW: |
1861 | 1686 | ||
1862 | |IL.opCASEL: |
1687 | |IL.opCASEL: |
1863 | GetRegA; |
1688 | GetRegA; |
1864 | cmprc(rax, param1); |
1689 | cmprc(rax, param1); |
1865 | jcc(jl, param2); |
1690 | jcc(jl, param2); |
1866 | drop |
1691 | drop |
1867 | 1692 | ||
1868 | |IL.opCASER: |
1693 | |IL.opCASER: |
1869 | GetRegA; |
1694 | GetRegA; |
1870 | cmprc(rax, param1); |
1695 | cmprc(rax, param1); |
1871 | jcc(jg, param2); |
1696 | jcc(jg, param2); |
1872 | drop |
1697 | drop |
1873 | 1698 | ||
1874 | |IL.opCASELR: |
1699 | |IL.opCASELR: |
1875 | GetRegA; |
1700 | GetRegA; |
1876 | cmprc(rax, param1); |
1701 | cmprc(rax, param1); |
- | 1702 | IF param2 = cmd.param3 THEN |
|
- | 1703 | jcc(jne, param2) |
|
- | 1704 | ELSE |
|
1877 | jcc(jl, param2); |
1705 | jcc(jl, param2); |
1878 | jcc(jg, cmd.param3); |
1706 | jcc(jg, cmd.param3) |
- | 1707 | END; |
|
1879 | drop |
1708 | drop |
1880 | 1709 | ||
1881 | |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR: |
1710 | |IL.opASR, IL.opROR, IL.opLSL, IL.opLSR: |
- | 1711 | UnOp(reg1); |
|
- | 1712 | IF reg1 # rcx THEN |
|
- | 1713 | ASSERT(REG.GetReg(R, rcx)); |
|
- | 1714 | ASSERT(REG.Exchange(R, reg1, rcx)); |
|
- | 1715 | drop |
|
- | 1716 | END; |
|
- | 1717 | ||
1882 | BinOp(reg1, reg2); |
1718 | BinOp(reg1, reg2); |
1883 | xchg(reg2, rcx); |
1719 | ASSERT(reg2 = rcx); |
1884 | Rex(reg1, 0); |
1720 | Rex(reg1, 0); |
1885 | OutByte(0D3H); |
1721 | OutByte(0D3H); |
1886 | X86.shift(opcode, reg1 MOD 8); (* shift reg1, cl *) |
1722 | X86.shift(opcode, reg1 MOD 8); (* shift reg1, cl *) |
1887 | xchg(reg2, rcx); |
- | |
1888 | drop |
1723 | drop |
1889 | 1724 | ||
1890 | |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1: |
1725 | |IL.opASR1, IL.opROR1, IL.opLSL1, IL.opLSR1: |
- | 1726 | UnOp(reg1); |
|
- | 1727 | IF reg1 # rcx THEN |
|
- | 1728 | ASSERT(REG.GetReg(R, rcx)); |
|
- | 1729 | ASSERT(REG.Exchange(R, reg1, rcx)); |
|
- | 1730 | drop |
|
- | 1731 | END; |
|
- | 1732 | ||
1891 | reg1 := GetAnyReg(); |
1733 | reg1 := GetAnyReg(); |
1892 | movrc(reg1, param2); |
1734 | movrc(reg1, param2); |
1893 | BinOp(reg1, reg2); |
1735 | BinOp(reg1, reg2); |
1894 | xchg(reg1, rcx); |
1736 | ASSERT(reg1 = rcx); |
1895 | Rex(reg2, 0); |
1737 | Rex(reg2, 0); |
1896 | OutByte(0D3H); |
1738 | OutByte(0D3H); |
1897 | X86.shift(opcode, reg2 MOD 8); (* shift reg2, cl *) |
1739 | X86.shift(opcode, reg2 MOD 8); (* shift reg2, cl *) |
1898 | xchg(reg1, rcx); |
- | |
1899 | drop; |
1740 | drop; |
1900 | drop; |
1741 | drop; |
1901 | ASSERT(REG.GetReg(R, reg2)) |
1742 | ASSERT(REG.GetReg(R, reg2)) |
1902 | 1743 | ||
1903 | |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2: |
1744 | |IL.opASR2, IL.opROR2, IL.opLSL2, IL.opLSR2: |
1904 | UnOp(reg1); |
1745 | UnOp(reg1); |
1905 | shiftrc(opcode, reg1, param2 MOD 64) |
1746 | shiftrc(opcode, reg1, param2 MOD 64) |
1906 | 1747 | ||
1907 | |IL.opGET, IL.opGETC: |
1748 | |IL.opGET, IL.opGETC: |
1908 | IF opcode = IL.opGET THEN |
1749 | IF opcode = IL.opGET THEN |
1909 | BinOp(reg1, reg2) |
1750 | BinOp(reg1, reg2) |
1910 | ELSIF opcode = IL.opGETC THEN |
1751 | ELSIF opcode = IL.opGETC THEN |
1911 | UnOp(reg2); |
1752 | UnOp(reg2); |
1912 | reg1 := GetAnyReg(); |
1753 | reg1 := GetAnyReg(); |
1913 | movrc(reg1, param1) |
1754 | movrc(reg1, param1) |
1914 | END; |
1755 | END; |
1915 | drop; |
1756 | drop; |
1916 | drop; |
1757 | drop; |
1917 | X86._movrm(reg1, reg1, 0, param2 * 8, FALSE); |
1758 | X86._movrm(reg1, reg1, 0, param2 * 8, FALSE); |
1918 | X86._movrm(reg1, reg2, 0, param2 * 8, TRUE) |
1759 | X86._movrm(reg1, reg2, 0, param2 * 8, TRUE) |
1919 | 1760 | ||
1920 | |IL.opCHKBYTE: |
1761 | |IL.opCHKBYTE: |
1921 | BinOp(reg1, reg2); |
1762 | BinOp(reg1, reg2); |
1922 | cmprc(reg1, 256); |
1763 | cmprc(reg1, 256); |
1923 | jcc(jb, param1) |
1764 | jcc(jb, param1) |
1924 | 1765 | ||
1925 | |IL.opCHKIDX: |
1766 | |IL.opCHKIDX: |
1926 | UnOp(reg1); |
1767 | UnOp(reg1); |
1927 | cmprc(reg1, param2); |
1768 | cmprc(reg1, param2); |
1928 | jcc(jb, param1) |
1769 | jcc(jb, param1) |
1929 | 1770 | ||
1930 | |IL.opCHKIDX2: |
1771 | |IL.opCHKIDX2: |
1931 | BinOp(reg1, reg2); |
1772 | BinOp(reg1, reg2); |
1932 | IF param2 # -1 THEN |
1773 | IF param2 # -1 THEN |
1933 | cmprr(reg2, reg1); |
1774 | cmprr(reg2, reg1); |
1934 | jcc(jb, param1); |
1775 | jcc(jb, param1); |
1935 | END; |
1776 | END; |
1936 | INCL(R.regs, reg1); |
1777 | INCL(R.regs, reg1); |
1937 | DEC(R.top); |
1778 | DEC(R.top); |
1938 | R.stk[R.top] := reg2 |
1779 | R.stk[R.top] := reg2 |
1939 | 1780 | ||
1940 | |IL.opLENGTH: |
1781 | |IL.opLENGTH: |
1941 | PushAll(2); |
1782 | PushAll(2); |
1942 | CallRTL(IL._length); |
1783 | CallRTL(IL._length); |
1943 | GetRegA |
1784 | GetRegA |
1944 | 1785 | ||
1945 | |IL.opLENGTHW: |
1786 | |IL.opLENGTHW: |
1946 | PushAll(2); |
1787 | PushAll(2); |
1947 | CallRTL(IL._lengthw); |
1788 | CallRTL(IL._lengthw); |
1948 | GetRegA |
1789 | GetRegA |
1949 | 1790 | ||
1950 | |IL.opLEN: |
1791 | |IL.opLEN: |
1951 | n := param2; |
1792 | n := param2; |
1952 | UnOp(reg1); |
1793 | UnOp(reg1); |
1953 | drop; |
1794 | drop; |
1954 | EXCL(R.regs, reg1); |
1795 | EXCL(R.regs, reg1); |
1955 | 1796 | ||
1956 | WHILE n > 0 DO |
1797 | WHILE n > 0 DO |
1957 | UnOp(reg2); |
1798 | UnOp(reg2); |
1958 | drop; |
1799 | drop; |
1959 | DEC(n) |
1800 | DEC(n) |
1960 | END; |
1801 | END; |
1961 | 1802 | ||
1962 | INCL(R.regs, reg1); |
1803 | INCL(R.regs, reg1); |
1963 | ASSERT(REG.GetReg(R, reg1)) |
1804 | ASSERT(REG.GetReg(R, reg1)) |
1964 | 1805 | ||
1965 | |IL.opCHR: |
1806 | |IL.opCHR: |
1966 | UnOp(reg1); |
1807 | UnOp(reg1); |
1967 | andrc(reg1, 255) |
1808 | andrc(reg1, 255) |
1968 | 1809 | ||
1969 | |IL.opWCHR: |
1810 | |IL.opWCHR: |
1970 | UnOp(reg1); |
1811 | UnOp(reg1); |
1971 | andrc(reg1, 65535) |
1812 | andrc(reg1, 65535) |
1972 | 1813 | ||
1973 | |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP: |
1814 | |IL.opEQP, IL.opNEP, IL.opEQIP, IL.opNEIP: |
1974 | UnOp(reg1); |
1815 | UnOp(reg1); |
1975 | reg2 := GetAnyReg(); |
1816 | reg2 := GetAnyReg(); |
1976 | 1817 | ||
1977 | CASE opcode OF |
1818 | CASE opcode OF |
1978 | |IL.opEQP, IL.opNEP: |
1819 | |IL.opEQP, IL.opNEP: |
1979 | lea(reg2, param1, sCODE) |
1820 | lea(reg2, param1, sCODE) |
1980 | 1821 | ||
1981 | |IL.opEQIP, IL.opNEIP: |
1822 | |IL.opEQIP, IL.opNEIP: |
1982 | lea(reg2, param1, sIMP); |
1823 | lea(reg2, param1, sIMP); |
1983 | movrm(reg2, reg2, 0) |
1824 | movrm(reg2, reg2, 0) |
1984 | END; |
1825 | END; |
1985 | 1826 | ||
1986 | cmprr(reg1, reg2); |
1827 | cmprr(reg1, reg2); |
1987 | drop; |
1828 | drop; |
1988 | drop; |
1829 | drop; |
1989 | reg1 := GetAnyReg(); |
1830 | reg1 := GetAnyReg(); |
1990 | 1831 | ||
1991 | CASE opcode OF |
1832 | CASE opcode OF |
1992 | |IL.opEQP, IL.opEQIP: X86.setcc(sete, reg1) |
1833 | |IL.opEQP, IL.opEQIP: X86.setcc(sete, reg1) |
1993 | |IL.opNEP, IL.opNEIP: X86.setcc(setne, reg1) |
1834 | |IL.opNEP, IL.opNEIP: X86.setcc(setne, reg1) |
1994 | END; |
1835 | END; |
1995 | 1836 | ||
1996 | andrc(reg1, 1) |
1837 | andrc(reg1, 1) |
1997 | 1838 | ||
1998 | |IL.opINCCB, IL.opDECCB: |
1839 | |IL.opINCCB, IL.opDECCB: |
1999 | UnOp(reg1); |
1840 | UnOp(reg1); |
2000 | IF reg1 >= 8 THEN |
1841 | IF reg1 >= 8 THEN |
2001 | OutByte(41H) |
1842 | OutByte(41H) |
2002 | END; |
1843 | END; |
2003 | OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1 MOD 8, param2 MOD 256); (* add/sub byte[reg1], param2 MOD 256 *) |
1844 | OutByte3(80H, 28H * ORD(opcode = IL.opDECCB) + reg1 MOD 8, param2 MOD 256); (* add/sub byte[reg1], param2 MOD 256 *) |
2004 | drop |
1845 | drop |
2005 | 1846 | ||
2006 | |IL.opINCB, IL.opDECB: |
1847 | |IL.opINCB, IL.opDECB: |
2007 | BinOp(reg1, reg2); |
1848 | BinOp(reg1, reg2); |
2008 | IF (reg1 >= 8) OR (reg2 >= 8) THEN |
1849 | IF (reg1 >= 8) OR (reg2 >= 8) THEN |
2009 | OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8)) |
1850 | OutByte(40H + reg2 DIV 8 + 4 * (reg1 DIV 8)) |
2010 | END; |
1851 | END; |
2011 | OutByte2(28H * ORD(opcode = IL.opDECB), reg2 MOD 8 + 8 * (reg1 MOD 8)); (* add/sub byte[reg2], reg1_8 *) |
1852 | OutByte2(28H * ORD(opcode = IL.opDECB), reg2 MOD 8 + 8 * (reg1 MOD 8)); (* add/sub byte[reg2], reg1_8 *) |
2012 | drop; |
1853 | drop; |
2013 | drop |
1854 | drop |
2014 | 1855 | ||
2015 | |IL.opSAVEIP: |
1856 | |IL.opSAVEIP: |
2016 | UnOp(reg1); |
1857 | UnOp(reg1); |
2017 | reg2 := GetAnyReg(); |
1858 | reg2 := GetAnyReg(); |
2018 | lea(reg2, param2, sIMP); |
1859 | lea(reg2, param2, sIMP); |
2019 | movrm(reg2, reg2, 0); |
1860 | movrm(reg2, reg2, 0); |
2020 | push(reg2); |
1861 | push(reg2); |
2021 | drop; |
1862 | drop; |
2022 | IF reg1 >= 8 THEN |
1863 | IF reg1 >= 8 THEN |
2023 | OutByte(41H) |
1864 | OutByte(41H) |
2024 | END; |
1865 | END; |
2025 | OutByte2(8FH, reg1 MOD 8); (* pop qword[reg1] *) |
1866 | OutByte2(8FH, reg1 MOD 8); (* pop qword[reg1] *) |
2026 | drop |
1867 | drop |
2027 | 1868 | ||
2028 | |IL.opCLEANUP: |
1869 | |IL.opCLEANUP: |
2029 | IF param2 # 0 THEN |
1870 | IF param2 # 0 THEN |
2030 | addrc(rsp, param2 * 8) |
1871 | addrc(rsp, param2 * 8) |
2031 | END |
1872 | END |
2032 | 1873 | ||
2033 | |IL.opPOPSP: |
1874 | |IL.opPOPSP: |
2034 | pop(rsp) |
1875 | pop(rsp) |
2035 | 1876 | ||
2036 | |IL.opLOADF: |
1877 | |IL.opLOADF: |
2037 | UnOp(reg1); |
1878 | UnOp(reg1); |
2038 | INC(xmm); |
1879 | INC(xmm); |
2039 | IF xmm > MAX_XMM THEN |
1880 | IF xmm > MAX_XMM THEN |
2040 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
1881 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
2041 | END; |
1882 | END; |
2042 | movsdrm(xmm, reg1, 0); |
1883 | movsdrm(xmm, reg1, 0); |
2043 | drop |
1884 | drop |
2044 | 1885 | ||
2045 | |IL.opPUSHF: |
1886 | |IL.opPUSHF: |
2046 | ASSERT(xmm >= 0); |
1887 | ASSERT(xmm >= 0); |
2047 | subrc(rsp, 8); |
1888 | subrc(rsp, 8); |
2048 | movsdmr(rsp, 0, xmm); |
1889 | movsdmr(rsp, 0, xmm); |
2049 | DEC(xmm) |
1890 | DEC(xmm) |
2050 | 1891 | ||
2051 | |IL.opCONSTF: |
1892 | |IL.opCONSTF: |
2052 | float := cmd.float; |
1893 | float := cmd.float; |
2053 | INC(xmm); |
1894 | INC(xmm); |
2054 | IF xmm > MAX_XMM THEN |
1895 | IF xmm > MAX_XMM THEN |
2055 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
1896 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
2056 | END; |
1897 | END; |
2057 | (* movsd xmm, qword ptr [rip + Numbers_Offs + Numbers_Count * 8 + DATA] *) |
1898 | (* movsd xmm, qword ptr [rip + Numbers_Offs + Numbers_Count * 8 + DATA] *) |
2058 | OutByte(0F2H); |
1899 | OutByte(0F2H); |
2059 | IF xmm >= 8 THEN |
1900 | IF xmm >= 8 THEN |
2060 | OutByte(44H) |
1901 | OutByte(44H) |
2061 | END; |
1902 | END; |
2062 | OutByte3(0FH, 10H, 05H + 8 * (xmm MOD 8)); |
1903 | OutByte3(0FH, 10H, 05H + 8 * (xmm MOD 8)); |
2063 | X86.Reloc(sDATA, Numbers_Offs + Numbers_Count * 8); |
1904 | X86.Reloc(sDATA, Numbers_Offs + Numbers_Count * 8); |
2064 | NewNumber(UTILS.splitf(float, a, b)) |
1905 | NewNumber(UTILS.splitf(float, a, b)) |
2065 | 1906 | ||
2066 | |IL.opSAVEF, IL.opSAVEFI: |
1907 | |IL.opSAVEF, IL.opSAVEFI: |
2067 | ASSERT(xmm >= 0); |
1908 | ASSERT(xmm >= 0); |
2068 | UnOp(reg1); |
1909 | UnOp(reg1); |
2069 | movsdmr(reg1, 0, xmm); |
1910 | movsdmr(reg1, 0, xmm); |
2070 | DEC(xmm); |
1911 | DEC(xmm); |
2071 | drop |
1912 | drop |
2072 | 1913 | ||
2073 | |IL.opADDF: |
1914 | |IL.opADDF: |
2074 | ASSERT(xmm >= 1); |
1915 | ASSERT(xmm >= 1); |
2075 | opxx(58H, xmm - 1, xmm); |
1916 | opxx(58H, xmm - 1, xmm); |
2076 | DEC(xmm) |
1917 | DEC(xmm) |
2077 | 1918 | ||
2078 | |IL.opSUBF: |
1919 | |IL.opSUBF: |
2079 | ASSERT(xmm >= 1); |
1920 | ASSERT(xmm >= 1); |
2080 | opxx(5CH, xmm - 1, xmm); |
1921 | opxx(5CH, xmm - 1, xmm); |
2081 | DEC(xmm) |
1922 | DEC(xmm) |
2082 | 1923 | ||
2083 | |IL.opSUBFI: |
1924 | |IL.opSUBFI: |
2084 | ASSERT(xmm >= 1); |
1925 | ASSERT(xmm >= 1); |
2085 | opxx(5CH, xmm, xmm - 1); |
1926 | opxx(5CH, xmm, xmm - 1); |
2086 | opxx(10H, xmm - 1, xmm); |
1927 | opxx(10H, xmm - 1, xmm); |
2087 | DEC(xmm) |
1928 | DEC(xmm) |
2088 | 1929 | ||
2089 | |IL.opMULF: |
1930 | |IL.opMULF: |
2090 | ASSERT(xmm >= 1); |
1931 | ASSERT(xmm >= 1); |
2091 | opxx(59H, xmm - 1, xmm); |
1932 | opxx(59H, xmm - 1, xmm); |
2092 | DEC(xmm) |
1933 | DEC(xmm) |
2093 | 1934 | ||
2094 | |IL.opDIVF: |
1935 | |IL.opDIVF: |
2095 | ASSERT(xmm >= 1); |
1936 | ASSERT(xmm >= 1); |
2096 | opxx(5EH, xmm - 1, xmm); |
1937 | opxx(5EH, xmm - 1, xmm); |
2097 | DEC(xmm) |
1938 | DEC(xmm) |
2098 | 1939 | ||
2099 | |IL.opDIVFI: |
1940 | |IL.opDIVFI: |
2100 | ASSERT(xmm >= 1); |
1941 | ASSERT(xmm >= 1); |
2101 | opxx(5EH, xmm, xmm - 1); |
1942 | opxx(5EH, xmm, xmm - 1); |
2102 | opxx(10H, xmm - 1, xmm); |
1943 | opxx(10H, xmm - 1, xmm); |
2103 | DEC(xmm) |
1944 | DEC(xmm) |
2104 | 1945 | ||
2105 | |IL.opFABS, IL.opUMINF: (* andpd/xorpd xmm, xmmword[rip + Numbers_Offs + (16) + DATA] *) |
1946 | |IL.opFABS, IL.opUMINF: (* andpd/xorpd xmm, xmmword[rip + Numbers_Offs + (16) + DATA] *) |
2106 | ASSERT(xmm >= 0); |
1947 | ASSERT(xmm >= 0); |
2107 | OutByte(66H); |
1948 | OutByte(66H); |
2108 | IF xmm >= 8 THEN |
1949 | IF xmm >= 8 THEN |
2109 | OutByte(44H) |
1950 | OutByte(44H) |
2110 | END; |
1951 | END; |
2111 | OutByte3(0FH, 54H + 3 * ORD(opcode = IL.opUMINF), 05H + (xmm MOD 8) * 8); |
1952 | OutByte3(0FH, 54H + 3 * ORD(opcode = IL.opUMINF), 05H + (xmm MOD 8) * 8); |
2112 | X86.Reloc(sDATA, Numbers_Offs + 16 * ORD(opcode = IL.opFABS)) |
1953 | X86.Reloc(sDATA, Numbers_Offs + 16 * ORD(opcode = IL.opFABS)) |
2113 | 1954 | ||
2114 | |IL.opFLT: |
1955 | |IL.opFLT: |
2115 | UnOp(reg1); |
1956 | UnOp(reg1); |
2116 | INC(xmm); |
1957 | INC(xmm); |
2117 | IF xmm > MAX_XMM THEN |
1958 | IF xmm > MAX_XMM THEN |
2118 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
1959 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
2119 | END; |
1960 | END; |
2120 | OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); (* cvtsi2sd xmm, reg1 *) |
1961 | OutByte(0F2H); Rex(reg1, xmm); OutByte(0FH); (* cvtsi2sd xmm, reg1 *) |
2121 | OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8); |
1962 | OutByte2(2AH, 0C0H + (xmm MOD 8) * 8 + reg1 MOD 8); |
2122 | drop |
1963 | drop |
2123 | 1964 | ||
2124 | |IL.opFLOOR: |
1965 | |IL.opFLOOR: |
2125 | ASSERT(xmm >= 0); |
1966 | ASSERT(xmm >= 0); |
2126 | reg1 := GetAnyReg(); |
1967 | reg1 := GetAnyReg(); |
2127 | subrc(rsp, 8); |
1968 | subrc(rsp, 8); |
2128 | OutByte3(00FH, 0AEH, 05CH); OutByte2(024H, 004H); (* stmxcsr dword[rsp+4]; *) |
1969 | OutByte3(00FH, 0AEH, 05CH); OutByte2(024H, 004H); (* stmxcsr dword[rsp+4]; *) |
2129 | OutByte2(00FH, 0AEH); OutByte2(01CH, 024H); (* stmxcsr dword[rsp]; *) |
1970 | OutByte2(00FH, 0AEH); OutByte2(01CH, 024H); (* stmxcsr dword[rsp]; *) |
2130 | OutByte3(081H, 024H, 024H); OutByte2(0FFH, 09FH); OutByte2(0FFH, 0FFH); (* and dword[rsp],11111111111111111001111111111111b; *) |
1971 | OutByte3(081H, 024H, 024H); OutByte2(0FFH, 09FH); OutByte2(0FFH, 0FFH); (* and dword[rsp],11111111111111111001111111111111b; *) |
2131 | OutByte3(081H, 00CH, 024H); OutByte2(000H, 020H); OutByte2(000H, 000H); (* or dword[rsp],00000000000000000010000000000000b; *) |
1972 | OutByte3(081H, 00CH, 024H); OutByte2(000H, 020H); OutByte2(000H, 000H); (* or dword[rsp],00000000000000000010000000000000b; *) |
2132 | OutByte2(00FH, 0AEH); OutByte2(014H, 024H); (* ldmxcsr dword[rsp]; *) |
1973 | OutByte2(00FH, 0AEH); OutByte2(014H, 024H); (* ldmxcsr dword[rsp]; *) |
2133 | OutByte(0F2H); Rex(xmm, reg1); OutByte(0FH); (* cvtsd2si reg1, xmm *) |
1974 | OutByte(0F2H); Rex(xmm, reg1); OutByte(0FH); (* cvtsd2si reg1, xmm *) |
2134 | OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8); |
1975 | OutByte2(2DH, 0C0H + xmm MOD 8 + (reg1 MOD 8) * 8); |
2135 | OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H); (* ldmxcsr dword[rsp+4]; *) |
1976 | OutByte3(00FH, 0AEH, 054H); OutByte2(024H, 004H); (* ldmxcsr dword[rsp+4]; *) |
2136 | addrc(rsp, 8); |
1977 | addrc(rsp, 8); |
2137 | DEC(xmm) |
1978 | DEC(xmm) |
2138 | 1979 | ||
2139 | |IL.opEQF .. IL.opGEF: |
1980 | |IL.opEQF .. IL.opGEF: |
2140 | ASSERT(xmm >= 1); |
1981 | ASSERT(xmm >= 1); |
2141 | fcmp(opcode, xmm); |
1982 | fcmp(opcode, xmm); |
2142 | DEC(xmm, 2) |
1983 | DEC(xmm, 2) |
2143 | 1984 | ||
2144 | |IL.opINF: |
1985 | |IL.opINF: |
2145 | INC(xmm); |
1986 | INC(xmm); |
2146 | IF xmm > MAX_XMM THEN |
1987 | IF xmm > MAX_XMM THEN |
2147 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
1988 | ERRORS.ErrorMsg(fname, param1, param2, FPR_ERR) |
2148 | END; |
1989 | END; |
2149 | (* movsd xmm, qword ptr [rip + Numbers_Offs + 32 + DATA] *) |
1990 | (* movsd xmm, qword ptr [rip + Numbers_Offs + 32 + DATA] *) |
2150 | OutByte(0F2H); |
1991 | OutByte(0F2H); |
2151 | IF xmm >= 8 THEN |
1992 | IF xmm >= 8 THEN |
2152 | OutByte(44H) |
1993 | OutByte(44H) |
2153 | END; |
1994 | END; |
2154 | OutByte3(0FH, 10H, 05H + 8 * (xmm MOD 8)); |
1995 | OutByte3(0FH, 10H, 05H + 8 * (xmm MOD 8)); |
2155 | X86.Reloc(sDATA, Numbers_Offs + 32) |
1996 | X86.Reloc(sDATA, Numbers_Offs + 32) |
2156 | 1997 | ||
2157 | |IL.opPACK, IL.opPACKC: |
1998 | |IL.opPACK, IL.opPACKC: |
2158 | IF opcode = IL.opPACK THEN |
1999 | IF opcode = IL.opPACK THEN |
2159 | BinOp(reg1, reg2) |
2000 | BinOp(reg1, reg2) |
2160 | ELSE |
2001 | ELSE |
2161 | UnOp(reg1); |
2002 | UnOp(reg1); |
2162 | reg2 := GetAnyReg(); |
2003 | reg2 := GetAnyReg(); |
2163 | movrc(reg2, param2) |
2004 | movrc(reg2, param2) |
2164 | END; |
2005 | END; |
2165 | push(reg1); |
2006 | push(reg1); |
2166 | movrm(reg1, reg1, 0); |
2007 | movrm(reg1, reg1, 0); |
2167 | shiftrc(shl, reg1, 1); |
2008 | shiftrc(shl, reg1, 1); |
2168 | shiftrc(shr, reg1, 53); |
2009 | shiftrc(shr, reg1, 53); |
2169 | add(reg1, reg2); |
2010 | add(reg1, reg2); |
2170 | andrc(reg1, ORD({0..10})); |
2011 | andrc(reg1, ORD({0..10})); |
2171 | shiftrc(shl, reg1, 52); |
2012 | shiftrc(shl, reg1, 52); |
2172 | movrm(reg2, rsp, 0); |
2013 | movrm(reg2, rsp, 0); |
2173 | movrm(reg2, reg2, 0); |
2014 | movrm(reg2, reg2, 0); |
2174 | 2015 | ||
2175 | push(reg1); |
2016 | push(reg1); |
2176 | lea(reg1, Numbers_Offs + 40, sDATA); (* {0..51, 63} *) |
2017 | lea(reg1, Numbers_Offs + 40, sDATA); (* {0..51, 63} *) |
2177 | movrm(reg1, reg1, 0); |
2018 | movrm(reg1, reg1, 0); |
2178 | and(reg2, reg1); |
2019 | and(reg2, reg1); |
2179 | pop(reg1); |
2020 | pop(reg1); |
2180 | 2021 | ||
2181 | _or(reg2, reg1); |
2022 | _or(reg2, reg1); |
2182 | pop(reg1); |
2023 | pop(reg1); |
2183 | movmr(reg1, 0, reg2); |
2024 | movmr(reg1, 0, reg2); |
2184 | drop; |
2025 | drop; |
2185 | drop |
2026 | drop |
2186 | 2027 | ||
2187 | |IL.opUNPK, IL.opLADR_UNPK: |
2028 | |IL.opUNPK, IL.opLADR_UNPK: |
2188 | 2029 | ||
2189 | IF opcode = IL.opLADR_UNPK THEN |
2030 | IF opcode = IL.opLADR_UNPK THEN |
2190 | n := param2 * 8; |
2031 | n := param2 * 8; |
2191 | UnOp(reg1); |
2032 | UnOp(reg1); |
2192 | reg2 := GetVarReg(param2); |
- | |
2193 | regVar := reg2 # -1; |
- | |
2194 | IF ~regVar THEN |
- | |
2195 | reg2 := GetAnyReg(); |
2033 | reg2 := GetAnyReg(); |
2196 | Rex(0, reg2); |
2034 | Rex(0, reg2); |
2197 | OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8); (* lea reg2, qword[rbp+n] *) |
2035 | OutByte2(8DH, 45H + long(n) + (reg2 MOD 8) * 8); (* lea reg2, qword[rbp+n] *) |
2198 | OutIntByte(n) |
2036 | OutIntByte(n) |
2199 | END |
- | |
2200 | ELSE |
2037 | ELSE |
2201 | BinOp(reg1, reg2); |
2038 | BinOp(reg1, reg2) |
2202 | regVar := FALSE |
- | |
2203 | END; |
2039 | END; |
2204 | 2040 | ||
2205 | push(reg1); |
2041 | push(reg1); |
2206 | movrm(reg1, reg1, 0); |
2042 | movrm(reg1, reg1, 0); |
2207 | shiftrc(shl, reg1, 1); |
2043 | shiftrc(shl, reg1, 1); |
2208 | shiftrc(shr, reg1, 53); |
2044 | shiftrc(shr, reg1, 53); |
2209 | subrc(reg1, 1023); |
2045 | subrc(reg1, 1023); |
2210 | - | ||
2211 | IF regVar THEN |
- | |
2212 | mov(reg2, reg1); |
- | |
2213 | reg2 := GetAnyReg() |
- | |
2214 | ELSE |
2046 | |
2215 | movmr(reg2, 0, reg1) |
- | |
2216 | END; |
2047 | movmr(reg2, 0, reg1); |
2217 | 2048 | ||
2218 | pop(reg2); |
2049 | pop(reg2); |
2219 | movrm(reg1, reg2, 0); |
2050 | movrm(reg1, reg2, 0); |
2220 | 2051 | ||
2221 | push(reg2); |
2052 | push(reg2); |
2222 | lea(reg2, Numbers_Offs + 48, sDATA); (* {52..61} *) |
2053 | lea(reg2, Numbers_Offs + 48, sDATA); (* {52..61} *) |
2223 | movrm(reg2, reg2, 0); |
2054 | movrm(reg2, reg2, 0); |
2224 | _or(reg1, reg2); |
2055 | _or(reg1, reg2); |
2225 | pop(reg2); |
2056 | pop(reg2); |
2226 | 2057 | ||
2227 | Rex(reg1, 0); |
2058 | Rex(reg1, 0); |
2228 | OutByte2(0FH, 0BAH); |
2059 | OutByte2(0FH, 0BAH); |
2229 | OutByte2(0F0H + reg1 MOD 8, 3EH); (* btr reg1, 62 *) |
2060 | OutByte2(0F0H + reg1 MOD 8, 3EH); (* btr reg1, 62 *) |
2230 | movmr(reg2, 0, reg1); |
2061 | movmr(reg2, 0, reg1); |
2231 | drop; |
2062 | drop; |
2232 | drop |
2063 | drop |
2233 | 2064 | ||
2234 | |IL.opSADR_PARAM: |
2065 | |IL.opSADR_PARAM: |
2235 | pushDA(stroffs + param2) |
2066 | pushDA(stroffs + param2) |
2236 | 2067 | ||
2237 | |IL.opVADR_PARAM: |
2068 | |IL.opVADR_PARAM: |
2238 | X86.pushm(rbp, param2 * 8) |
2069 | X86.pushm(rbp, param2 * 8) |
2239 | 2070 | ||
2240 | |IL.opLOAD64_PARAM: |
2071 | |IL.opLOAD64_PARAM: |
2241 | UnOp(reg1); |
2072 | UnOp(reg1); |
2242 | X86.pushm(reg1, 0); |
2073 | X86.pushm(reg1, 0); |
2243 | drop |
2074 | drop |
2244 | 2075 | ||
2245 | |IL.opLLOAD64_PARAM: |
2076 | |IL.opLLOAD64_PARAM: |
2246 | reg1 := GetVarReg(param2); |
- | |
2247 | IF reg1 # -1 THEN |
- | |
2248 | push(reg1) |
- | |
2249 | ELSE |
- | |
2250 | X86.pushm(rbp, param2 * 8) |
2077 | X86.pushm(rbp, param2 * 8) |
2251 | END |
- | |
2252 | 2078 | ||
2253 | |IL.opGLOAD64_PARAM: |
2079 | |IL.opGLOAD64_PARAM: |
2254 | OutByte2(0FFH, 35H); (* push qword[rip + param2 + BSS] *) |
2080 | OutByte2(0FFH, 35H); (* push qword[rip + param2 + BSS] *) |
2255 | X86.Reloc(sBSS, param2) |
2081 | X86.Reloc(sBSS, param2) |
2256 | 2082 | ||
2257 | |IL.opCONST_PARAM: |
2083 | |IL.opCONST_PARAM: |
2258 | pushc(param2) |
2084 | pushc(param2) |
2259 | 2085 | ||
2260 | |IL.opGLOAD32_PARAM, IL.opLOAD32_PARAM: |
2086 | |IL.opGLOAD32_PARAM, IL.opLOAD32_PARAM: |
2261 | IF opcode = IL.opGLOAD32_PARAM THEN |
2087 | IF opcode = IL.opGLOAD32_PARAM THEN |
2262 | reg1 := GetAnyReg(); |
2088 | reg1 := GetAnyReg(); |
2263 | lea(reg1, param2, sBSS) |
2089 | lea(reg1, param2, sBSS) |
2264 | ELSE |
2090 | ELSE |
2265 | UnOp(reg1) |
2091 | UnOp(reg1) |
2266 | END; |
2092 | END; |
2267 | movrm32(reg1, reg1, 0); |
2093 | movrm32(reg1, reg1, 0); |
2268 | shiftrc(shl, reg1, 32); |
2094 | shiftrc(shl, reg1, 32); |
2269 | shiftrc(shr, reg1, 32); |
2095 | shiftrc(shr, reg1, 32); |
2270 | push(reg1); |
2096 | push(reg1); |
2271 | drop |
2097 | drop |
2272 | 2098 | ||
2273 | |IL.opLLOAD32_PARAM: |
2099 | |IL.opLLOAD32_PARAM: |
2274 | reg1 := GetAnyReg(); |
2100 | reg1 := GetAnyReg(); |
2275 | reg2 := GetVarReg(param2); |
- | |
2276 | IF reg2 # -1 THEN |
- | |
2277 | mov(reg1, reg2) |
- | |
2278 | ELSE |
- | |
2279 | movrm32(reg1, rbp, param2 * 8) |
2101 | movrm32(reg1, rbp, param2 * 8); |
2280 | END; |
- | |
2281 | shiftrc(shl, reg1, 32); |
2102 | shiftrc(shl, reg1, 32); |
2282 | shiftrc(shr, reg1, 32); |
2103 | shiftrc(shr, reg1, 32); |
2283 | push(reg1); |
2104 | push(reg1); |
2284 | drop |
2105 | drop |
2285 | 2106 | ||
2286 | |IL.opLADR_SAVEC: |
2107 | |IL.opLADR_SAVEC: |
2287 | n := param1 * 8; |
2108 | n := param1 * 8; |
2288 | reg1 := GetVarReg(param1); |
- | |
2289 | IF reg1 # -1 THEN |
- | |
2290 | movrc(reg1, param2) |
- | |
2291 | ELSE |
- | |
2292 | IF isLong(param2) THEN |
2109 | IF isLong(param2) THEN |
2293 | reg2 := GetAnyReg(); |
2110 | reg2 := GetAnyReg(); |
2294 | movrc(reg2, param2); |
2111 | movrc(reg2, param2); |
2295 | movmr(rbp, n, reg2); |
2112 | movmr(rbp, n, reg2); |
2296 | drop |
2113 | drop |
2297 | ELSE |
2114 | ELSE |
2298 | OutByte3(48H, 0C7H, 45H + long(n)); (* mov qword[rbp+n], param2 *) |
2115 | OutByte3(48H, 0C7H, 45H + long(n)); (* mov qword[rbp+n], param2 *) |
2299 | OutIntByte(n); |
2116 | OutIntByte(n); |
2300 | OutInt(param2) |
2117 | OutInt(param2) |
2301 | END |
2118 | END |
2302 | END |
- | |
2303 | 2119 | ||
2304 | |IL.opGADR_SAVEC: |
2120 | |IL.opGADR_SAVEC: |
2305 | IF isLong(param2) THEN |
2121 | IF isLong(param2) THEN |
2306 | reg1 := GetAnyReg(); |
2122 | reg1 := GetAnyReg(); |
2307 | movrc(reg1, param2); |
2123 | movrc(reg1, param2); |
2308 | reg2 := GetAnyReg(); |
2124 | reg2 := GetAnyReg(); |
2309 | lea(reg2, param1, sBSS); |
2125 | lea(reg2, param1, sBSS); |
2310 | movmr(reg2, 0, reg1); |
2126 | movmr(reg2, 0, reg1); |
2311 | drop; |
2127 | drop; |
2312 | drop |
2128 | drop |
2313 | ELSE |
2129 | ELSE |
2314 | (* mov qword[rip + param1 - 4 + BSS], param2 *) |
2130 | (* mov qword[rip + param1 - 4 + BSS], param2 *) |
2315 | OutByte3(48H, 0C7H, 05H); |
2131 | OutByte3(48H, 0C7H, 05H); |
2316 | X86.Reloc(sBSS, param1 - 4); |
2132 | X86.Reloc(sBSS, param1 - 4); |
2317 | OutInt(param2) |
2133 | OutInt(param2) |
2318 | END |
2134 | END |
2319 | 2135 | ||
2320 | |IL.opLADR_SAVE: |
2136 | |IL.opLADR_SAVE: |
2321 | UnOp(reg1); |
2137 | UnOp(reg1); |
2322 | reg2 := GetVarReg(param2); |
- | |
2323 | IF reg2 # -1 THEN |
- | |
2324 | mov(reg2, reg1) |
- | |
2325 | ELSE |
- | |
2326 | movmr(rbp, param2 * 8, reg1) |
2138 | movmr(rbp, param2 * 8, reg1); |
2327 | END; |
- | |
2328 | drop |
2139 | drop |
2329 | 2140 | ||
2330 | |IL.opLADR_INCC: |
2141 | |IL.opLADR_INCC: |
2331 | reg1 := GetVarReg(param1); |
- | |
2332 | IF isLong(param2) THEN |
2142 | IF isLong(param2) THEN |
2333 | reg2 := GetAnyReg(); |
2143 | reg2 := GetAnyReg(); |
2334 | movrc(reg2, param2); |
2144 | movrc(reg2, param2); |
2335 | IF reg1 # -1 THEN |
- | |
2336 | add(reg1, reg2) |
- | |
2337 | ELSE |
- | |
2338 | n := param1 * 8; |
2145 | n := param1 * 8; |
2339 | Rex(0, reg2); |
2146 | Rex(0, reg2); |
2340 | OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8); |
2147 | OutByte2(01H, 45H + long(n) + (reg2 MOD 8) * 8); |
2341 | OutIntByte(n) (* add qword[rbp+n], reg2 *) |
2148 | OutIntByte(n); (* add qword[rbp+n], reg2 *) |
2342 | END; |
- | |
2343 | drop |
2149 | drop |
2344 | ELSIF ABS(param2) = 1 THEN |
2150 | ELSIF ABS(param2) = 1 THEN |
2345 | IF reg1 # -1 THEN |
- | |
2346 | IF param2 = 1 THEN |
- | |
2347 | incr(reg1) |
- | |
2348 | ELSE |
- | |
2349 | decr(reg1) |
- | |
2350 | END |
- | |
2351 | ELSE |
- | |
2352 | n := param1 * 8; |
2151 | n := param1 * 8; |
2353 | OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec qword[rbp+n] *) |
2152 | OutByte3(48H, 0FFH, 45H + 8 * ORD(param2 = -1) + long(n)); (* inc/dec qword[rbp+n] *) |
2354 | OutIntByte(n) |
2153 | OutIntByte(n) |
2355 | END |
- | |
2356 | ELSE |
- | |
2357 | IF reg1 # -1 THEN |
- | |
2358 | addrc(reg1, param2) |
- | |
2359 | ELSE |
2154 | ELSE |
2360 | n := param1 * 8; |
2155 | n := param1 * 8; |
2361 | OutByte3(48H, 81H + short(param2), 45H + long(n)); |
2156 | OutByte3(48H, 81H + short(param2), 45H + long(n)); |
2362 | OutIntByte(n); |
2157 | OutIntByte(n); |
2363 | OutIntByte(param2) (* add qword[rbp+n], param2 *) |
2158 | OutIntByte(param2) (* add qword[rbp+n], param2 *) |
2364 | END |
2159 | END |
2365 | END |
- | |
2366 | 2160 | ||
2367 | |IL.opLADR_INCCB, IL.opLADR_DECCB: |
- | |
2368 | reg1 := GetVarReg(param1); |
2161 | |IL.opLADR_INCCB, IL.opLADR_DECCB: |
2369 | param2 := param2 MOD 256; |
- | |
2370 | IF reg1 # -1 THEN |
- | |
2371 | IF opcode = IL.opLADR_DECCB THEN |
- | |
2372 | subrc(reg1, param2) |
- | |
2373 | ELSE |
- | |
2374 | addrc(reg1, param2) |
- | |
2375 | END; |
- | |
2376 | andrc(reg1, 255) |
- | |
2377 | ELSE |
2162 | param2 := param2 MOD 256; |
2378 | n := param1 * 8; |
2163 | n := param1 * 8; |
2379 | OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB)); |
2164 | OutByte2(80H, 45H + long(n) + 28H * ORD(opcode = IL.opLADR_DECCB)); |
2380 | OutIntByte(n); |
2165 | OutIntByte(n); |
2381 | OutByte(param2) (* add/sub byte[rbp+n], param2 *) |
2166 | OutByte(param2) (* add/sub byte[rbp+n], param2 *) |
2382 | END |
- | |
2383 | 2167 | ||
2384 | |IL.opLADR_INC, IL.opLADR_DEC: |
2168 | |IL.opLADR_INC, IL.opLADR_DEC: |
2385 | UnOp(reg1); |
2169 | UnOp(reg1); |
2386 | reg2 := GetVarReg(param2); |
- | |
2387 | IF reg2 # -1 THEN |
- | |
2388 | IF opcode = IL.opLADR_DEC THEN |
- | |
2389 | sub(reg2, reg1) |
- | |
2390 | ELSE |
- | |
2391 | add(reg2, reg1) |
- | |
2392 | END |
- | |
2393 | ELSE |
- | |
2394 | n := param2 * 8; |
2170 | n := param2 * 8; |
2395 | Rex(0, reg1); |
2171 | Rex(0, reg1); |
2396 | OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8); |
2172 | OutByte2(01H + 28H * ORD(opcode = IL.opLADR_DEC), 45H + long(n) + (reg1 MOD 8) * 8); |
2397 | OutIntByte(n) (* add/sub qword[rbp+n], reg1 *) |
2173 | OutIntByte(n); (* add/sub qword[rbp+n], reg1 *) |
2398 | END; |
- | |
2399 | drop |
2174 | drop |
2400 | 2175 | ||
2401 | |IL.opLADR_INCB, IL.opLADR_DECB: |
2176 | |IL.opLADR_INCB, IL.opLADR_DECB: |
2402 | UnOp(reg1); |
2177 | UnOp(reg1); |
2403 | reg2 := GetVarReg(param2); |
- | |
2404 | IF reg2 # -1 THEN |
- | |
2405 | IF opcode = IL.opLADR_DECB THEN |
- | |
2406 | sub(reg2, reg1) |
- | |
2407 | ELSE |
- | |
2408 | add(reg2, reg1) |
- | |
2409 | END; |
- | |
2410 | andrc(reg2, 255) |
- | |
2411 | ELSE |
- | |
2412 | n := param2 * 8; |
2178 | n := param2 * 8; |
2413 | IF reg1 >= 8 THEN |
2179 | IF reg1 >= 8 THEN |
2414 | OutByte(44H) |
2180 | OutByte(44H) |
2415 | END; |
2181 | END; |
2416 | OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8)); |
2182 | OutByte2(28H * ORD(opcode = IL.opLADR_DECB), 45H + long(n) + 8 * (reg1 MOD 8)); |
2417 | OutIntByte(n) (* add/sub byte[rbp+n], reg1_8 *) |
2183 | OutIntByte(n); (* add/sub byte[rbp+n], reg1_8 *) |
2418 | END; |
- | |
2419 | drop |
2184 | drop |
2420 | 2185 | ||
2421 | |IL.opLADR_INCL, IL.opLADR_EXCL: |
2186 | |IL.opLADR_INCL, IL.opLADR_EXCL: |
2422 | UnOp(reg1); |
2187 | UnOp(reg1); |
2423 | cmprc(reg1, 64); |
2188 | cmprc(reg1, 64); |
2424 | reg2 := GetVarReg(param2); |
- | |
2425 | IF reg2 # -1 THEN |
- | |
2426 | OutByte2(73H, 4); (* jnb L *) |
- | |
2427 | oprr2(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), reg2, reg1) (* bts/btr reg2, reg1 *) |
- | |
2428 | ELSE |
- | |
2429 | n := param2 * 8; |
2189 | n := param2 * 8; |
2430 | OutByte2(73H, 5 + 3 * ORD(~X86.isByte(n))); (* jnb L *) |
2190 | OutByte2(73H, 5 + 3 * ORD(~X86.isByte(n))); (* jnb L *) |
2431 | Rex(0, reg1); |
2191 | Rex(0, reg1); |
2432 | OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8)); |
2192 | OutByte3(0FH, 0ABH + 8 * ORD(opcode = IL.opLADR_EXCL), 45H + long(n) + 8 * (reg1 MOD 8)); |
2433 | OutIntByte(n) (* bts/btr qword[rbp+n], reg1 *) |
2193 | OutIntByte(n); (* bts/btr qword[rbp+n], reg1 *) |
2434 | END; |
- | |
2435 | (* L: *) |
2194 | (* L: *) |
2436 | drop |
2195 | drop |
2437 | 2196 | ||
2438 | |IL.opLADR_INCLC, IL.opLADR_EXCLC: |
2197 | |IL.opLADR_INCLC, IL.opLADR_EXCLC: |
2439 | reg1 := GetVarReg(param1); |
- | |
2440 | IF reg1 # -1 THEN |
- | |
2441 | Rex(reg1, 0); |
- | |
2442 | OutByte3(0FH, 0BAH, 0E8H); (* bts/btr reg1, param2 *) |
- | |
2443 | OutByte2(reg1 MOD 8 + 8 * ORD(opcode = IL.opLADR_EXCLC), param2) |
- | |
2444 | ELSE |
- | |
2445 | n := param1 * 8; |
2198 | n := param1 * 8; |
2446 | OutByte3(48H, 0FH, 0BAH); (* bts/btr qword[rbp+n], param2 *) |
2199 | OutByte3(48H, 0FH, 0BAH); (* bts/btr qword[rbp+n], param2 *) |
2447 | OutByte(6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); |
2200 | OutByte(6DH + long(n) + 8 * ORD(opcode = IL.opLADR_EXCLC)); |
2448 | OutIntByte(n); |
2201 | OutIntByte(n); |
2449 | OutByte(param2) |
2202 | OutByte(param2) |
2450 | END |
- | |
2451 | 2203 | ||
2452 | |IL.opFNAME: |
2204 | |IL.opFNAME: |
2453 | fname := cmd(IL.FNAMECMD).fname |
2205 | fname := cmd(IL.FNAMECMD).fname |
2454 | - | ||
2455 | |IL.opLOOP, IL.opENDLOOP: |
- | |
2456 | 2206 | ||
2457 | END; |
2207 | END; |
2458 | 2208 | ||
2459 | cmd := cmd.next(COMMAND) |
2209 | cmd := cmd.next(COMMAND) |
2460 | END; |
2210 | END; |
2461 | 2211 | ||
2462 | ASSERT(R.pushed = 0); |
2212 | ASSERT(R.pushed = 0); |
2463 | ASSERT(R.top = -1); |
2213 | ASSERT(R.top = -1); |
2464 | ASSERT(xmm = -1) |
2214 | ASSERT(xmm = -1) |
2465 | END translate; |
2215 | END translate; |
2466 | 2216 | ||
2467 | 2217 | ||
2468 | PROCEDURE prolog (modname: ARRAY OF CHAR; target, stack_size: INTEGER); |
2218 | PROCEDURE prolog (modname: ARRAY OF CHAR; target, stack_size: INTEGER); |
2469 | VAR |
2219 | VAR |
2470 | ModName_Offs, entry, L: INTEGER; |
2220 | ModName_Offs, entry, L: INTEGER; |
2471 | 2221 | ||
2472 | BEGIN |
2222 | BEGIN |
2473 | ModName_Offs := tcount * 8 + CHL.Length(IL.codes.data); |
2223 | ModName_Offs := tcount * 8 + CHL.Length(IL.codes.data); |
2474 | Numbers_Offs := ModName_Offs + LENGTH(modname) + 1; |
2224 | Numbers_Offs := ModName_Offs + LENGTH(modname) + 1; |
2475 | ASSERT(UTILS.Align(Numbers_Offs, 16)); |
2225 | ASSERT(UTILS.Align(Numbers_Offs, 16)); |
2476 | 2226 | ||
2477 | entry := NewLabel(); |
2227 | entry := NewLabel(); |
2478 | X86.SetLabel(entry); |
2228 | X86.SetLabel(entry); |
2479 | 2229 | ||
2480 | IF target = TARGETS.Win64DLL THEN |
2230 | IF target = TARGETS.Win64DLL THEN |
2481 | dllret := NewLabel(); |
2231 | dllret := NewLabel(); |
2482 | push(r8); |
2232 | push(r8); |
2483 | push(rdx); |
2233 | push(rdx); |
2484 | push(rcx); |
2234 | push(rcx); |
2485 | CallRTL(IL._dllentry); |
2235 | CallRTL(IL._dllentry); |
2486 | test(rax); |
2236 | test(rax); |
2487 | jcc(je, dllret); |
2237 | jcc(je, dllret); |
2488 | pushc(0) |
2238 | pushc(0) |
2489 | ELSIF target = TARGETS.Linux64 THEN |
2239 | ELSIF target = TARGETS.Linux64 THEN |
2490 | push(rsp) |
2240 | push(rsp) |
2491 | ELSE |
2241 | ELSE |
2492 | pushc(0) |
2242 | pushc(0) |
2493 | END; |
2243 | END; |
2494 | 2244 | ||
2495 | lea(rax, entry, sCODE); |
2245 | lea(rax, entry, sCODE); |
2496 | push(rax); |
2246 | push(rax); |
2497 | pushDA(0); (* TYPES *) |
2247 | pushDA(0); (* TYPES *) |
2498 | pushc(tcount); |
2248 | pushc(tcount); |
2499 | pushDA(ModName_Offs); (* MODNAME *) |
2249 | pushDA(ModName_Offs); (* MODNAME *) |
2500 | CallRTL(IL._init); |
2250 | CallRTL(IL._init); |
2501 | 2251 | ||
2502 | IF target IN {TARGETS.Win64C, TARGETS.Win64GUI, TARGETS.Linux64} THEN |
2252 | IF target IN {TARGETS.Win64C, TARGETS.Win64GUI, TARGETS.Linux64} THEN |
2503 | L := NewLabel(); |
2253 | L := NewLabel(); |
2504 | pushc(0); |
2254 | pushc(0); |
2505 | push(rsp); |
2255 | push(rsp); |
2506 | pushc(1024 * 1024 * stack_size); |
2256 | pushc(1024 * 1024 * stack_size); |
2507 | pushc(0); |
2257 | pushc(0); |
2508 | CallRTL(IL._new); |
2258 | CallRTL(IL._new); |
2509 | pop(rax); |
2259 | pop(rax); |
2510 | test(rax); |
2260 | test(rax); |
2511 | jcc(je, L); |
2261 | jcc(je, L); |
2512 | GetRegA; |
2262 | GetRegA; |
2513 | addrc(rax, 1024 * 1024 * stack_size - 8); |
2263 | addrc(rax, 1024 * 1024 * stack_size - 8); |
2514 | drop; |
2264 | drop; |
2515 | mov(rsp, rax); |
2265 | mov(rsp, rax); |
2516 | X86.SetLabel(L) |
2266 | X86.SetLabel(L) |
2517 | END |
2267 | END |
2518 | END prolog; |
2268 | END prolog; |
2519 | 2269 | ||
2520 | 2270 | ||
2521 | PROCEDURE epilog (modname: ARRAY OF CHAR; target: INTEGER); |
2271 | PROCEDURE epilog (modname: ARRAY OF CHAR; target: INTEGER); |
2522 | VAR |
2272 | VAR |
2523 | i, n: INTEGER; |
2273 | i, n: INTEGER; |
2524 | number: Number; |
2274 | number: Number; |
2525 | exp: IL.EXPORT_PROC; |
2275 | exp: IL.EXPORT_PROC; |
2526 | 2276 | ||
2527 | 2277 | ||
2528 | PROCEDURE _import (imp: LISTS.LIST); |
2278 | PROCEDURE _import (imp: LISTS.LIST); |
2529 | VAR |
2279 | VAR |
2530 | lib: IL.IMPORT_LIB; |
2280 | lib: IL.IMPORT_LIB; |
2531 | proc: IL.IMPORT_PROC; |
2281 | proc: IL.IMPORT_PROC; |
2532 | 2282 | ||
2533 | BEGIN |
2283 | BEGIN |
2534 | 2284 | ||
2535 | lib := imp.first(IL.IMPORT_LIB); |
2285 | lib := imp.first(IL.IMPORT_LIB); |
2536 | WHILE lib # NIL DO |
2286 | WHILE lib # NIL DO |
2537 | BIN.Import(prog, lib.name, 0); |
2287 | BIN.Import(prog, lib.name, 0); |
2538 | proc := lib.procs.first(IL.IMPORT_PROC); |
2288 | proc := lib.procs.first(IL.IMPORT_PROC); |
2539 | WHILE proc # NIL DO |
2289 | WHILE proc # NIL DO |
2540 | BIN.Import(prog, proc.name, proc.label); |
2290 | BIN.Import(prog, proc.name, proc.label); |
2541 | proc := proc.next(IL.IMPORT_PROC) |
2291 | proc := proc.next(IL.IMPORT_PROC) |
2542 | END; |
2292 | END; |
2543 | lib := lib.next(IL.IMPORT_LIB) |
2293 | lib := lib.next(IL.IMPORT_LIB) |
2544 | END |
2294 | END |
2545 | 2295 | ||
2546 | END _import; |
2296 | END _import; |
2547 | 2297 | ||
2548 | 2298 | ||
2549 | BEGIN |
2299 | BEGIN |
2550 | IF target = TARGETS.Win64DLL THEN |
2300 | IF target = TARGETS.Win64DLL THEN |
2551 | X86.SetLabel(dllret); |
2301 | X86.SetLabel(dllret); |
2552 | X86.ret |
2302 | X86.ret |
2553 | ELSIF target = TARGETS.Linux64SO THEN |
2303 | ELSIF target = TARGETS.Linux64SO THEN |
2554 | sofinit := NewLabel(); |
2304 | sofinit := NewLabel(); |
2555 | X86.ret; |
2305 | X86.ret; |
2556 | X86.SetLabel(sofinit); |
2306 | X86.SetLabel(sofinit); |
2557 | CallRTL(IL._sofinit); |
2307 | CallRTL(IL._sofinit); |
2558 | X86.ret |
2308 | X86.ret |
2559 | ELSE |
2309 | ELSE |
2560 | pushc(0); |
2310 | pushc(0); |
2561 | CallRTL(IL._exit) |
2311 | CallRTL(IL._exit) |
2562 | END; |
2312 | END; |
2563 | 2313 | ||
2564 | X86.fixup; |
2314 | X86.fixup; |
2565 | 2315 | ||
2566 | i := 0; |
2316 | i := 0; |
2567 | WHILE i < tcount DO |
2317 | WHILE i < tcount DO |
2568 | BIN.PutData64LE(prog, CHL.GetInt(IL.codes.types, i)); |
2318 | BIN.PutData64LE(prog, CHL.GetInt(IL.codes.types, i)); |
2569 | INC(i) |
2319 | INC(i) |
2570 | END; |
2320 | END; |
2571 | 2321 | ||
2572 | i := 0; |
2322 | i := 0; |
2573 | WHILE i < CHL.Length(IL.codes.data) DO |
2323 | WHILE i < CHL.Length(IL.codes.data) DO |
2574 | BIN.PutData(prog, CHL.GetByte(IL.codes.data, i)); |
2324 | BIN.PutData(prog, CHL.GetByte(IL.codes.data, i)); |
2575 | INC(i) |
2325 | INC(i) |
2576 | END; |
2326 | END; |
2577 | 2327 | ||
2578 | BIN.PutDataStr(prog, modname); |
2328 | BIN.PutDataStr(prog, modname); |
2579 | BIN.PutData(prog, 0); |
2329 | BIN.PutData(prog, 0); |
2580 | n := CHL.Length(prog.data); |
2330 | n := CHL.Length(prog.data); |
2581 | ASSERT(UTILS.Align(n, 16)); |
2331 | ASSERT(UTILS.Align(n, 16)); |
2582 | i := n - CHL.Length(prog.data); |
2332 | i := n - CHL.Length(prog.data); |
2583 | WHILE i > 0 DO |
2333 | WHILE i > 0 DO |
2584 | BIN.PutData(prog, 0); |
2334 | BIN.PutData(prog, 0); |
2585 | DEC(i) |
2335 | DEC(i) |
2586 | END; |
2336 | END; |
2587 | number := Numbers.first(Number); |
2337 | number := Numbers.first(Number); |
2588 | FOR i := 0 TO Numbers_Count - 1 DO |
2338 | FOR i := 0 TO Numbers_Count - 1 DO |
2589 | BIN.PutData64LE(prog, number.value); |
2339 | BIN.PutData64LE(prog, number.value); |
2590 | number := number.next(Number) |
2340 | number := number.next(Number) |
2591 | END; |
2341 | END; |
2592 | 2342 | ||
2593 | exp := IL.codes.export.first(IL.EXPORT_PROC); |
2343 | exp := IL.codes.export.first(IL.EXPORT_PROC); |
2594 | WHILE exp # NIL DO |
2344 | WHILE exp # NIL DO |
2595 | BIN.Export(prog, exp.name, exp.label); |
2345 | BIN.Export(prog, exp.name, exp.label); |
2596 | exp := exp.next(IL.EXPORT_PROC) |
2346 | exp := exp.next(IL.EXPORT_PROC) |
2597 | END; |
2347 | END; |
2598 | 2348 | ||
2599 | _import(IL.codes._import) |
2349 | _import(IL.codes._import) |
2600 | END epilog; |
2350 | END epilog; |
2601 | 2351 | ||
2602 | - | ||
2603 | PROCEDURE rload (reg, offs, size: INTEGER); |
- | |
2604 | BEGIN |
- | |
2605 | offs := offs * 8; |
- | |
2606 | CASE size OF |
- | |
2607 | |1: movzx(reg, rbp, offs, FALSE) |
- | |
2608 | |2: movzx(reg, rbp, offs, TRUE) |
- | |
2609 | |4: xor(reg, reg); movrm32(reg, rbp, offs) |
- | |
2610 | |8: movrm(reg, rbp, offs) |
- | |
2611 | END |
- | |
2612 | END rload; |
- | |
2613 | - | ||
2614 | - | ||
2615 | PROCEDURE rsave (reg, offs, size: INTEGER); |
- | |
2616 | BEGIN |
- | |
2617 | offs := offs * 8; |
- | |
2618 | CASE size OF |
- | |
2619 | |1: X86.movmr8(rbp, offs, reg) |
- | |
2620 | |2: X86.movmr16(rbp, offs, reg) |
- | |
2621 | |4: movmr32(rbp, offs, reg) |
- | |
2622 | |8: movmr(rbp, offs, reg) |
- | |
2623 | END |
- | |
2624 | END rsave; |
- | |
2625 | - | ||
2626 | 2352 | ||
2627 | PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS); |
2353 | PROCEDURE CodeGen* (outname: ARRAY OF CHAR; target: INTEGER; options: PROG.OPTIONS); |
2628 | VAR |
2354 | VAR |
2629 | path, modname, ext: PATHS.PATH; |
2355 | path, modname, ext: PATHS.PATH; |
2630 | 2356 | ||
2631 | BEGIN |
2357 | BEGIN |
2632 | Xmm[0] := 0; |
2358 | Xmm[0] := 0; |
2633 | tcount := CHL.Length(IL.codes.types); |
2359 | tcount := CHL.Length(IL.codes.types); |
2634 | 2360 | ||
2635 | Win64RegPar[0] := rcx; |
2361 | Win64RegPar[0] := rcx; |
2636 | Win64RegPar[1] := rdx; |
2362 | Win64RegPar[1] := rdx; |
2637 | Win64RegPar[2] := r8; |
2363 | Win64RegPar[2] := r8; |
2638 | Win64RegPar[3] := r9; |
2364 | Win64RegPar[3] := r9; |
2639 | 2365 | ||
2640 | SystemVRegPar[0] := rdi; |
2366 | SystemVRegPar[0] := rdi; |
2641 | SystemVRegPar[1] := rsi; |
2367 | SystemVRegPar[1] := rsi; |
2642 | SystemVRegPar[2] := rdx; |
2368 | SystemVRegPar[2] := rdx; |
2643 | SystemVRegPar[3] := rcx; |
2369 | SystemVRegPar[3] := rcx; |
2644 | SystemVRegPar[4] := r8; |
2370 | SystemVRegPar[4] := r8; |
2645 | SystemVRegPar[5] := r9; |
2371 | SystemVRegPar[5] := r9; |
2646 | 2372 | ||
2647 | PATHS.split(outname, path, modname, ext); |
2373 | PATHS.split(outname, path, modname, ext); |
2648 | S.append(modname, ext); |
2374 | S.append(modname, ext); |
2649 | 2375 | ||
2650 | REG.Init(R, push, pop, mov, xchg, rload, rsave, {rax, r10, r11}, {rcx, rdx, r8, r9}); |
2376 | REG.Init(R, push, pop, mov, xchg, {rax, rcx, rdx, r8, r9, r10, r11}); |
2651 | 2377 | ||
2652 | IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 8))); |
2378 | IL.set_bss(MAX(IL.codes.bss, MAX(IL.codes.dmin - CHL.Length(IL.codes.data), 8))); |
2653 | 2379 | ||
2654 | Numbers := LISTS.create(NIL); |
2380 | Numbers := LISTS.create(NIL); |
2655 | Numbers_Count := 0; |
2381 | Numbers_Count := 0; |
2656 | NewNumber(ROR(1, 1)); (* 8000000000000000H *) |
2382 | NewNumber(ROR(1, 1)); (* 8000000000000000H *) |
2657 | NewNumber(0); |
2383 | NewNumber(0); |
2658 | NewNumber(ROR(-2, 1)); (* 7FFFFFFFFFFFFFFFH *) |
2384 | NewNumber(ROR(-2, 1)); (* 7FFFFFFFFFFFFFFFH *) |
2659 | NewNumber(-1); |
2385 | NewNumber(-1); |
2660 | NewNumber(ROR(7FFH, 12)); (* +Infinity *) |
2386 | NewNumber(ROR(7FFH, 12)); (* +Infinity *) |
2661 | NewNumber(ORD(-BITS(LSR(ASR(ROR(1, 1), 10), 1)))); (* {0..51, 63} *) |
2387 | NewNumber(ORD(-BITS(LSR(ASR(ROR(1, 1), 10), 1)))); (* {0..51, 63} *) |
2662 | NewNumber(LSR(ASR(ROR(1, 1), 9), 2)); (* {52..61} *) |
2388 | NewNumber(LSR(ASR(ROR(1, 1), 9), 2)); (* {52..61} *) |
2663 | 2389 | ||
2664 | prog := BIN.create(IL.codes.lcount); |
2390 | prog := BIN.create(IL.codes.lcount); |
2665 | BIN.SetParams(prog, IL.codes.bss, 1, WCHR(1), WCHR(0)); |
2391 | BIN.SetParams(prog, IL.codes.bss, 1, WCHR(1), WCHR(0)); |
2666 | 2392 | ||
2667 | X86.SetProgram(prog); |
2393 | X86.SetProgram(prog); |
2668 | 2394 | ||
2669 | prolog(modname, target, options.stack); |
2395 | prolog(modname, target, options.stack); |
2670 | translate(IL.codes.commands, tcount * 8); |
2396 | translate(IL.codes.commands, tcount * 8); |
2671 | epilog(modname, target); |
2397 | epilog(modname, target); |
2672 | 2398 | ||
2673 | BIN.fixup(prog); |
2399 | BIN.fixup(prog); |
2674 | IF TARGETS.OS = TARGETS.osWIN64 THEN |
2400 | IF TARGETS.OS = TARGETS.osWIN64 THEN |
2675 | PE32.write(prog, outname, target = TARGETS.Win64C, target = TARGETS.Win64DLL, TRUE) |
2401 | PE32.write(prog, outname, target = TARGETS.Win64C, target = TARGETS.Win64DLL, TRUE) |
2676 | ELSIF TARGETS.OS = TARGETS.osLINUX64 THEN |
2402 | ELSIF TARGETS.OS = TARGETS.osLINUX64 THEN |
2677 | ELF.write(prog, outname, sofinit, target = TARGETS.Linux64SO, TRUE) |
2403 | ELF.write(prog, outname, sofinit, target = TARGETS.Linux64SO, TRUE) |
2678 | END |
2404 | END |
2679 | END CodeGen; |
2405 | END CodeGen; |
2680 | 2406 | ||
2681 | 2407 | ||
2682 | END AMD64.>>>>>>=>=>=>=>=>>=>=>>> |
2408 | END AMD64.>>>>>>=>=>=>=>=>>=>=>>> |