1 ! Copyright (C) 2006, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays assocs generic kernel kernel.private
4 math memory namespaces make sequences layouts system hashtables
5 classes alien byte-arrays combinators words sets fry ;
8 ! Representations -- these are like low-level types
10 ! Unknown representation; this is used for ##copy instructions which
11 ! get eliminated later
14 ! Integer registers can contain data with one of these three representations
15 ! tagged-rep: tagged pointer or fixnum
16 ! int-rep: untagged fixnum, not a pointer
17 SINGLETONS: tagged-rep int-rep ;
19 ! Floating point registers can contain data with
20 ! one of these representations
21 SINGLETONS: float-rep double-rep ;
23 ! On x86, floating point registers are really vector registers
34 ! Scalar values in the high component of a vector register
43 ulonglong-scalar-rep ;
59 UNION: signed-int-vector-rep
65 UNION: unsigned-int-vector-rep
79 ulonglong-scalar-rep ;
81 UNION: float-vector-rep
98 : unsign-rep ( rep -- rep' )
100 { uint-4-rep int-4-rep }
101 { ulonglong-2-rep longlong-2-rep }
102 { ushort-8-rep short-8-rep }
103 { uchar-16-rep char-16-rep }
104 { uchar-scalar-rep char-scalar-rep }
105 { ushort-scalar-rep short-scalar-rep }
106 { uint-scalar-rep int-scalar-rep }
107 { ulonglong-scalar-rep longlong-scalar-rep }
111 SINGLETONS: int-regs float-regs ;
113 UNION: reg-class int-regs float-regs ;
114 CONSTANT: reg-classes { int-regs float-regs }
116 ! A pseudo-register class for parameters spilled on the stack
117 SINGLETON: stack-params
119 ! On x86, vectors and floats are stored in the same register bank
120 ! On PowerPC they are distinct
121 HOOK: vector-regs cpu ( -- reg-class )
123 GENERIC: reg-class-of ( rep -- reg-class )
125 M: tagged-rep reg-class-of drop int-regs ;
126 M: int-rep reg-class-of drop int-regs ;
127 M: float-rep reg-class-of drop float-regs ;
128 M: double-rep reg-class-of drop float-regs ;
129 M: vector-rep reg-class-of drop vector-regs ;
130 M: scalar-rep reg-class-of drop vector-regs ;
131 M: stack-params reg-class-of drop stack-params ;
133 GENERIC: rep-size ( rep -- n ) foldable
135 M: tagged-rep rep-size drop cell ;
136 M: int-rep rep-size drop cell ;
137 M: float-rep rep-size drop 4 ;
138 M: double-rep rep-size drop 8 ;
139 M: stack-params rep-size drop cell ;
140 M: vector-rep rep-size drop 16 ;
141 M: char-scalar-rep rep-size drop 1 ;
142 M: uchar-scalar-rep rep-size drop 1 ;
143 M: short-scalar-rep rep-size drop 2 ;
144 M: ushort-scalar-rep rep-size drop 2 ;
145 M: int-scalar-rep rep-size drop 4 ;
146 M: uint-scalar-rep rep-size drop 4 ;
147 M: longlong-scalar-rep rep-size drop 8 ;
148 M: ulonglong-scalar-rep rep-size drop 8 ;
150 GENERIC: rep-component-type ( rep -- n )
152 ! Methods defined in alien.c-types
154 GENERIC: scalar-rep-of ( rep -- rep' )
156 M: float-4-rep scalar-rep-of drop float-rep ;
157 M: double-2-rep scalar-rep-of drop double-rep ;
158 M: char-16-rep scalar-rep-of drop char-scalar-rep ;
159 M: uchar-16-rep scalar-rep-of drop uchar-scalar-rep ;
160 M: short-8-rep scalar-rep-of drop short-scalar-rep ;
161 M: ushort-8-rep scalar-rep-of drop ushort-scalar-rep ;
162 M: int-4-rep scalar-rep-of drop int-scalar-rep ;
163 M: uint-4-rep scalar-rep-of drop uint-scalar-rep ;
164 M: longlong-2-rep scalar-rep-of drop longlong-scalar-rep ;
165 M: ulonglong-2-rep scalar-rep-of drop ulonglong-scalar-rep ;
167 ! Mapping from register class to machine registers
168 HOOK: machine-registers cpu ( -- assoc )
170 HOOK: %load-immediate cpu ( reg obj -- )
171 HOOK: %load-reference cpu ( reg obj -- )
173 HOOK: %peek cpu ( vreg loc -- )
174 HOOK: %replace cpu ( vreg loc -- )
175 HOOK: %inc-d cpu ( n -- )
176 HOOK: %inc-r cpu ( n -- )
178 HOOK: stack-frame-size cpu ( stack-frame -- n )
179 HOOK: %call cpu ( word -- )
180 HOOK: %jump cpu ( word -- )
181 HOOK: %jump-label cpu ( label -- )
182 HOOK: %return cpu ( -- )
184 HOOK: %dispatch cpu ( src temp -- )
186 HOOK: %slot cpu ( dst obj slot -- )
187 HOOK: %slot-imm cpu ( dst obj slot tag -- )
188 HOOK: %set-slot cpu ( src obj slot -- )
189 HOOK: %set-slot-imm cpu ( src obj slot tag -- )
191 HOOK: %string-nth cpu ( dst obj index temp -- )
192 HOOK: %set-string-nth-fast cpu ( ch obj index temp -- )
194 HOOK: %add cpu ( dst src1 src2 -- )
195 HOOK: %add-imm cpu ( dst src1 src2 -- )
196 HOOK: %sub cpu ( dst src1 src2 -- )
197 HOOK: %sub-imm cpu ( dst src1 src2 -- )
198 HOOK: %mul cpu ( dst src1 src2 -- )
199 HOOK: %mul-imm cpu ( dst src1 src2 -- )
200 HOOK: %and cpu ( dst src1 src2 -- )
201 HOOK: %and-imm cpu ( dst src1 src2 -- )
202 HOOK: %or cpu ( dst src1 src2 -- )
203 HOOK: %or-imm cpu ( dst src1 src2 -- )
204 HOOK: %xor cpu ( dst src1 src2 -- )
205 HOOK: %xor-imm cpu ( dst src1 src2 -- )
206 HOOK: %shl cpu ( dst src1 src2 -- )
207 HOOK: %shl-imm cpu ( dst src1 src2 -- )
208 HOOK: %shr cpu ( dst src1 src2 -- )
209 HOOK: %shr-imm cpu ( dst src1 src2 -- )
210 HOOK: %sar cpu ( dst src1 src2 -- )
211 HOOK: %sar-imm cpu ( dst src1 src2 -- )
212 HOOK: %min cpu ( dst src1 src2 -- )
213 HOOK: %max cpu ( dst src1 src2 -- )
214 HOOK: %not cpu ( dst src -- )
215 HOOK: %neg cpu ( dst src -- )
216 HOOK: %log2 cpu ( dst src -- )
218 HOOK: %copy cpu ( dst src rep -- )
220 HOOK: %fixnum-add cpu ( label dst src1 src2 -- )
221 HOOK: %fixnum-sub cpu ( label dst src1 src2 -- )
222 HOOK: %fixnum-mul cpu ( label dst src1 src2 -- )
224 HOOK: %add-float cpu ( dst src1 src2 -- )
225 HOOK: %sub-float cpu ( dst src1 src2 -- )
226 HOOK: %mul-float cpu ( dst src1 src2 -- )
227 HOOK: %div-float cpu ( dst src1 src2 -- )
228 HOOK: %min-float cpu ( dst src1 src2 -- )
229 HOOK: %max-float cpu ( dst src1 src2 -- )
230 HOOK: %sqrt cpu ( dst src -- )
231 HOOK: %unary-float-function cpu ( dst src func -- )
232 HOOK: %binary-float-function cpu ( dst src1 src2 func -- )
234 HOOK: %single>double-float cpu ( dst src -- )
235 HOOK: %double>single-float cpu ( dst src -- )
237 HOOK: %integer>float cpu ( dst src -- )
238 HOOK: %float>integer cpu ( dst src -- )
240 HOOK: %zero-vector cpu ( dst rep -- )
241 HOOK: %fill-vector cpu ( dst rep -- )
242 HOOK: %gather-vector-2 cpu ( dst src1 src2 rep -- )
243 HOOK: %gather-vector-4 cpu ( dst src1 src2 src3 src4 rep -- )
244 HOOK: %shuffle-vector cpu ( dst src shuffle rep -- )
245 HOOK: %shuffle-vector-imm cpu ( dst src shuffle rep -- )
246 HOOK: %tail>head-vector cpu ( dst src rep -- )
247 HOOK: %merge-vector-head cpu ( dst src1 src2 rep -- )
248 HOOK: %merge-vector-tail cpu ( dst src1 src2 rep -- )
249 HOOK: %signed-pack-vector cpu ( dst src1 src2 rep -- )
250 HOOK: %unsigned-pack-vector cpu ( dst src1 src2 rep -- )
251 HOOK: %unpack-vector-head cpu ( dst src rep -- )
252 HOOK: %unpack-vector-tail cpu ( dst src rep -- )
253 HOOK: %integer>float-vector cpu ( dst src rep -- )
254 HOOK: %float>integer-vector cpu ( dst src rep -- )
255 HOOK: %compare-vector cpu ( dst src1 src2 rep cc -- )
256 HOOK: %test-vector cpu ( dst src1 temp rep vcc -- )
257 HOOK: %test-vector-branch cpu ( label src1 temp rep vcc -- )
258 HOOK: %add-vector cpu ( dst src1 src2 rep -- )
259 HOOK: %saturated-add-vector cpu ( dst src1 src2 rep -- )
260 HOOK: %add-sub-vector cpu ( dst src1 src2 rep -- )
261 HOOK: %sub-vector cpu ( dst src1 src2 rep -- )
262 HOOK: %saturated-sub-vector cpu ( dst src1 src2 rep -- )
263 HOOK: %mul-vector cpu ( dst src1 src2 rep -- )
264 HOOK: %saturated-mul-vector cpu ( dst src1 src2 rep -- )
265 HOOK: %div-vector cpu ( dst src1 src2 rep -- )
266 HOOK: %min-vector cpu ( dst src1 src2 rep -- )
267 HOOK: %max-vector cpu ( dst src1 src2 rep -- )
268 HOOK: %dot-vector cpu ( dst src1 src2 rep -- )
269 HOOK: %sqrt-vector cpu ( dst src rep -- )
270 HOOK: %horizontal-add-vector cpu ( dst src rep -- )
271 HOOK: %horizontal-sub-vector cpu ( dst src rep -- )
272 HOOK: %abs-vector cpu ( dst src rep -- )
273 HOOK: %and-vector cpu ( dst src1 src2 rep -- )
274 HOOK: %andn-vector cpu ( dst src1 src2 rep -- )
275 HOOK: %or-vector cpu ( dst src1 src2 rep -- )
276 HOOK: %xor-vector cpu ( dst src1 src2 rep -- )
277 HOOK: %not-vector cpu ( dst src rep -- )
278 HOOK: %shl-vector cpu ( dst src1 src2 rep -- )
279 HOOK: %shr-vector cpu ( dst src1 src2 rep -- )
280 HOOK: %horizontal-shl-vector cpu ( dst src1 src2 rep -- )
281 HOOK: %horizontal-shr-vector cpu ( dst src1 src2 rep -- )
283 HOOK: %integer>scalar cpu ( dst src rep -- )
284 HOOK: %scalar>integer cpu ( dst src rep -- )
285 HOOK: %vector>scalar cpu ( dst src rep -- )
286 HOOK: %scalar>vector cpu ( dst src rep -- )
288 HOOK: %zero-vector-reps cpu ( -- reps )
289 HOOK: %fill-vector-reps cpu ( -- reps )
290 HOOK: %gather-vector-2-reps cpu ( -- reps )
291 HOOK: %gather-vector-4-reps cpu ( -- reps )
292 HOOK: %alien-vector-reps cpu ( -- reps )
293 HOOK: %shuffle-vector-reps cpu ( -- reps )
294 HOOK: %shuffle-vector-imm-reps cpu ( -- reps )
295 HOOK: %merge-vector-reps cpu ( -- reps )
296 HOOK: %signed-pack-vector-reps cpu ( -- reps )
297 HOOK: %unsigned-pack-vector-reps cpu ( -- reps )
298 HOOK: %unpack-vector-head-reps cpu ( -- reps )
299 HOOK: %unpack-vector-tail-reps cpu ( -- reps )
300 HOOK: %integer>float-vector-reps cpu ( -- reps )
301 HOOK: %float>integer-vector-reps cpu ( -- reps )
302 HOOK: %compare-vector-reps cpu ( cc -- reps )
303 HOOK: %compare-vector-ccs cpu ( rep cc -- {cc,swap?}s not? )
304 HOOK: %test-vector-reps cpu ( -- reps )
305 HOOK: %add-vector-reps cpu ( -- reps )
306 HOOK: %saturated-add-vector-reps cpu ( -- reps )
307 HOOK: %add-sub-vector-reps cpu ( -- reps )
308 HOOK: %sub-vector-reps cpu ( -- reps )
309 HOOK: %saturated-sub-vector-reps cpu ( -- reps )
310 HOOK: %mul-vector-reps cpu ( -- reps )
311 HOOK: %saturated-mul-vector-reps cpu ( -- reps )
312 HOOK: %div-vector-reps cpu ( -- reps )
313 HOOK: %min-vector-reps cpu ( -- reps )
314 HOOK: %max-vector-reps cpu ( -- reps )
315 HOOK: %dot-vector-reps cpu ( -- reps )
316 HOOK: %sqrt-vector-reps cpu ( -- reps )
317 HOOK: %horizontal-add-vector-reps cpu ( -- reps )
318 HOOK: %horizontal-sub-vector-reps cpu ( -- reps )
319 HOOK: %abs-vector-reps cpu ( -- reps )
320 HOOK: %and-vector-reps cpu ( -- reps )
321 HOOK: %andn-vector-reps cpu ( -- reps )
322 HOOK: %or-vector-reps cpu ( -- reps )
323 HOOK: %xor-vector-reps cpu ( -- reps )
324 HOOK: %not-vector-reps cpu ( -- reps )
325 HOOK: %shl-vector-reps cpu ( -- reps )
326 HOOK: %shr-vector-reps cpu ( -- reps )
327 HOOK: %horizontal-shl-vector-reps cpu ( -- reps )
328 HOOK: %horizontal-shr-vector-reps cpu ( -- reps )
330 M: object %zero-vector-reps { } ;
331 M: object %fill-vector-reps { } ;
332 M: object %gather-vector-2-reps { } ;
333 M: object %gather-vector-4-reps { } ;
334 M: object %alien-vector-reps { } ;
335 M: object %shuffle-vector-reps { } ;
336 M: object %shuffle-vector-imm-reps { } ;
337 M: object %merge-vector-reps { } ;
338 M: object %signed-pack-vector-reps { } ;
339 M: object %unsigned-pack-vector-reps { } ;
340 M: object %unpack-vector-head-reps { } ;
341 M: object %unpack-vector-tail-reps { } ;
342 M: object %integer>float-vector-reps { } ;
343 M: object %float>integer-vector-reps { } ;
344 M: object %compare-vector-reps drop { } ;
345 M: object %compare-vector-ccs 2drop { } f ;
346 M: object %test-vector-reps { } ;
347 M: object %add-vector-reps { } ;
348 M: object %saturated-add-vector-reps { } ;
349 M: object %add-sub-vector-reps { } ;
350 M: object %sub-vector-reps { } ;
351 M: object %saturated-sub-vector-reps { } ;
352 M: object %mul-vector-reps { } ;
353 M: object %saturated-mul-vector-reps { } ;
354 M: object %div-vector-reps { } ;
355 M: object %min-vector-reps { } ;
356 M: object %max-vector-reps { } ;
357 M: object %dot-vector-reps { } ;
358 M: object %sqrt-vector-reps { } ;
359 M: object %horizontal-add-vector-reps { } ;
360 M: object %horizontal-sub-vector-reps { } ;
361 M: object %abs-vector-reps { } ;
362 M: object %and-vector-reps { } ;
363 M: object %andn-vector-reps { } ;
364 M: object %or-vector-reps { } ;
365 M: object %xor-vector-reps { } ;
366 M: object %not-vector-reps { } ;
367 M: object %shl-vector-reps { } ;
368 M: object %shr-vector-reps { } ;
369 M: object %horizontal-shl-vector-reps { } ;
370 M: object %horizontal-shr-vector-reps { } ;
372 HOOK: %unbox-alien cpu ( dst src -- )
373 HOOK: %unbox-any-c-ptr cpu ( dst src temp -- )
374 HOOK: %box-alien cpu ( dst src temp -- )
375 HOOK: %box-displaced-alien cpu ( dst displacement base temp1 temp2 base-class -- )
377 HOOK: %alien-unsigned-1 cpu ( dst src offset -- )
378 HOOK: %alien-unsigned-2 cpu ( dst src offset -- )
379 HOOK: %alien-unsigned-4 cpu ( dst src offset -- )
380 HOOK: %alien-signed-1 cpu ( dst src offset -- )
381 HOOK: %alien-signed-2 cpu ( dst src offset -- )
382 HOOK: %alien-signed-4 cpu ( dst src offset -- )
383 HOOK: %alien-cell cpu ( dst src offset -- )
384 HOOK: %alien-float cpu ( dst src offset -- )
385 HOOK: %alien-double cpu ( dst src offset -- )
386 HOOK: %alien-vector cpu ( dst src offset rep -- )
388 HOOK: %set-alien-integer-1 cpu ( ptr offset value -- )
389 HOOK: %set-alien-integer-2 cpu ( ptr offset value -- )
390 HOOK: %set-alien-integer-4 cpu ( ptr offset value -- )
391 HOOK: %set-alien-cell cpu ( ptr offset value -- )
392 HOOK: %set-alien-float cpu ( ptr offset value -- )
393 HOOK: %set-alien-double cpu ( ptr offset value -- )
394 HOOK: %set-alien-vector cpu ( ptr offset value rep -- )
396 HOOK: %alien-global cpu ( dst symbol library -- )
397 HOOK: %vm-field-ptr cpu ( dst fieldname -- )
399 HOOK: %allot cpu ( dst size class temp -- )
400 HOOK: %write-barrier cpu ( src slot temp1 temp2 -- )
401 HOOK: %write-barrier-imm cpu ( src slot temp1 temp2 -- )
404 HOOK: %check-nursery cpu ( label size temp1 temp2 -- )
405 HOOK: %save-gc-root cpu ( gc-root register -- )
406 HOOK: %load-gc-root cpu ( gc-root register -- )
407 HOOK: %call-gc cpu ( gc-root-count temp1 -- )
409 HOOK: %prologue cpu ( n -- )
410 HOOK: %epilogue cpu ( n -- )
412 HOOK: %compare cpu ( dst temp cc src1 src2 -- )
413 HOOK: %compare-imm cpu ( dst temp cc src1 src2 -- )
414 HOOK: %compare-float-ordered cpu ( dst temp cc src1 src2 -- )
415 HOOK: %compare-float-unordered cpu ( dst temp cc src1 src2 -- )
417 HOOK: %compare-branch cpu ( label cc src1 src2 -- )
418 HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- )
419 HOOK: %compare-float-ordered-branch cpu ( label cc src1 src2 -- )
420 HOOK: %compare-float-unordered-branch cpu ( label cc src1 src2 -- )
422 HOOK: %spill cpu ( src rep dst -- )
423 HOOK: %reload cpu ( dst rep src -- )
425 HOOK: %loop-entry cpu ( -- )
429 ! Return values of this class go here
430 GENERIC: return-reg ( reg-class -- reg )
432 ! Sequence of registers used for parameter passing in class
433 GENERIC: param-regs ( reg-class -- regs )
435 M: stack-params param-regs drop f ;
437 GENERIC: param-reg ( n reg-class -- reg )
439 M: reg-class param-reg param-regs nth ;
441 M: stack-params param-reg drop ;
443 ! Is this integer small enough to be an immediate operand for
444 ! %add-imm, %sub-imm, and %mul-imm?
445 HOOK: immediate-arithmetic? cpu ( n -- ? )
447 ! Is this integer small enough to be an immediate operand for
448 ! %and-imm, %or-imm, and %xor-imm?
449 HOOK: immediate-bitwise? cpu ( n -- ? )
451 ! Is this structure small enough to be returned in registers?
452 HOOK: return-struct-in-registers? cpu ( c-type -- ? )
454 ! Do we pass this struct by value or hidden reference?
455 HOOK: value-struct? cpu ( c-type -- ? )
457 ! If t, all parameters are shadowed by dummy stack parameters
458 HOOK: dummy-stack-params? cpu ( -- ? )
460 ! If t, all FP parameters are shadowed by dummy int parameters
461 HOOK: dummy-int-params? cpu ( -- ? )
463 ! If t, all int parameters are shadowed by dummy FP parameters
464 HOOK: dummy-fp-params? cpu ( -- ? )
466 HOOK: %prepare-unbox cpu ( n -- )
468 HOOK: %unbox cpu ( n rep func -- )
470 HOOK: %unbox-long-long cpu ( n func -- )
472 HOOK: %unbox-small-struct cpu ( c-type -- )
474 HOOK: %unbox-large-struct cpu ( n c-type -- )
476 HOOK: %box cpu ( n rep func -- )
478 HOOK: %box-long-long cpu ( n func -- )
480 HOOK: %prepare-box-struct cpu ( -- )
482 HOOK: %box-small-struct cpu ( c-type -- )
484 HOOK: %box-large-struct cpu ( n c-type -- )
486 HOOK: %save-param-reg cpu ( stack reg rep -- )
488 HOOK: %load-param-reg cpu ( stack reg rep -- )
490 HOOK: %save-context cpu ( temp1 temp2 callback-allowed? -- )
492 HOOK: %prepare-var-args cpu ( -- )
494 M: object %prepare-var-args ;
496 HOOK: %alien-invoke cpu ( function library -- )
498 HOOK: %cleanup cpu ( params -- )
500 M: object %cleanup ( params -- ) drop ;
502 HOOK: %prepare-alien-indirect cpu ( -- )
504 HOOK: %alien-indirect cpu ( -- )
506 HOOK: %alien-callback cpu ( quot -- )
508 HOOK: %callback-value cpu ( ctype -- )
510 HOOK: %nest-stacks cpu ( -- )
512 HOOK: %unnest-stacks cpu ( -- )
514 ! Return to caller with stdcall unwinding (only for x86)
515 HOOK: %callback-return cpu ( params -- )
517 M: object %callback-return drop %return ;