! Copyright (C) 2005, 2006 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. IN: compiler USING: alien assembler kernel kernel-internals math math-internals namespaces sequences words ; : untag ( dest src -- ) 0 0 31 tag-bits - RLWINM ; : tag-fixnum ( src dest -- ) tag-bits SLWI ; : untag-fixnum ( src dest -- ) tag-bits SRAWI ; \ tag [ "in" operand "out" operand tag-mask ANDI "out" operand dup tag-fixnum ] H{ { +input { { f "in" } } } { +scratch { { f "out" } } } { +output { "out" } } } define-intrinsic : generate-slot ( size quot -- ) >r >r ! turn tagged fixnum slot # into an offset, multiple of 4 "n" operand dup tag-bits r> - SRAWI ! compute slot address "obj" operand dup "n" operand ADD ! load slot value "obj" operand dup r> call ; inline \ slot [ "obj" operand dup untag cell log2 [ 0 LWZ ] generate-slot ] H{ { +input { { f "obj" } { f "n" } } } { +output { "obj" } } } define-intrinsic \ char-slot [ 1 [ string-offset LHZ ] generate-slot "obj" operand dup tag-fixnum ] H{ { +input { { f "n" } { f "obj" } } } { +output { "obj" } } } define-intrinsic : generate-set-slot ( size quot -- ) >r >r ! turn tagged fixnum slot # into an offset, multiple of 4 "slot" operand dup tag-bits r> - SRAWI ! compute slot address in 1st input "slot" operand dup "obj" operand ADD ! store new slot value "val" operand "slot" operand r> call ; inline : generate-write-barrier ( -- ) #! Mark the card pointed to by vreg. "obj" operand dup card-bits SRAWI "obj" operand dup 16 ADD "x" operand "obj" operand 0 LBZ "x" operand dup card-mark ORI "x" operand "obj" operand 0 STB ; \ set-slot [ "obj" operand dup untag cell log2 [ 0 STW ] generate-set-slot generate-write-barrier ] H{ { +input { { f "val" } { f "obj" } { f "slot" } } } { +scratch { { f "x" } } } { +clobber { "obj" } } } define-intrinsic \ set-char-slot [ ! untag the new value in 0th input "val" operand dup untag-fixnum 1 [ string-offset STH ] generate-set-slot ] H{ { +input { { f "val" } { f "slot" } { f "obj" } } } { +scratch { { f "x" } } } { +clobber { "obj" } } } define-intrinsic : define-binary-op ( word op -- ) [ [ "x" operand "y" operand "x" operand ] % , ] [ ] make H{ { +input { { f "x" } { f "y" } } } { +output { "x" } } } define-intrinsic ; { { fixnum+fast ADD } { fixnum-fast SUBF } { fixnum-bitand AND } { fixnum-bitor OR } { fixnum-bitxor XOR } } [ first2 define-binary-op ] each : generate-fixnum-mod #! PowerPC doesn't have a MOD instruction; so we compute #! x-(x/y)*y. Puts the result in "s" operand. "s" operand "r" operand "y" operand MULLW "s" operand "s" operand "x" operand SUBF ; \ fixnum-mod [ ! divide x by y, store result in x "r" operand "x" operand "y" operand DIVW generate-fixnum-mod "x" operand "s" operand MR ] H{ { +input { { f "x" } { f "y" } } } { +scratch { { f "r" } { f "s" } } } { +output { "x" } } } define-intrinsic \ fixnum-bitnot [ "x" operand dup NOT "x" operand dup untag ] H{ { +input { { f "x" } } } { +output { "x" } } } define-intrinsic : define-binary-jump ( word op -- ) [ [ end-basic-block "x" operand 0 "y" operand CMP ] % , ] [ ] make H{ { +input { { f "x" } { f "y" } } } } define-if-intrinsic ; { { fixnum< BLT } { fixnum<= BLE } { fixnum> BGT } { fixnum>= BGE } { eq? BEQ } } [ first2 define-binary-jump ] each \ type [