From 7ebd63a2174daa059d01dda12b3170806e286cf5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Lindqvist?= <bjourne@gmail.com>
Date: Sun, 16 Nov 2014 12:35:52 +0100
Subject: [PATCH] cpu.architecture: docs and some tests

---
 .../cpu/architecture/architecture-docs.factor | 30 +++++++++++++++++--
 .../architecture/architecture-tests.factor    | 19 ++++++++++++
 basis/cpu/architecture/architecture.factor    |  2 --
 3 files changed, 47 insertions(+), 4 deletions(-)
 create mode 100644 basis/cpu/architecture/architecture-tests.factor

diff --git a/basis/cpu/architecture/architecture-docs.factor b/basis/cpu/architecture/architecture-docs.factor
index b49d6c0321..ddf4972d1c 100644
--- a/basis/cpu/architecture/architecture-docs.factor
+++ b/basis/cpu/architecture/architecture-docs.factor
@@ -1,6 +1,7 @@
-USING: assocs alien classes compiler.cfg.instructions cpu.x86.assembler
-cpu.x86.assembler.operands help.markup help.syntax kernel
+USING: assocs alien classes compiler.cfg.instructions compiler.cfg.stack-frame
+cpu.x86.assembler cpu.x86.assembler.operands help.markup help.syntax kernel
 layouts literals math multiline system words ;
+QUALIFIED: vm
 IN: cpu.architecture
 
 <<
@@ -52,6 +53,12 @@ USING: cpu.architecture make ;
 0000000000e63abc: 4c897010    mov [rax+0x10], r14
 0000000000e63ac0: 4c897818    mov [rax+0x18], r15
 ;
+
+STRING: ex-%copy
+USING: cpu.architecture make ;
+RAX RBX int-rep [ %copy ] B{ } make disassemble
+000000000108a970: 4889d8  mov rax, rbx
+;
 >>
 
 HELP: signed-rep
@@ -104,6 +111,11 @@ HELP: %context
 { $description "Emits machine code for putting a pointer to the context field of the " { $link vm } " in a register." }
 { $examples { $unchecked-example $[ ex-%context ] } } ;
 
+HELP: %copy
+{ $values { "dst" "destination" } { "src" "source" } { "rep" representation } }
+{ $description "Emits code copying a value from a register, arbitrary memory location or " { $link spill-slot } " to a destination." }
+{ $examples { $unchecked-example $[ ex-%copy ] } } ;
+
 HELP: %safepoint
 { $description "Emits a safe point to the current code sequence being generated." }
 { $examples { $unchecked-example $[ ex-%safepoint ] } } ;
@@ -127,6 +139,15 @@ HELP: %allot
   { $unchecked-example $[ ex-%allot ] }
 } ;
 
+HELP: %local-allot
+{ $values
+  { "dst" "destination register symbol" }
+  { "size" "number of bytes to allocate" }
+  { "align" "alignment" }
+  { "offset" "where to allocate the data, relative to the stack register" }
+}
+{ $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." } ;
+
 HELP: test-instruction?
 { $values { "?" "a boolean" } }
 { $description "Does the current architecture have a test instruction? Used on x86 to rewrite some " { $link CMP } " instructions to less expensive " { $link TEST } "s." } ;
@@ -159,6 +180,11 @@ HELP: stack-cleanup
   }
 } ;
 
+HELP: gc-root-offset
+{ $values { "spill-slot" spill-slot } { "n" integer } }
+{ $description "Offset in the " { $link stack-frame } " for the word being constructed where the spill slot is located, in " { $link cell } " units." }
+{ $see-also vm:gc-info } ;
+
 ARTICLE: "cpu.architecture" "CPU architecture description model"
 "The " { $vocab-link "cpu.architecture" } " vocab contains generic words and hooks that serves as an api for the compiler towards the cpu architecture."
 $nl
diff --git a/basis/cpu/architecture/architecture-tests.factor b/basis/cpu/architecture/architecture-tests.factor
new file mode 100644
index 0000000000..e62c93d5d1
--- /dev/null
+++ b/basis/cpu/architecture/architecture-tests.factor
@@ -0,0 +1,19 @@
+USING: compiler.cfg.instructions compiler.cfg.stack-frame kernel namespaces
+system tools.test ;
+IN: cpu.architecture
+
+cpu x86.64? [
+    ! The offset is 1, not 0 because the return address occupies the
+    ! first position in the stack frame.
+    { 1 } [
+        T{ stack-frame { spill-area-base 0 } } stack-frame [
+            T{ spill-slot { n 0 } } gc-root-offset
+        ] with-variable
+    ] unit-test
+
+    { 10 } [
+        T{ stack-frame { spill-area-base 64 } } stack-frame [
+            T{ spill-slot { n 8 } } gc-root-offset
+        ] with-variable
+    ] unit-test
+] when
diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor
index af55954540..c2242bdfb6 100644
--- a/basis/cpu/architecture/architecture.factor
+++ b/basis/cpu/architecture/architecture.factor
@@ -548,10 +548,8 @@ M: object immediate-comparand? ( n -- ? )
 
 HOOK: return-regs cpu ( -- regs )
 
-! Registers used for parameter passing
 HOOK: param-regs cpu ( abi -- regs )
 
-! Is this structure small enough to be returned in registers?
 HOOK: return-struct-in-registers? cpu ( c-type -- ? )
 
 ! Do we pass this struct by value or hidden reference?