] when ;\r
\r
: (objects>registers) ( vregs -- )\r
- ! Place instructions in reverse order, so that the\r
- ! ##store-stack-param instructions come first. This ensures\r
+ ! Place ##store-stack-param instructions first. This ensures\r
! that no registers are used after the ##store-reg-param\r
! instructions.\r
[\r
[ [ alloc-stack-param ] keep \ ##store-stack-param new-insn ]\r
[ [ next-reg-param ] keep \ ##store-reg-param new-insn ]\r
if\r
- ] map reverse % ;\r
+ ] map [ ##store-stack-param? ] partition [ % ] bi@ ;\r
\r
: objects>registers ( params -- stack-size )\r
[ abi>> ] [ parameters>> ] [ return>> ] tri\r
\r
M: struct-c-type flatten-c-type\r
flatten-struct-type [ first2 [ drop stack-params ] when ] map ;\r
+ \r
M: long-long-type flatten-c-type drop { int-rep int-rep } ;\r
-M: c-type flatten-c-type rep>> 1array ;\r
+\r
+M: c-type flatten-c-type\r
+ rep>> {\r
+ { int-rep [ { int-rep } ] }\r
+ { float-rep [ float-on-stack? { stack-params } { float-rep } ? ] }\r
+ { double-rep [\r
+ float-on-stack?\r
+ cell 4 = { stack-params stack-params } { stack-params } ?\r
+ { double-rep } ?\r
+ ] }\r
+ } case ;\r
+ \r
M: object flatten-c-type base-type flatten-c-type ;\r
\r
: flatten-c-types ( types -- reps )\r
compiler.constants compiler.alien compiler.codegen
compiler.codegen.fixup compiler.cfg.instructions
compiler.cfg.builder compiler.cfg.builder.alien
+compiler.cfg.builder.alien.params
compiler.cfg.intrinsics compiler.cfg.stack-frame
cpu.x86.assembler cpu.x86.assembler.operands cpu.x86
cpu.architecture vm ;
M: int-rep load-return-reg drop EAX swap MOV ;
M: int-rep store-return-reg drop EAX MOV ;
-M: float-rep load-return-reg drop FLDS ;
-M: float-rep store-return-reg drop FSTPS ;
-
-M: double-rep load-return-reg drop FLDL ;
-M: double-rep store-return-reg drop FSTPL ;
+:: load-float-return ( src x87-insn sse-insn -- )
+ src register? [
+ ESP 4 SUB
+ ESP [] src sse-insn execute
+ ESP [] x87-insn execute
+ ESP 4 ADD
+ ] [
+ src x87-insn execute
+ ] if ; inline
+
+:: store-float-return ( dst x87-insn sse-insn -- )
+ dst register? [
+ ESP 4 SUB
+ ESP [] x87-insn execute
+ dst ESP [] sse-insn execute
+ ESP 4 ADD
+ ] [
+ dst x87-insn execute
+ ] if ; inline
+
+M: float-rep load-return-reg
+ drop \ FLDS \ MOVSS load-float-return ;
+
+M: float-rep store-return-reg
+ drop \ FSTPS \ MOVSS store-float-return ;
+
+M: double-rep load-return-reg
+ drop \ FLDL \ MOVSD load-float-return ;
+
+M: double-rep store-return-reg
+ drop \ FSTPL \ MOVSD store-float-return ;
M: x86.32 %prologue ( n -- )
dup PUSH
M:: x86.32 %unbox ( dst src func rep -- )
src func call-unbox-func
- dst rep reg-class-of return-reg rep %copy ;
+ dst ?spill-slot rep store-return-reg ;
+
+M:: x86.32 %store-return ( src rep -- )
+ src ?spill-slot rep load-return-reg ;
-M:: x86.32 %store-long-long-return ( src1 src2 n func -- )
+M:: x86.32 %store-long-long-return ( src1 src2 -- )
src2 EAX = [ src1 src2 XCHG src2 src1 ] [ src1 src2 ] if :> ( src1 src2 )
EAX src1 int-rep %copy
EDX src2 int-rep %copy ;
bi and ;
: stack-arg-size ( params -- n )
- dup abi>> '[
+ dup abi>> [
alien-parameters flatten-c-types
- [ _ alloc-parameter 2drop ] each
+ [ alloc-parameter 2drop ] each
stack-params get
] with-param-regs ;
M: x86.32 long-long-on-stack? t ;
-M: x86.32 structs-on-stack? t ;
+M: x86.32 float-on-stack? t ;
+
+M: x86.32 flatten-struct-type
+ stack-size cell /i { int-rep t } <repetition> ;
M: x86.32 struct-return-on-stack? os linux? not ;
{ float-regs [ float-regs get pop swap MOVSD ] }
} case ;
+M:: x86.64 %store-return ( src rep -- )
+ rep reg-class-of return-reg src rep %copy ;
+
M:: x86.64 %store-struct-return ( src c-type -- )
! Move src to R11 so that we don't clobber it.
R11 src int-rep %copy
M: x86.64 long-long-on-stack? f ;
+M: x86.64 float-on-stack? f ;
+
M: x86.64 struct-return-on-stack? f ;
! The result of reading 4 bytes from memory is a fixnum on