ref: 7d3fb4d665372fe975403ff80f32500204454d3b
dir: /os/pc64/bindings.s/
/* This file is the forth equivalent of os/port/inferno.c It contains forth bindings for the functions in os/port/sysfile.c */ /* plan9 assembler puts the first argument in R8 (RARG), return value in AX. Caller saves registers - plan9 convention not maintaining the values of the temporary registers or EFLAGS */ /* using ( 2nd_parameter 1st_parameter -- ) mode fd open simpler code, more comprehensible with the 1st arg next to the call - my opinion instead of ( 1st_parameter 2nd_parameter -- ) fd mode open might revisit this later after a trial there is no forth word for this. It is call'able by the bindings subroutines cannot get this to work and I cannot decipher it with all the psuedo register nonsense */ //TEXT ff_to_c(SB), $0 /* ( argn .. arg2 arg1 nargs -- ) (G move args to C stack) */ // POPQ SI /* get my return PC from the stack */ // MOVQ TOP, CX /* check nargs */ // POP(TOP) // TESTQ $0, CX // JZ .ff_to_c_done /* no args */ // MOVQ TOP, RARG /* 1st argument is put in RARG also */ //.ff_to_c_again: // PUSHQ TOP // POP(TOP) // LOOP .ff_to_c_again //.ff_to_c_done: // STOREFORTH // JMP* SI /* go back to the caller */ #define STORE(x,y) \ MOVQ $y, CX; \ ADDQ UP, CX; \ MOVQ x, 0(CX); #define STOREFORTH \ STORE(TOP,FORTHTOP);\ STORE(PSP,FORTHPSP);\ STORE(RSP,FORTHRSP);\ STORE(IP,FORTHIP);\ STORE(W,FORTHW);\ STORE(UP,FORTHUP);\ STORE(UPE,FORTHUPE); #define RESTORE(x,y) \ MOVQ $x, CX; \ ADDQ UP, CX; \ MOVQ 0(CX), y; #define RESTOREFORTH \ RESTORE(FORTHTOP,TOP);\ RESTORE(FORTHPSP,PSP);\ RESTORE(FORTHRSP,RSP);\ RESTORE(FORTHIP,IP);\ RESTORE(FORTHW,W);\ RESTORE(FORTHUP,UP);\ RESTORE(FORTHUPE,UPE); #define C_TO_F_0 \ RESTOREFORTH; #define C_TO_F_1 /* there is a returned argument */\ C_TO_F_0; \ PUSH(TOP); \ MOVQ AX, TOP; /* C puts the return value in AX */\ #define F_TO_C_3 \ MOVQ TOP, RARG;\ POP(TOP);\ MOVQ TOP, 8(SP);\ POP(TOP);\ MOVQ TOP, 16(SP);\ POP(TOP);\ STOREFORTH; #define F_TO_C_2 \ MOVQ TOP, RARG;\ POP(TOP);\ MOVQ TOP, 8(SP);\ POP(TOP);\ STOREFORTH; #define F_TO_C_1 \ MOVQ TOP, RARG;\ POP(TOP);\ STOREFORTH; TEXT fsopen(SB), 1, $24 /* ( mode cstr -- fd ) */ MOVQ UP, 16(SP) F_TO_C_2 CALL kopen(SB) MOVQ 16(SP), UP C_TO_F_1 ADDQ $24, SP NEXT TEXT fsclose(SB), 1, $16 /* ( fd -- n ) */ MOVQ UP, 8(SP) F_TO_C_1 CALL kclose(SB) MOVQ 24(SP), UP C_TO_F_1 ADDQ $16, SP NEXT /* * no link register in amd64 * 3 arguments for kwrite = 24 bytes * 1 local for storing UP = 8 bytes * 1 local for storing fd * Hence, need 40 bytes on the stack * if fd == 0 and read return value == 0 == End of file, terminate */ TEXT fsread(SB), 1, $40 /* ( n a fd -- n2 ) */ PUSH(TOP) MOVQ 16(PSP), TOP MOVQ 8(PSP), CX PUSH(TOP) MOVQ CX, TOP /* ( n a fd -- n a fd n a ) */ CALL validatebuffer(SB) /* ( n a fd ) */ MOVQ TOP, 32(SP) /* storing the fd to double check later */ MOVQ UP, 24(SP) F_TO_C_3 CALL kread(SB) MOVQ 24(SP), UP C_TO_F_1 TESTQ TOP, TOP /* check read return value */ JNZ fsread_continue MOVQ 32(SP), CX /* read return value == 0 */ TESTQ CX, CX JNZ fsread_continue JMP terminate(SB) /* and fd == 0, terminate */ fsread_continue: ADDQ $40, SP NEXT /* * no link register in amd64 * 3 arguments for kwrite = 24 bytes * 1 local for storing UP = 8 bytes * Hence, need 32 bytes on the stack */ TEXT fswrite(SB), 1, $32 /* ( n a fd -- n2|-1 ) */ PUSH(TOP) /* ( -- n a fd fd ) */ MOVQ 16(PSP), TOP /* TOP = n */ MOVQ 8(PSP), CX /* CX = a */ PUSH(TOP) /* ( -- n a fd n n ) */ MOVQ CX, TOP /* ( n a fd -- n a fd n a ) */ CALL validatebuffer(SB) MOVQ UP, 24(SP) F_TO_C_3 CALL kwrite(SB) MOVQ 24(SP), UP C_TO_F_1 ADDQ $32, SP NEXT TEXT fsseek(SB), 1, $32 /* ( type pos fd -- n ) */ MOVQ UP, 24(SP) F_TO_C_3 CALL kseek(SB) MOVQ 24(SP), UP C_TO_F_1 ADDQ $32, SP NEXT