]> gitweb.factorcode.org Git - factor.git/blob - basis/cpu/architecture/architecture-docs.factor
docs: Fix help-lint-all mistakes.
[factor.git] / basis / cpu / architecture / architecture-docs.factor
1 USING: alien assocs byte-arrays classes compiler.cfg.instructions
2 compiler.cfg.registers compiler.cfg.stack-frame cpu.x86.assembler
3 cpu.x86.assembler.operands help.markup help.syntax kernel layouts
4 literals math multiline sequences strings system vm words ;
5 IN: cpu.architecture
6
7 <<
8 STRING: ex-%allot
9 USING: cpu.architecture make ;
10 [ RAX 40 tuple RCX %allot ] B{ } make disassemble
11 0000000002270cc0: 498d4d10        lea rcx, [r13+0x10]
12 0000000002270cc4: 488b01          mov rax, [rcx]
13 0000000002270cc7: 48c7001c000000  mov qword [rax], 0x1c
14 0000000002270cce: 4883c807        or rax, 0x7
15 0000000002270cd2: 48830130        add qword [rcx], 0x30
16 ;
17
18 STRING: ex-%box-alien
19 USING: compiler.codegen compiler.codegen.relocation cpu.architecture make ;
20 [ RAX RBX RCX %box-alien ] with-fixup 4 swap nth disassemble
21 000000e9fcc720a0: 48b80100000000000000  mov eax, 0x1
22 000000e9fcc720aa: 4885db                test rbx, rbx
23 000000e9fcc720ad: 0f8400000000          jz dword 0xe9fcc720b3
24 000000e9fcc720b3: 498d4d10              lea rcx, [r13+0x10]
25 000000e9fcc720b7: 488b01                mov rax, [rcx]
26 000000e9fcc720ba: 48c70018000000        mov qword [rax], 0x18
27 000000e9fcc720c1: 4883c806              or rax, 0x6
28 000000e9fcc720c5: 48830130              add qword [rcx], 0x30
29 000000e9fcc720c9: 48c7400201000000      mov qword [rax+0x2], 0x1
30 000000e9fcc720d1: 48c7400a01000000      mov qword [rax+0xa], 0x1
31 000000e9fcc720d9: 48895812              mov [rax+0x12], rbx
32 000000e9fcc720dd: 4889581a              mov [rax+0x1a], rbx
33 ;
34
35 STRING: ex-%context
36 USING: cpu.architecture make ;
37 [ EAX %context ] B{ } make disassemble
38 00000000010f5ed0: 418b4500  mov eax, [r13]
39 ;
40
41 STRING: ex-%copy
42 USING: cpu.architecture make ;
43 RAX RBX int-rep [ %copy ] B{ } make disassemble
44 000000000108a970: 4889d8  mov rax, rbx
45 ;
46
47 STRING: ex-%safepoint
48 USING: cpu.architecture make ;
49 init-relocation [ %safepoint ] B{ } make disassemble
50 00000000010b05a0: 890500000000  mov [rip], eax
51 ;
52
53 STRING: ex-%save-context
54 USING: cpu.architecture make ;
55 [ RAX RBX %save-context ] B{ } make disassemble
56 0000000000e63ab0: 498b4500    mov rax, [r13]
57 0000000000e63ab4: 488d5c24f8  lea rbx, [rsp-0x8]
58 0000000000e63ab9: 488918      mov [rax], rbx
59 0000000000e63abc: 4c897010    mov [rax+0x10], r14
60 0000000000e63ac0: 4c897818    mov [rax+0x18], r15
61 ;
62
63 STRING: ex-%write-barrier
64 USING: cpu.architecture make tools.disassembler ;
65 init-relocation [ RAX RBX 3 -14 RCX RDX %write-barrier ] B{ } make disassemble
66 000000000143f960: 488d4cd80e            lea rcx, [rax+rbx*8+0xe]
67 000000000143f965: 48c1e908              shr rcx, 0x8
68 000000000143f969: 48ba0000000000000000  mov rdx, 0x0
69 000000000143f973: 48c60411c0            mov byte [rcx+rdx], 0xc0
70 000000000143f978: 48c1e90a              shr rcx, 0xa
71 000000000143f97c: 48ba0000000000000000  mov rdx, 0x0
72 000000000143f986: 48c60411c0            mov byte [rcx+rdx], 0xc0
73 ;
74 >>
75
76 HELP: %alien-invoke
77 { $values
78   { "varargs?" boolean }
79   { "reg-inputs" sequence }
80   { "stack-inputs" sequence }
81   { "reg-outputs" sequence }
82   { "dead-outputs" sequence }
83   { "cleanup" integer }
84   { "stack-size" integer }
85   { "symbols" string }
86   { "dll" { $maybe dll } }
87   { "gc-map" gc-map }
88 }
89 { $description "Machine code emitter for the " { $link ##alien-invoke } " instruction." } ;
90
91
92 HELP: %allot
93 { $values
94   { "dst" "destination register symbol" }
95   { "size" "number of bytes to allocate" }
96   { "class" "one of the built-in classes listed in " { $link type-numbers } }
97   { "temp" "temporary register symbol" }
98 }
99 { $description "Emits machine code for allocating memory." }
100 { $examples
101   "In this example 40 bytes is allocated and a tagged pointer to the memory is put in " { $link RAX } ":"
102   { $unchecked-example $[ ex-%allot ] }
103 } ;
104
105 HELP: %and-imm
106 { $values
107   { "dst" "destination register" }
108   { "src1" "first source register" }
109   { "src2" "second source register" }
110 }
111 { $description "Emits an " { $link AND } " instruction between a register and an immediate." } ;
112
113 HELP: %box
114 { $values
115   { "dst" "destination register" }
116   { "src" "source register" }
117   { "func" "function?" }
118   { "rep" "representation class" }
119   { "gc-map" gc-map }
120 }
121 { $description "Call a function to convert a value into a tagged pointer, possibly allocating a bignum, float, or alien instance, which is then pushed on the data stack." } ;
122
123 HELP: %box-alien
124 { $values
125   { "dst" "destination register" }
126   { "src" "register containing pointer to the alien" }
127   { "temp" "temporary register" }
128 }
129 { $description "Emits machine code for boxing an alien value. If the alien is not a NULL pointer, then five " { $link cells } " will be allocated in the nursery space to wrap the object. See vm/layouts.hpp for details." }
130 { $examples { $unchecked-example $[ ex-%box-alien ] } }
131 { $see-also ##box-alien %allot } ;
132
133 HELP: %call
134 { $values { "word" word } }
135 { $description "Emits code for calling a Factor word." } ;
136
137 HELP: %c-invoke
138 { $values { "symbols" byte-array } { "dll" dll } { "gc-map" gc-map } }
139 { $description "Emits code for calling an FFI function." } ;
140
141 HELP: %check-nursery-branch
142 { $values
143   { "label" "label" }
144   { "size" integer }
145   { "cc" "comparison symbol" }
146   { "temp1" "first temporary register" }
147   { "temp2" "second temporary register" }
148 }
149 { $description "Emits code for jumping to the nursery garbage collection block if an allocation of size 'size' requires a garbage collection." } ;
150
151 HELP: %context
152 { $values { "dst" "a register symbol" } }
153 { $description "Emits machine code for putting a pointer to the context field of the " { $link vm } " in a register." }
154 { $examples { $unchecked-example $[ ex-%context ] } } ;
155
156 HELP: %copy
157 { $values { "dst" "destination" } { "src" "source" } { "rep" representation } }
158 { $description "Emits code copying a value from a register, arbitrary memory location or " { $link spill-slot } " to a destination." }
159 { $examples { $unchecked-example $[ ex-%copy ] } } ;
160
161 HELP: %dispatch
162 { $values { "src" "a register symbol" } { "temp" "a register symbol" } }
163 { $description "Code emitter for the " { $link ##dispatch } " instruction." } ;
164
165 HELP: %horizontal-add-vector
166 { $values
167   { "dst" "destination register symbol" }
168   { "src1"  "first source register" }
169   { "src2" "second source register" }
170   { "rep" "representation" }
171 }
172 { $description "Emits machine code for performing a horizontal add, meaning that adjacent elements in the same operand are added together. So if the two vectors are (a0, a1, a2, a3) and (b0, b1, b2, b3) then the result is (a0 + a1, a2 + a3, b0 + b1, b2 + b3)." }
173 { $examples
174   { $unchecked-example
175     "USING: cpu.architecture make tools.disassembler ;"
176     "[ XMM0 XMM1 XMM2 float-4-rep %horizontal-add-vector ] B{ } make disassemble"
177     "0000000002660870: 0f28c1    movaps xmm0, xmm1"
178     "0000000002660873: f20f7cc2  haddps xmm0, xmm2"
179   }
180 } ;
181
182 HELP: %load-double
183 { $values
184   { "reg" "destination register symbol" }
185   { "val" float }
186 } { $description "Loads a literal floating point value into a register. On x86, this corresponds to the " { $link MOVSD } " instruction." }
187 { $see-also ##load-double } ;
188
189 HELP: %load-immediate
190 { $values { "reg" "a register symbol" } { "val" "a value" } }
191 { $description "Emits code for loading an immediate value into a register. On " { $link x86 } ", if val is 0, then an " { $link XOR } " instruction is emitted instead of " { $link MOV } " because the former is shorter." }
192 { $see-also ##load-tagged } ;
193
194 HELP: %load-memory-imm
195 { $values
196   { "dst" "destination register" }
197   { "base" "base gpr for memory address" }
198   { "offset" "memory offset" }
199   { "rep" "representation" }
200   { "c-type" "no idea" }
201 }
202 { $description "Emits code for loading a value from memory into a SIMD register." }
203 { $examples
204   { $unchecked-example
205     "USING: cpu.architecture make tools.disassembler ;"
206     "[ XMM0 RCX 7 float-4-rep f %load-memory-imm ] B{ } make disassemble"
207     "0000000002633800: 480f284107  movaps xmm0, [rcx+0x7]"
208   }
209 } ;
210
211 HELP: %local-allot
212 { $values
213   { "dst" "destination register symbol" }
214   { "size" "number of bytes to allocate" }
215   { "align" "alignment" }
216   { "offset" "where to allocate the data, relative to the stack register" }
217 }
218 { $description "Emits machine code for stack \"allocating\" a chunk of memory. No memory is really allocated and instead a pointer to it is just put in the destination register." }
219 { $see-also ##local-allot } ;
220
221 HELP: %replace-imm
222 { $values
223   { "src" integer }
224   { "loc" loc }
225 }
226 { $description "Emits machine code for putting a literal on the stack." }
227 { $examples
228   { $unchecked-example
229     "USING: cpu.architecture make ;"
230     "[ 777 D: 0 %replace-imm ] B{ } make disassemble"
231     "0000000000aad8c0: 49c70690300000  mov qword [r14], 0x3090"
232   }
233 } ;
234
235 HELP: %safepoint
236 { $description "Emits a safe point to the current code sequence being generated." }
237 { $examples { $unchecked-example $[ ex-%safepoint ] } } ;
238
239 HELP: %save-context
240 { $values { "temp1" "a register symbol" } { "temp2" "a register symbol" } }
241 { $description "Emits machine code for saving pointers to the callstack, datastack and retainstack in the current context field struct." }
242 { $examples { $unchecked-example $[ ex-%save-context ] } } ;
243
244 HELP: %set-slot
245 { $values
246   { "src" "register containing the element" }
247   { "obj" "register containing the object" }
248   { "slot" "register containing the slot index" }
249   { "scale" fixnum }
250   { "tag" "type tag for the builtin" }
251 } { $description "Emits machine code for " { $link ##set-slot } " instructions." }
252 { $examples
253   { $unchecked-example
254     "USING: cpu.architecture prettyprint ;"
255     "[ RAX RBX RCX 3 2 %set-slot ] B{ } make disassemble"
256     "0000000000f1fda0: 488944cbfe  mov [rbx+rcx*8-0x2], rax"
257   }
258 } ;
259
260 HELP: %shl-imm
261 { $values
262   { "dst" "register" }
263   { "src1" "register" }
264   { "src2" integer }
265 } { $description "Bitshifts the value in a register left by a constant." }
266 { $see-also ##shl-imm } ;
267
268 HELP: %spill
269 { $values
270   { "src" "source register" }
271   { "rep" representation }
272   { "dst" spill-slot }
273 } { $description "Emits machine code for spilling a register to a spill slot." }
274 { $see-also %reload } ;
275
276 HELP: %store-memory-imm
277 { $values
278   { "value" "source register" }
279   { "base" "base register for memory" }
280   { "offset" "memory offset" }
281   { "rep" "representation" }
282   { "c-type" "a c type or " { $link f } }
283 }
284 { $description "Emits machine code for " { $link ##store-memory-imm } " instructions." }
285 { $examples
286   { $unchecked-example
287     "USING: cpu.architecture prettyprint ;"
288     "[ XMM0 RBX 5 double-rep f %store-memory-imm ] B{ } make disassemble"
289     "0000000002800ae0: f2480f114305  movsd [rbx+0x5], xmm0"
290   }
291 } ;
292
293 HELP: %test-imm-branch
294 { $values
295   { "label" "branch destination" }
296   { "cc" "comparison symbol" }
297   { "src1" "register" }
298   { "src2" "immediate" }
299 } { $description "Emits a TEST instruction with a register and an immediate, followed by a branch." } ;
300
301 HELP: %unbox
302 { $values
303   { "dst" "destination register" }
304   { "src" "source register" }
305   { "func" "function?" }
306   { "rep" representation }
307 }
308 { $description "Call a function to convert a tagged pointer into a value that can be passed to a C function, or returned from a callback." } ;
309
310 HELP: %vector>scalar
311 { $values
312   { "dst" "destination register" }
313   { "src" "source register" }
314   { "rep" representation }
315 }
316 { $description "Converts the contents of a SIMD register to a scalar. On x86 this instruction is a noop." } ;
317
318 HELP: %write-barrier
319 { $values
320   { "src" "a register symbol" }
321   { "slot" "a register symbol" }
322   { "scale" integer }
323   { "tag" integer }
324   { "temp1" "a register symbol" }
325   { "temp2" "a register symbol" }
326 }
327 { $description "Generates code for the " { $link ##write-barrier } " instruction." }
328 { $examples { $unchecked-example $[ ex-%write-barrier ] } } ;
329
330 HELP: complex-addressing?
331 { $values { "?" boolean } }
332 { $description "Specifies if " { $link %slot } ", " { $link %set-slot } " and " { $link %write-barrier } " accept the 'scale' and 'tag' parameters, and if %load-memory and %store-memory work." } ;
333
334 HELP: double-2-rep
335 { $var-description "Representation for a pair of doubles." } ;
336
337 HELP: dummy-fp-params?
338 { $values { "?" boolean } }
339 { $description "Whether the architecture's ABI uses dummy floating point parameters. If it does, then the corresponding floating point register is 'dummy allocated' when an integer register is allocated." } { $see-also dummy-int-params? } ;
340
341 HELP: dummy-int-params?
342 { $values { "?" boolean } }
343 { $description "Whether the architecture's ABI uses dummy integer parameters. If it does, then the corresponding integer register is 'dummy allocated' when a floating point register is allocated." } { $see-also dummy-fp-params? } ;
344
345 HELP: float-regs
346 { $description "Floating point register class." } ;
347
348 HELP: fused-unboxing?
349 { $values { "?" boolean } }
350 { $description "Whether this architecture support " { $link %load-float } ", " { $link %load-double } ", and " { $link %load-vector } "." } ;
351
352 HELP: enable-cpu-features
353 { $description "This word is run when compiling the compiler during bootstrap and enables optional features that the processor is found to support." } ;
354
355 HELP: gc-root-offset
356 { $values { "spill-slot" spill-slot } { "n" integer } }
357 { $description "Offset in the " { $link stack-frame } " for the word being constructed where the spill slot is located. The value is given in " { $link cell } " units." }
358 { $see-also gc-info } ;
359
360 HELP: immediate-arithmetic?
361 { $values { "n" number } { "?" boolean } }
362 { $description
363   "Can this value be an immediate operand for " { $link %add-imm } ", "
364   { $link %sub-imm } ", or " { $link %mul-imm } "?"
365 } ;
366
367 HELP: immediate-bitwise?
368 { $values { "n" number } { "?" boolean } }
369 { $description "Can this value be an immediate operand for %and-imm, %or-imm, or %xor-imm?" } ;
370
371 HELP: immediate-comparand?
372 { $values { "n" number } { "?" boolean } }
373 { $description "Can this value be an immediate operand for %compare-imm or %compare-imm-branch?" } ;
374
375 HELP: immediate-store?
376 { $values { "n" number } { "?" boolean } }
377 { $description "Can this value be an immediate operand for %replace-imm?" } ;
378
379 HELP: int-regs
380 { $description "Integer register class." } ;
381
382 HELP: machine-registers
383 { $values { "assoc" assoc } }
384 { $description "Mapping from register class to machine registers. Only registers not reserved by the Factor VM are included." } ;
385
386 HELP: param-regs
387 { $values { "abi" "a calling convention symbol" } { "regs" assoc } }
388 { $description "Retrieves the order in which machine registers are used for parameters for the given calling convention." } ;
389
390 HELP: rep-size
391 { $values { "rep" representation } { "n" integer } }
392 { $description "Size in bytes of a representation." }
393 { $see representation } ;
394
395 HELP: reg-class-of
396 { $values { "rep" representation } { "reg-class" reg-class } }
397 { $description "Register class for values of the given representation." } ;
398
399 HELP: return-regs
400 { $values { "regs" assoc } }
401 { $description "What registers that will be used for function return values of which class." } ;
402
403 HELP: return-struct-in-registers?
404 { $values { "c-type" class } { "?" boolean } }
405 { $description "Whether the size of the struct is so small that it will be returned in registers or not." } ;
406
407 HELP: signed-rep
408 { $values { "rep" representation } { "rep'" representation } }
409 { $description "Maps any representation to its signed counterpart, if it has one." } ;
410
411 HELP: stack-cleanup
412 { $values
413   { "stack-size" integer }
414   { "return" "a c type" }
415   { "abi" abi }
416   { "n" integer }
417 }
418 { $description "Calculates how many bytes of stack space the caller of the procedure being constructed need to cleanup. For modern abi's the value is almost always 0." }
419 { $examples
420   { $unchecked-example
421     "USING: cpu.architecture prettyprint ;"
422     "20 void stdcall stack-cleanup ."
423     "20"
424   }
425 } ;
426
427 HELP: stack-frame-size
428 { $values
429   { "stack-frame" stack-frame }
430   { "n" integer }
431 } { $description "Calculates the total size of a stack frame, including padding and alignment." } ;
432
433 HELP: test-instruction?
434 { $values { "?" boolean } }
435 { $description "Does the current architecture have a test instruction? Used on x86 to rewrite some " { $link CMP } " instructions to less expensive " { $link TEST } "s." } ;
436
437 HELP: vm-stack-space
438 { $values { "n" number } }
439 { $description "Parameter space to reserve in anything making VM calls. Why is this set to 16 on x86.32?" } ;
440
441 ARTICLE: "cpu.architecture" "CPU architecture description model"
442 "The " { $vocab-link "cpu.architecture" } " vocab contains generic words and hooks that serves as an api for the compiler towards the cpu architecture."
443 $nl
444 "Architecture support checks:"
445 { $subsections
446   complex-addressing?
447   dummy-int-params?
448   dummy-fp-params?
449   float-right-align-on-stack?
450   fused-unboxing?
451   test-instruction?
452 }
453 "Arithmetic:"
454 { $subsections
455   %add
456   %add-imm
457   %sub
458   %sub-imm
459   %mul
460   %mul-imm
461   %neg
462 }
463 "Bit twiddling:"
464 { $subsections
465   %and
466   %and-imm
467   %not
468   %or
469   %or-imm
470   %sar
471   %sar-imm
472   %shl
473   %shl-imm
474   %shr
475   %shr-imm
476   %xor
477   %xor-imm
478 }
479 "Control flow code emitters:"
480 { $subsections
481   %call
482   %epilogue
483   %jump
484   %jump-label
485   %prologue
486   %return
487   %safepoint
488 }
489 "Foreign function interface:"
490 { $subsections %c-invoke }
491 "Garbage collection:"
492 { $subsections
493   %call-gc
494   %check-nursery-branch
495 }
496 "Moving values around:"
497 { $subsections
498   %clear
499   %peek
500   %replace
501   %replace-imm
502 }
503 "Register categories:"
504 { $subsections
505   machine-registers
506   param-regs
507   return-regs
508 }
509 "Representation metadata:"
510 { $subsections
511   narrow-vector-rep
512   reg-class-of
513   rep-component-type
514   rep-length
515   rep-size
516   scalar-rep-of
517   signed-rep
518   widen-vector-rep
519 }
520 "Slot access:"
521 { $subsections
522   %set-slot
523   %set-slot-imm
524   %slot
525   %slot-imm
526   %write-barrier
527 }
528 "Spilling & reloading:"
529 { $subsections %spill %reload gc-root-offset }
530 "Value as immediate checks:"
531 { $subsections
532   immediate-arithmetic?
533   immediate-bitwise?
534   immediate-comparand?
535   immediate-store?
536   immediate-shift-count?
537 } ;
538
539 ABOUT: "cpu.architecture"