code: 9ferno

Download patch

ref: 91f2ea9edb3d2b74afcecfcc3a692b9a506e95f1
parent: 40554c2f569dbfca2823883f856ed2a68404e09b
author: jro <jro@freeshell.org>
date: Thu Aug 26 21:30:40 EDT 2021

Linux amd64 patch

One thing I noticed that could be propagated to other platforms are all the getcallerpc-<ARCH>.S files under lib9 - gcc and clang have a builtin that do what should happen for that function, and it might be worth it to use that across the board for any host OS that uses gcc and/or clang. That was really the only hard part I ran into and took any major amount of research on my part.

John Osborne

--- /dev/null
+++ b/emu/Linux/asm-amd64.S
@@ -1,0 +1,43 @@
+	.file	"asm-Linux-amd64.S"
+	.text
+
+/*
+ * umult(ulong m1, ulong m2, ulong *hi)
+ */
+
+	.type	umult,@function
+	.global	umult
+umult:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	pushq	%rbx  /* not %rsi ? */
+
+	movq	16(%rbp), %rax
+	movq	24(%rbp), %rbx
+	mulq	%rbx
+	movq	32(%rbp), %rbx
+	movq	%rdx, (%rbx)
+
+	popq	%rbx
+	popq	%rbp
+	ret
+
+	.type	FPsave,@function
+	.global	FPsave
+FPsave:
+	fstenv (%rdi)
+	ret
+
+	.type	FPrestore,@function
+	.global	FPrestore
+FPrestore:
+	fldenv	(%rdi)
+	ret
+
+	.type	_tas,@function
+	.globl	_tas
+_tas:
+	movl	$1, %eax
+	xchgl	%eax, 0(%rdi)		/* rdi has the first argument to a function */
+	ret
+
--- /dev/null
+++ b/emu/Linux/segflush-amd64.c
@@ -1,0 +1,11 @@
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+#include "dat.h"
+
+int
+segflush(void *a, ulong n)
+{
+	USED(a); USED(n);
+	return 0;
+}
--- a/emu/Linux/srv.h
+++ b/emu/Linux/srv.h
@@ -4,7 +4,7 @@
 {
 	WORD	regs[NREG-1];
 	WORD	noret;
-	uchar	temps[12];
+	uchar	temps[24];
 };
 void Srv_ipa2h(void*);
 typedef struct F_Srv_ipa2h F_Srv_ipa2h;
@@ -12,7 +12,7 @@
 {
 	WORD	regs[NREG-1];
 	List**	ret;
-	uchar	temps[12];
+	uchar	temps[24];
 	String*	addr;
 };
 void Srv_iph2a(void*);
@@ -21,7 +21,7 @@
 {
 	WORD	regs[NREG-1];
 	List**	ret;
-	uchar	temps[12];
+	uchar	temps[24];
 	String*	host;
 };
 void Srv_ipn2p(void*);
@@ -30,7 +30,7 @@
 {
 	WORD	regs[NREG-1];
 	String**	ret;
-	uchar	temps[12];
+	uchar	temps[24];
 	String*	net;
 	String*	service;
 };
--- a/emu/Linux/srvm.h
+++ b/emu/Linux/srvm.h
@@ -1,9 +1,9 @@
 typedef struct{char *name; long sig; void (*fn)(void*); int size; int np; uchar map[16];} Runtab;
 Runtab Srvmodtab[]={
-	"init",0x9cd71c5e,Srv_init,32,0,{0},
-	"ipa2h",0xaf4c19dd,Srv_ipa2h,40,2,{0x0,0x80,},
-	"iph2a",0xaf4c19dd,Srv_iph2a,40,2,{0x0,0x80,},
-	"ipn2p",0xea1a6969,Srv_ipn2p,40,2,{0x0,0xc0,},
+	"init",0x9cd71c5e,Srv_init,64,0,{0},
+	"ipa2h",0xaf4c19dd,Srv_ipa2h,72,2,{0x0,0x80,},
+	"iph2a",0xaf4c19dd,Srv_iph2a,72,2,{0x0,0x80,},
+	"ipn2p",0xea1a6969,Srv_ipn2p,80,2,{0x0,0xc0,},
 	0
 };
 #define Srvmodlen	4
--- /dev/null
+++ b/lib9/getcallerpc-Linux-amd64.c
@@ -1,0 +1,12 @@
+#include <lib9.h>
+
+uintptr
+getcallerpc(void *x)
+{
+//uintptr *lp;
+
+//	lp = x;
+
+//	return lp[-1];
+	return (uintptr) __builtin_return_address(0);
+}
--- a/lib9/pow10.c
+++ b/lib9/pow10.c
@@ -1,6 +1,9 @@
 #ifdef	LINUX_386
 #define	_MATH_H
 #endif
+#ifdef	LINUX_AMD64
+#define	_MATH_H
+#endif
 #include	"lib9.h"
 
 /*
--- /dev/null
+++ b/lib9/setfcr-Linux-amd64.S
@@ -1,0 +1,34 @@
+
+#define	FN(x)	.type x,@function; .global x; x
+#define	ENT	subq $32, %rsp
+#define	RET	addq $32, %rsp; ret
+
+	.file	"setfcr-Linux-amd64.S"
+FN(setfcr):
+	ENT
+	xorb	$0x3f, %al
+	movq	%rax, (%rsp)
+	fwait
+	fldcw	(%rsp)
+	RET
+
+FN(getfcr):
+	ENT
+	fwait
+	fstcw	(%rsp)
+	movw	(%rsp), %ax
+	andq	$0xffffff, %rax
+	xorb	$0x3f, %al
+	RET
+
+FN(getfsr):
+	ENT
+	fwait
+	fstsw	(%rsp)
+	movw	(%rsp), %ax
+	andq	$0xffffff, %rax
+	RET
+
+FN(setfsr):
+	fclex
+	ret
--- a/libkern/pow10.c
+++ b/libkern/pow10.c
@@ -1,6 +1,9 @@
 #ifdef	LINUX_386
 #define	_MATH_H
 #endif
+#ifdef	LINUX_AMD64
+#define	_MATH_H
+#endif
 #include	"lib9.h"
 
 /*