]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/cpu/x86/x86.factor
Merge branch 'master' into simd-cleanup
[factor.git] / basis / cpu / x86 / x86.factor
index d78d8c852ed5aff5de455a69bcc01f82cfe03b22..0de9e7d1e49ff7490176971297beefbf21851f22 100644 (file)
@@ -45,8 +45,7 @@ HOOK: extra-stack-space cpu ( stack-frame -- n )
 : incr-stack-reg ( n -- )
     dup 0 = [ drop ] [ stack-reg swap ADD ] if ;
 
-: align-stack ( n -- n' )
-    os macosx? cpu x86.64? or [ 16 align ] when ;
+: align-stack ( n -- n' ) 16 align ;
 
 M: x86 stack-frame-size ( stack-frame -- i )
     [ (stack-frame-size) ]
@@ -141,8 +140,10 @@ M: x86 %not     int-rep one-operand NOT ;
 M: x86 %neg     int-rep one-operand NEG ;
 M: x86 %log2    BSR ;
 
+! A bit of logic to avoid using MOVSS/MOVSD for reg-reg moves
+! since this induces partial register stalls
 GENERIC: copy-register* ( dst src rep -- )
-GENERIC: copy-unaligned* ( dst src rep -- )
+GENERIC: copy-memory* ( dst src rep -- )
 
 M: int-rep copy-register* drop MOV ;
 M: tagged-rep copy-register* drop MOV ;
@@ -152,17 +153,14 @@ M: float-4-rep copy-register* drop MOVAPS ;
 M: double-2-rep copy-register* drop MOVAPS ;
 M: vector-rep copy-register* drop MOVDQA ;
 
-M: object copy-unaligned* copy-register* ;
-M: float-rep copy-unaligned* drop MOVSS ;
-M: double-rep copy-unaligned* drop MOVSD ;
-M: float-4-rep copy-unaligned* drop MOVUPS ;
-M: double-2-rep copy-unaligned* drop MOVUPS ;
-M: vector-rep copy-unaligned* drop MOVDQU ;
+M: object copy-memory* copy-register* ;
+M: float-rep copy-memory* drop MOVSS ;
+M: double-rep copy-memory* drop MOVSD ;
 
 M: x86 %copy ( dst src rep -- )
     2over eq? [ 3drop ] [
         [ [ dup spill-slot? [ n>> spill@ ] when ] bi@ ] dip
-        2over [ register? ] both? [ copy-register* ] [ copy-unaligned* ] if
+        2over [ register? ] both? [ copy-register* ] [ copy-memory* ] if
     ] if ;
 
 M: x86 %fixnum-add ( label dst src1 src2 -- )
@@ -177,76 +175,109 @@ M: x86 %fixnum-mul ( label dst src1 src2 -- )
 M: x86 %unbox-alien ( dst src -- )
     alien-offset [+] MOV ;
 
-M:: x86 %unbox-any-c-ptr ( dst src temp -- )
+M:: x86 %unbox-any-c-ptr ( dst src -- )
     [
-        { "is-byte-array" "end" "start" } [ define-label ] each
-        dst 0 MOV
-        temp src MOV
-        ! We come back here with displaced aliens
-        "start" resolve-label
+        "end" define-label
+        dst dst XOR
         ! Is the object f?
-        temp \ f tag-number CMP
+        src \ f type-number CMP
         "end" get JE
+        ! Compute tag in dst register
+        dst src MOV
+        dst tag-mask get AND
         ! Is the object an alien?
-        temp header-offset [+] alien type-number tag-fixnum CMP
-        "is-byte-array" get JNE
-        ! If so, load the offset and add it to the address
-        dst temp alien-offset [+] ADD
-        ! Now recurse on the underlying alien
-        temp temp underlying-alien-offset [+] MOV
-        "start" get JMP
-        "is-byte-array" resolve-label
-        ! Add byte array address to address being computed
-        dst temp ADD
+        dst alien type-number CMP
         ! Add an offset to start of byte array's data
-        dst byte-array-offset ADD
+        dst src byte-array-offset [+] LEA
+        "end" get JNE
+        ! If so, load the offset and add it to the address
+        dst src alien-offset [+] MOV
         "end" resolve-label
     ] with-scope ;
 
-: alien@ ( reg n -- op ) cells alien tag-number - [+] ;
-
-:: %allot-alien ( dst displacement base temp -- )
-    dst 4 cells alien temp %allot
-    dst 1 alien@ base MOV ! alien
-    dst 2 alien@ \ f tag-number MOV ! expired
-    dst 3 alien@ displacement MOV ! displacement
-    ;
+: alien@ ( reg n -- op ) cells alien type-number - [+] ;
 
 M:: x86 %box-alien ( dst src temp -- )
     [
         "end" define-label
-        dst \ f tag-number MOV
-        src 0 CMP
+        dst \ f type-number MOV
+        src src TEST
         "end" get JE
-        dst src \ f tag-number temp %allot-alien
+        dst 5 cells alien temp %allot
+        dst 1 alien@ \ f type-number MOV ! base
+        dst 2 alien@ \ f type-number MOV ! expired
+        dst 3 alien@ src MOV ! displacement
+        dst 4 alien@ src MOV ! address
         "end" resolve-label
     ] with-scope ;
 
-M:: x86 %box-displaced-alien ( dst displacement base displacement' base' base-class -- )
+M:: x86 %box-displaced-alien ( dst displacement base temp base-class -- )
+    ! This is ridiculous
     [
         "end" define-label
-        "ok" define-label
+        "not-f" define-label
+        "not-alien" define-label
+
         ! If displacement is zero, return the base
         dst base MOV
-        displacement 0 CMP
+        displacement displacement TEST
         "end" get JE
-        ! Quickly use displacement' before its needed for real, as allot temporary
-        dst 4 cells alien displacement' %allot
-        ! If base is already a displaced alien, unpack it
-        base' base MOV
-        displacement' displacement MOV
-        base \ f tag-number CMP
-        "ok" get JE
-        base header-offset [+] alien type-number tag-fixnum CMP
-        "ok" get JNE
-        ! displacement += base.displacement
-        displacement' base 3 alien@ ADD
-        ! base = base.base
-        base' base 1 alien@ MOV
-        "ok" resolve-label
-        dst 1 alien@ base' MOV ! alien
-        dst 2 alien@ \ f tag-number MOV ! expired
-        dst 3 alien@ displacement' MOV ! displacement
+
+        ! Displacement is non-zero, we're going to be allocating a new
+        ! object
+        dst 5 cells alien temp %allot
+
+        ! Set expired to f
+        dst 2 alien@ \ f type-number MOV
+
+        ! Is base f?
+        base \ f type-number CMP
+        "not-f" get JNE
+
+        ! Yes, it is f. Fill in new object
+        dst 1 alien@ base MOV
+        dst 3 alien@ displacement MOV
+        dst 4 alien@ displacement MOV
+
+        "end" get JMP
+
+        "not-f" resolve-label
+
+        ! Check base type
+        temp base MOV
+        temp tag-mask get AND
+
+        ! Is base an alien?
+        temp alien type-number CMP
+        "not-alien" get JNE
+
+        ! Yes, it is an alien. Set new alien's base to base.base
+        temp base 1 alien@ MOV
+        dst 1 alien@ temp MOV
+
+        ! Compute displacement
+        temp base 3 alien@ MOV
+        temp displacement ADD
+        dst 3 alien@ temp MOV
+
+        ! Compute address
+        temp base 4 alien@ MOV
+        temp displacement ADD
+        dst 4 alien@ temp MOV
+
+        ! We are done
+        "end" get JMP
+
+        ! Is base a byte array? It has to be, by now...
+        "not-alien" resolve-label
+
+        dst 1 alien@ base MOV
+        dst 3 alien@ displacement MOV
+        temp base MOV
+        temp byte-array-offset ADD
+        temp displacement ADD
+        dst 4 alien@ temp MOV
+
         "end" resolve-label
     ] with-scope ;
 
@@ -396,13 +427,13 @@ M: x86 %vm-field-ptr ( dst field -- )
     [ drop "nursery" %vm-field-ptr ] [ swap [] MOV ] 2bi ;
 
 : inc-allot-ptr ( nursery-ptr n -- )
-    [ [] ] dip 8 align ADD ;
+    [ [] ] dip data-alignment get align ADD ;
 
 : store-header ( temp class -- )
     [ [] ] [ type-number tag-fixnum ] bi* MOV ;
 
 : store-tagged ( dst tag -- )
-    tag-number OR ;
+    type-number OR ;
 
 M:: x86 %allot ( dst size class nursery-ptr -- )
     nursery-ptr dst load-allot-ptr
@@ -444,7 +475,7 @@ M: x86 %alien-global ( dst symbol library -- )
 M: x86 %epilogue ( n -- ) cell - incr-stack-reg ;
 
 :: %boolean ( dst temp word -- )
-    dst \ f tag-number MOV
+    dst \ f type-number MOV
     temp 0 MOV \ t rc-absolute-cell rel-immediate
     dst temp word execute ; inline