ref: 8107a788ff769af07e522f6972653949b3c13046
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 CMPQ TOP, $-1 /* return value == -1? */ JEQ fsread_checkfd /* return value = -1 */ TESTQ TOP, TOP /* check if read return value == 0 */ JNZ fsread_continue fsread_checkfd: MOVQ 32(SP), CX /* read return value == 0, check if fd is stdin */ TESTQ CX, CX JNZ fsread_continue /* and fd == 0, terminate */ ADDQ $40, SP /* TODO * this should have been JMP terminate(SB), but it is raising a #GP error. * CALL terminate(SB) works fine. * Would have to dig through the amd64 manuals and * https://www.felixcloutier.com/x86/jmp to figure out why. * until then, use the label to jump to JMP to a label: JMP _fthterminate 2011b8 4883c428 (644) ADDQ $40,SP 2011bc e9d0fcffff (493) JMP ,200e91 2011c1 4883c428 (656) ADDQ $40,SP JMP to symbol: JMP terminate(SB) 2011b8 4883c428 (645) ADDQ $40,SP 2011bc ff2425910e2000 (654) JMP ,terminate+0(SB) 2011c3 4883c428 (657) ADDQ $40,SP CALL to symbol: CALL terminate(SB) 2011b8 4883c428 (645) ADDQ $40,SP 2011bc e8d0fcffff (655) CALL ,200e91+terminate 2011c1 4883c428 (657) ADDQ $40,SP */ JMP _fthterminate /* TODO fix this JMP terminate(SB) */ 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 TEXT fscreate(SB), 1, $32 /* ( perm mode cstr -- fd ) */ MOVQ UP, 24(SP) F_TO_C_3 CALL kcreate(SB) MOVQ 24(SP), UP C_TO_F_1 ADDQ $32, SP NEXT