commit 4362d9865b937ddf5ea74c0b3e7dece0239725dc
parent c36748c96ede909d985f6766f9a1a02647c582f8
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 24 Oct 2021 09:09:00 +0200
Initial FreeBSD support
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
16 files changed, 950 insertions(+), 13 deletions(-)
diff --git a/include/lex.h b/include/lex.h
@@ -137,10 +137,6 @@ enum lexical_token {
T_ERROR,
};
-#ifndef __STDC_IEC_559__
-#error "harec requires IEC 60559 (IEEE 754) floating-point arithmetic"
-#endif
-
struct location {
const char *path;
int lineno, colno;
diff --git a/rt/+freebsd/errno.ha b/rt/+freebsd/errno.ha
@@ -0,0 +1,99 @@
+export def EPERM: int = 1;
+export def ENOENT: int = 2;
+export def ESRCH: int = 3;
+export def EINTR: int = 4;
+export def EIO: int = 5;
+export def ENXIO: int = 6;
+export def E2BIG: int = 7;
+export def ENOEXEC: int = 8;
+export def EBADF: int = 9;
+export def ECHILD: int = 10;
+export def EDEADLK: int = 11;
+export def ENOMEM: int = 12;
+export def EACCES: int = 13;
+export def EFAULT: int = 14;
+export def ENOTBLK: int = 15;
+export def EBUSY: int = 16;
+export def EEXIST: int = 17;
+export def EXDEV: int = 18;
+export def ENODEV: int = 19;
+export def ENOTDIR: int = 20;
+export def EISDIR: int = 21;
+export def EINVAL: int = 22;
+export def ENFILE: int = 23;
+export def EMFILE: int = 24;
+export def ENOTTY: int = 25;
+export def ETXTBSY: int = 26;
+export def EFBIG: int = 27;
+export def ENOSPC: int = 28;
+export def ESPIPE: int = 29;
+export def EROFS: int = 30;
+export def EMLINK: int = 31;
+export def EPIPE: int = 32;
+export def EDOM: int = 33;
+export def ERANGE: int = 34;
+export def EAGAIN: int = 35;
+export def EWOULDBLOCK: int = EAGAIN;
+export def EINPROGRESS: int = 36;
+export def EALREADY: int = 37;
+export def ENOTSOCK: int = 38;
+export def EDESTADDRREQ: int = 39;
+export def EMSGSIZE: int = 40;
+export def EPROTOTYPE: int = 41;
+export def ENOPROTOOPT: int = 42;
+export def EPROTONOSUPPORT: int = 43;
+export def ESOCKTNOSUPPORT: int = 44;
+export def EOPNOTSUPP: int = 45;
+export def ENOTSUP: int = EOPNOTSUPP;
+export def EPFNOSUPPORT: int = 46;
+export def EAFNOSUPPORT: int = 47;
+export def EADDRINUSE: int = 48;
+export def EADDRNOTAVAIL: int = 49;
+export def ENETDOWN: int = 50;
+export def ENETUNREACH: int = 51;
+export def ENETRESET: int = 52;
+export def ECONNABORTED: int = 53;
+export def ECONNRESET: int = 54;
+export def ENOBUFS: int = 55;
+export def EISCONN: int = 56;
+export def ENOTCONN: int = 57;
+export def ESHUTDOWN: int = 58;
+export def ETOOMANYREFS: int = 59;
+export def ETIMEDOUT: int = 60;
+export def ECONNREFUSED: int = 61;
+export def ELOOP: int = 62;
+export def ENAMETOOLONG: int = 63;
+export def EHOSTDOWN: int = 64;
+export def EHOSTUNREACH: int = 65;
+export def ENOTEMPTY: int = 66;
+export def EPROCLIM: int = 67;
+export def EUSERS: int = 68;
+export def EDQUOT: int = 69;
+export def ESTALE: int = 70;
+export def EREMOTE: int = 71;
+export def EBADRPC: int = 72;
+export def ERPCMISMATCH: int = 73;
+export def EPROGUNAVAIL: int = 74;
+export def EPROGMISMATCH: int = 75;
+export def EPROCUNAVAIL: int = 76;
+export def ENOLCK: int = 77;
+export def ENOSYS: int = 78;
+export def EFTYPE: int = 79;
+export def EAUTH: int = 80;
+export def ENEEDAUTH: int = 81;
+export def EIDRM: int = 82;
+export def ENOMSG: int = 83;
+export def EOVERFLOW: int = 84;
+export def ECANCELED: int = 85;
+export def EILSEQ: int = 86;
+export def ENOATTR: int = 87;
+export def EDOOFUS: int = 88;
+export def EBADMSG: int = 89;
+export def EMULTIHOP: int = 90;
+export def ENOLINK: int = 91;
+export def EPROTO: int = 92;
+export def ENOTCAPABLE: int = 93;
+export def ECAPMODE: int = 94;
+export def ENOTRECOVERABLE: int = 95;
+export def EOWNERDEAD: int = 96;
+export def EINTEGRITY: int = 97;
diff --git a/rt/+freebsd/segmalloc.ha b/rt/+freebsd/segmalloc.ha
@@ -0,0 +1,10 @@
+// Allocates a segment.
+fn segmalloc(n: size) nullable *void = {
+ let p: *void = mmap(null, n,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ return if (p: uintptr: int == -ENOMEM) null else p;
+};
+
+// Frees a segment allocated with segmalloc.
+fn segfree(p: *void, s: size) int = munmap(p, s);
diff --git a/rt/+freebsd/start+aarch64.s b/rt/+freebsd/start+aarch64.s
@@ -0,0 +1,8 @@
+.text
+.global _start
+_start:
+ mov x29, #0
+ mov x30, #0
+ mov x0, sp
+ add sp, x0, #-16
+ b rt.start_ha
diff --git a/rt/+freebsd/start+riscv64.s b/rt/+freebsd/start+riscv64.s
@@ -0,0 +1,6 @@
+.text
+.global _start
+_start:
+ mv a0, sp
+ andi sp, sp, -16
+ tail rt.start_ha
diff --git a/rt/+freebsd/start+x86_64.s b/rt/+freebsd/start+x86_64.s
@@ -0,0 +1,6 @@
+.text
+.global _start
+_start:
+ xor %rbp, %rbp
+ movq %rsp, %rdi
+ call rt.start_ha
diff --git a/rt/+freebsd/syscall+aarch64.s b/rt/+freebsd/syscall+aarch64.s
@@ -0,0 +1,69 @@
+.section .text.rt.syscall0
+.global rt.syscall0
+rt.syscall0:
+ mov x8, x0
+ svc 0
+ ret
+
+.section .text.rt.syscall1
+.global rt.syscall1
+rt.syscall1:
+ mov x8, x0
+ mov x0, x1
+ svc 0
+ ret
+
+.section .text.rt.syscall2
+.global rt.syscall2
+rt.syscall2:
+ mov x8, x0
+ mov x0, x1
+ mov x1, x2
+ svc 0
+ ret
+
+.section .text.rt.syscall3
+.global rt.syscall3
+rt.syscall3:
+ mov x8, x0
+ mov x0, x1
+ mov x1, x2
+ mov x2, x3
+ svc 0
+ ret
+
+.section .text.rt.syscall4
+.global rt.syscall4
+rt.syscall4:
+ mov x8, x0
+ mov x0, x1
+ mov x1, x2
+ mov x2, x3
+ mov x3, x4
+ svc 0
+ ret
+
+.section .text.rt.syscall5
+.global rt.syscall5
+rt.syscall5:
+ mov x8, x0
+ mov x0, x1
+ mov x1, x2
+ mov x2, x3
+ mov x3, x4
+ mov x4, x5
+ svc 0
+ ret
+
+.section .text.rt.syscall6
+.global rt.syscall6
+rt.syscall6:
+ mov x8, x0
+ mov x0, x1
+ mov x1, x2
+ mov x2, x3
+ mov x3, x4
+ mov x4, x5
+ mov x5, x6
+ svc 0
+ ret
diff --git a/rt/+freebsd/syscall+riscv64.s b/rt/+freebsd/syscall+riscv64.s
@@ -0,0 +1,146 @@
+.section .text.rt.syscall0
+.global rt.syscall0
+rt.syscall0:
+ addi sp, sp, -32
+ sd s0, 24(sp)
+ addi s0, sp, 32
+ sd a0, -24(s0)
+ ld a7, -24(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 24(sp)
+ addi sp, sp, 32
+ jr ra
+
+.section .text.rt.syscall1
+.global rt.syscall1
+rt.syscall1:
+ addi sp, sp, -32
+ sd s0, 24(sp)
+ addi s0, sp, 32
+ sd a0, -24(s0)
+ sd a1, -32(s0)
+ ld a7, -24(s0)
+ ld a0, -32(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 24(sp)
+ addi sp, sp, 32
+ jr ra
+
+.section .text.rt.syscall2
+.global rt.syscall2
+rt.syscall2:
+ addi sp, sp, -48
+ sd s0, 40(sp)
+ addi s0, sp, 48
+ sd a0, -24(s0)
+ sd a1, -32(s0)
+ sd a2, -40(s0)
+ ld a7, -24(s0)
+ ld a0, -32(s0)
+ ld a1, -40(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 40(sp)
+ addi sp, sp, 48
+ jr ra
+
+.section .text.rt.syscall3
+.global rt.syscall3
+rt.syscall3:
+ addi sp, sp, -48
+ sd s0, 40(sp)
+ addi s0, sp, 48
+ sd a0, -24(s0)
+ sd a1, -32(s0)
+ sd a2, -40(s0)
+ sd a3, -48(s0)
+ ld a7, -24(s0)
+ ld a0, -32(s0)
+ ld a1, -40(s0)
+ ld a2, -48(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 40(sp)
+ addi sp, sp, 48
+ jr ra
+
+.section .text.rt.syscall4
+.global rt.syscall4
+rt.syscall4:
+ addi sp, sp, -64
+ sd s0, 56(sp)
+ addi s0, sp, 64
+ sd a0, -24(s0)
+ sd a1, -32(s0)
+ sd a2, -40(s0)
+ sd a3, -48(s0)
+ sd a4, -56(s0)
+ ld a7, -24(s0)
+ ld a0, -32(s0)
+ ld a1, -40(s0)
+ ld a2, -48(s0)
+ ld a3, -56(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 56(sp)
+ addi sp, sp, 64
+ jr ra
+
+.section .text.rt.syscall5
+.global rt.syscall5
+rt.syscall5:
+ addi sp, sp, -64
+ sd s0, 56(sp)
+ addi s0, sp, 64
+ sd a0, -24(s0)
+ sd a1, -32(s0)
+ sd a2, -40(s0)
+ sd a3, -48(s0)
+ sd a4, -56(s0)
+ sd a5, -64(s0)
+ ld a7, -24(s0)
+ ld a0, -32(s0)
+ ld a1, -40(s0)
+ ld a2, -48(s0)
+ ld a3, -56(s0)
+ ld a4, -64(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 56(sp)
+ addi sp, sp, 64
+ jr ra
+
+.section .text.rt.syscall6
+.global rt.syscall6
+rt.syscall6:
+ addi sp, sp, -80
+ sd s0, 72(sp)
+ addi s0, sp, 80
+ sd a0, -24(s0)
+ sd a1, -32(s0)
+ sd a2, -40(s0)
+ sd a3, -48(s0)
+ sd a4, -56(s0)
+ sd a5, -64(s0)
+ sd a6, -72(s0)
+ ld a7, -24(s0)
+ ld a0, -32(s0)
+ ld a1, -40(s0)
+ ld a2, -48(s0)
+ ld a3, -56(s0)
+ ld a4, -64(s0)
+ ld a5, -72(s0)
+ ecall
+ mv a5, a0
+ mv a0, a5
+ ld s0, 72(sp)
+ addi sp, sp, 80
+ jr ra
diff --git a/rt/+freebsd/syscall+x86_64.s b/rt/+freebsd/syscall+x86_64.s
@@ -0,0 +1,69 @@
+.section .text.rt.syscall0
+.global rt.syscall0
+rt.syscall0:
+ movq %rdi, %rax
+ syscall
+ ret
+
+.section .text.rt.syscall1
+.global rt.syscall1
+rt.syscall1:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ syscall
+ ret
+
+.section .text.rt.syscall2
+.global rt.syscall2
+rt.syscall2:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ movq %rdx, %rsi
+ syscall
+ ret
+
+.section .text.rt.syscall3
+.global rt.syscall3
+rt.syscall3:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ syscall
+ ret
+
+.section .text.rt.syscall4
+.global rt.syscall4
+rt.syscall4:
+ movq %rdi, %rax
+ movq %r8, %r10
+ movq %rsi, %rdi
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ syscall
+ ret
+
+.section .text.rt.syscall5
+.global rt.syscall5
+rt.syscall5:
+ movq %rdi, %rax
+ movq %r8, %r10
+ movq %rsi, %rdi
+ movq %r9, %r8
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ syscall
+ ret
+
+.section .text.rt.syscall6
+.global rt.syscall6
+rt.syscall6:
+ movq %rdi, %rax
+ movq %r8, %r10
+ movq %rsi, %rdi
+ movq %r9, %r8
+ movq %rdx, %rsi
+ movq 8(%rsp), %r9
+ movq %rcx, %rdx
+ syscall
+ ret
diff --git a/rt/+freebsd/syscallno.ha b/rt/+freebsd/syscallno.ha
@@ -0,0 +1,419 @@
+export def SYS_syscall: u64 = 0;
+export def SYS_exit: u64 = 1;
+export def SYS_fork: u64 = 2;
+export def SYS_read: u64 = 3;
+export def SYS_write: u64 = 4;
+export def SYS_open: u64 = 5;
+export def SYS_close: u64 = 6;
+export def SYS_wait4: u64 = 7;
+export def SYS_link: u64 = 9;
+export def SYS_unlink: u64 = 10;
+export def SYS_chdir: u64 = 12;
+export def SYS_fchdir: u64 = 13;
+export def SYS_freebsd11_mknod: u64 = 14;
+export def SYS_chmod: u64 = 15;
+export def SYS_chown: u64 = 16;
+export def SYS_break: u64 = 17;
+export def SYS_getpid: u64 = 20;
+export def SYS_mount: u64 = 21;
+export def SYS_unmount: u64 = 22;
+export def SYS_setuid: u64 = 23;
+export def SYS_getuid: u64 = 24;
+export def SYS_geteuid: u64 = 25;
+export def SYS_ptrace: u64 = 26;
+export def SYS_recvmsg: u64 = 27;
+export def SYS_sendmsg: u64 = 28;
+export def SYS_recvfrom: u64 = 29;
+export def SYS_accept: u64 = 30;
+export def SYS_getpeername: u64 = 31;
+export def SYS_getsockname: u64 = 32;
+export def SYS_access: u64 = 33;
+export def SYS_chflags: u64 = 34;
+export def SYS_fchflags: u64 = 35;
+export def SYS_sync: u64 = 36;
+export def SYS_kill: u64 = 37;
+export def SYS_getppid: u64 = 39;
+export def SYS_dup: u64 = 41;
+export def SYS_freebsd10_pipe: u64 = 42;
+export def SYS_getegid: u64 = 43;
+export def SYS_profil: u64 = 44;
+export def SYS_ktrace: u64 = 45;
+export def SYS_getgid: u64 = 47;
+export def SYS_getlogin: u64 = 49;
+export def SYS_setlogin: u64 = 50;
+export def SYS_acct: u64 = 51;
+export def SYS_sigaltstack: u64 = 53;
+export def SYS_ioctl: u64 = 54;
+export def SYS_reboot: u64 = 55;
+export def SYS_revoke: u64 = 56;
+export def SYS_symlink: u64 = 57;
+export def SYS_readlink: u64 = 58;
+export def SYS_execve: u64 = 59;
+export def SYS_umask: u64 = 60;
+export def SYS_chroot: u64 = 61;
+export def SYS_msync: u64 = 65;
+export def SYS_vfork: u64 = 66;
+export def SYS_sbrk: u64 = 69;
+export def SYS_sstk: u64 = 70;
+export def SYS_freebsd11_vadvise: u64 = 72;
+export def SYS_munmap: u64 = 73;
+export def SYS_mprotect: u64 = 74;
+export def SYS_madvise: u64 = 75;
+export def SYS_mincore: u64 = 78;
+export def SYS_getgroups: u64 = 79;
+export def SYS_setgroups: u64 = 80;
+export def SYS_getpgrp: u64 = 81;
+export def SYS_setpgid: u64 = 82;
+export def SYS_setitimer: u64 = 83;
+export def SYS_swapon: u64 = 85;
+export def SYS_getitimer: u64 = 86;
+export def SYS_getdtablesize: u64 = 89;
+export def SYS_dup2: u64 = 90;
+export def SYS_fcntl: u64 = 92;
+export def SYS_select: u64 = 93;
+export def SYS_fsync: u64 = 95;
+export def SYS_setpriority: u64 = 96;
+export def SYS_socket: u64 = 97;
+export def SYS_connect: u64 = 98;
+export def SYS_getpriority: u64 = 100;
+export def SYS_bind: u64 = 104;
+export def SYS_setsockopt: u64 = 105;
+export def SYS_listen: u64 = 106;
+export def SYS_gettimeofday: u64 = 116;
+export def SYS_getrusage: u64 = 117;
+export def SYS_getsockopt: u64 = 118;
+export def SYS_readv: u64 = 120;
+export def SYS_writev: u64 = 121;
+export def SYS_settimeofday: u64 = 122;
+export def SYS_fchown: u64 = 123;
+export def SYS_fchmod: u64 = 124;
+export def SYS_setreuid: u64 = 126;
+export def SYS_setregid: u64 = 127;
+export def SYS_rename: u64 = 128;
+export def SYS_flock: u64 = 131;
+export def SYS_mkfifo: u64 = 132;
+export def SYS_sendto: u64 = 133;
+export def SYS_shutdown: u64 = 134;
+export def SYS_socketpair: u64 = 135;
+export def SYS_mkdir: u64 = 136;
+export def SYS_rmdir: u64 = 137;
+export def SYS_utimes: u64 = 138;
+export def SYS_adjtime: u64 = 140;
+export def SYS_setsid: u64 = 147;
+export def SYS_quotactl: u64 = 148;
+export def SYS_nlm_syscall: u64 = 154;
+export def SYS_nfssvc: u64 = 155;
+export def SYS_lgetfh: u64 = 160;
+export def SYS_getfh: u64 = 161;
+export def SYS_sysarch: u64 = 165;
+export def SYS_rtprio: u64 = 166;
+export def SYS_semsys: u64 = 169;
+export def SYS_msgsys: u64 = 170;
+export def SYS_shmsys: u64 = 171;
+export def SYS_setfib: u64 = 175;
+export def SYS_ntp_adjtime: u64 = 176;
+export def SYS_setgid: u64 = 181;
+export def SYS_setegid: u64 = 182;
+export def SYS_seteuid: u64 = 183;
+export def SYS_freebsd11_stat: u64 = 188;
+export def SYS_freebsd11_fstat: u64 = 189;
+export def SYS_freebsd11_lstat: u64 = 190;
+export def SYS_pathconf: u64 = 191;
+export def SYS_fpathconf: u64 = 192;
+export def SYS_getrlimit: u64 = 194;
+export def SYS_setrlimit: u64 = 195;
+export def SYS_freebsd11_getdirentries: u64 = 196;
+export def SYS___syscall: u64 = 198;
+export def SYS___sysctl: u64 = 202;
+export def SYS_mlock: u64 = 203;
+export def SYS_munlock: u64 = 204;
+export def SYS_undelete: u64 = 205;
+export def SYS_futimes: u64 = 206;
+export def SYS_getpgid: u64 = 207;
+export def SYS_poll: u64 = 209;
+export def SYS_freebsd7___semctl: u64 = 220;
+export def SYS_semget: u64 = 221;
+export def SYS_semop: u64 = 222;
+export def SYS_freebsd7_msgctl: u64 = 224;
+export def SYS_msgget: u64 = 225;
+export def SYS_msgsnd: u64 = 226;
+export def SYS_msgrcv: u64 = 227;
+export def SYS_shmat: u64 = 228;
+export def SYS_freebsd7_shmctl: u64 = 229;
+export def SYS_shmdt: u64 = 230;
+export def SYS_shmget: u64 = 231;
+export def SYS_clock_gettime: u64 = 232;
+export def SYS_clock_settime: u64 = 233;
+export def SYS_clock_getres: u64 = 234;
+export def SYS_ktimer_create: u64 = 235;
+export def SYS_ktimer_delete: u64 = 236;
+export def SYS_ktimer_settime: u64 = 237;
+export def SYS_ktimer_gettime: u64 = 238;
+export def SYS_ktimer_getoverrun: u64 = 239;
+export def SYS_nanosleep: u64 = 240;
+export def SYS_ffclock_getcounter: u64 = 241;
+export def SYS_ffclock_setestimate: u64 = 242;
+export def SYS_ffclock_getestimate: u64 = 243;
+export def SYS_clock_nanosleep: u64 = 244;
+export def SYS_clock_getcpuclockid2: u64 = 247;
+export def SYS_ntp_gettime: u64 = 248;
+export def SYS_minherit: u64 = 250;
+export def SYS_rfork: u64 = 251;
+export def SYS_issetugid: u64 = 253;
+export def SYS_lchown: u64 = 254;
+export def SYS_aio_read: u64 = 255;
+export def SYS_aio_write: u64 = 256;
+export def SYS_lio_listio: u64 = 257;
+export def SYS_freebsd11_getdents: u64 = 272;
+export def SYS_lchmod: u64 = 274;
+export def SYS_lutimes: u64 = 276;
+export def SYS_freebsd11_nstat: u64 = 278;
+export def SYS_freebsd11_nfstat: u64 = 279;
+export def SYS_freebsd11_nlstat: u64 = 280;
+export def SYS_preadv: u64 = 289;
+export def SYS_pwritev: u64 = 290;
+export def SYS_fhopen: u64 = 298;
+export def SYS_freebsd11_fhstat: u64 = 299;
+export def SYS_modnext: u64 = 300;
+export def SYS_modstat: u64 = 301;
+export def SYS_modfnext: u64 = 302;
+export def SYS_modfind: u64 = 303;
+export def SYS_kldload: u64 = 304;
+export def SYS_kldunload: u64 = 305;
+export def SYS_kldfind: u64 = 306;
+export def SYS_kldnext: u64 = 307;
+export def SYS_kldstat: u64 = 308;
+export def SYS_kldfirstmod: u64 = 309;
+export def SYS_getsid: u64 = 310;
+export def SYS_setresuid: u64 = 311;
+export def SYS_setresgid: u64 = 312;
+export def SYS_aio_return: u64 = 314;
+export def SYS_aio_suspend: u64 = 315;
+export def SYS_aio_cancel: u64 = 316;
+export def SYS_aio_error: u64 = 317;
+export def SYS_yield: u64 = 321;
+export def SYS_mlockall: u64 = 324;
+export def SYS_munlockall: u64 = 325;
+export def SYS___getcwd: u64 = 326;
+export def SYS_sched_setparam: u64 = 327;
+export def SYS_sched_getparam: u64 = 328;
+export def SYS_sched_setscheduler: u64 = 329;
+export def SYS_sched_getscheduler: u64 = 330;
+export def SYS_sched_yield: u64 = 331;
+export def SYS_sched_get_priority_max: u64 = 332;
+export def SYS_sched_get_priority_min: u64 = 333;
+export def SYS_sched_rr_get_u64erval: u64 = 334;
+export def SYS_utrace: u64 = 335;
+export def SYS_kldsym: u64 = 337;
+export def SYS_jail: u64 = 338;
+export def SYS_nnpfs_syscall: u64 = 339;
+export def SYS_sigprocmask: u64 = 340;
+export def SYS_sigsuspend: u64 = 341;
+export def SYS_sigpending: u64 = 343;
+export def SYS_sigtimedwait: u64 = 345;
+export def SYS_sigwaitinfo: u64 = 346;
+export def SYS___acl_get_file: u64 = 347;
+export def SYS___acl_set_file: u64 = 348;
+export def SYS___acl_get_fd: u64 = 349;
+export def SYS___acl_set_fd: u64 = 350;
+export def SYS___acl_delete_file: u64 = 351;
+export def SYS___acl_delete_fd: u64 = 352;
+export def SYS___acl_aclcheck_file: u64 = 353;
+export def SYS___acl_aclcheck_fd: u64 = 354;
+export def SYS_extattrctl: u64 = 355;
+export def SYS_extattr_set_file: u64 = 356;
+export def SYS_extattr_get_file: u64 = 357;
+export def SYS_extattr_delete_file: u64 = 358;
+export def SYS_aio_waitcomplete: u64 = 359;
+export def SYS_getresuid: u64 = 360;
+export def SYS_getresgid: u64 = 361;
+export def SYS_kqueue: u64 = 362;
+export def SYS_freebsd11_kevent: u64 = 363;
+export def SYS_extattr_set_fd: u64 = 371;
+export def SYS_extattr_get_fd: u64 = 372;
+export def SYS_extattr_delete_fd: u64 = 373;
+export def SYS___setugid: u64 = 374;
+export def SYS_eaccess: u64 = 376;
+export def SYS_afs3_syscall: u64 = 377;
+export def SYS_nmount: u64 = 378;
+export def SYS___mac_get_proc: u64 = 384;
+export def SYS___mac_set_proc: u64 = 385;
+export def SYS___mac_get_fd: u64 = 386;
+export def SYS___mac_get_file: u64 = 387;
+export def SYS___mac_set_fd: u64 = 388;
+export def SYS___mac_set_file: u64 = 389;
+export def SYS_kenv: u64 = 390;
+export def SYS_lchflags: u64 = 391;
+export def SYS_uuidgen: u64 = 392;
+export def SYS_sendfile: u64 = 393;
+export def SYS_mac_syscall: u64 = 394;
+export def SYS_freebsd11_getfsstat: u64 = 395;
+export def SYS_freebsd11_statfs: u64 = 396;
+export def SYS_freebsd11_fstatfs: u64 = 397;
+export def SYS_freebsd11_fhstatfs: u64 = 398;
+export def SYS_ksem_close: u64 = 400;
+export def SYS_ksem_post: u64 = 401;
+export def SYS_ksem_wait: u64 = 402;
+export def SYS_ksem_trywait: u64 = 403;
+export def SYS_ksem_init: u64 = 404;
+export def SYS_ksem_open: u64 = 405;
+export def SYS_ksem_unlink: u64 = 406;
+export def SYS_ksem_getvalue: u64 = 407;
+export def SYS_ksem_destroy: u64 = 408;
+export def SYS___mac_get_pid: u64 = 409;
+export def SYS___mac_get_link: u64 = 410;
+export def SYS___mac_set_link: u64 = 411;
+export def SYS_extattr_set_link: u64 = 412;
+export def SYS_extattr_get_link: u64 = 413;
+export def SYS_extattr_delete_link: u64 = 414;
+export def SYS___mac_execve: u64 = 415;
+export def SYS_sigaction: u64 = 416;
+export def SYS_sigreturn: u64 = 417;
+export def SYS_getcontext: u64 = 421;
+export def SYS_setcontext: u64 = 422;
+export def SYS_swapcontext: u64 = 423;
+export def SYS_swapoff: u64 = 424;
+export def SYS___acl_get_link: u64 = 425;
+export def SYS___acl_set_link: u64 = 426;
+export def SYS___acl_delete_link: u64 = 427;
+export def SYS___acl_aclcheck_link: u64 = 428;
+export def SYS_sigwait: u64 = 429;
+export def SYS_thr_create: u64 = 430;
+export def SYS_thr_exit: u64 = 431;
+export def SYS_thr_self: u64 = 432;
+export def SYS_thr_kill: u64 = 433;
+export def SYS_jail_attach: u64 = 436;
+export def SYS_extattr_list_fd: u64 = 437;
+export def SYS_extattr_list_file: u64 = 438;
+export def SYS_extattr_list_link: u64 = 439;
+export def SYS_ksem_timedwait: u64 = 441;
+export def SYS_thr_suspend: u64 = 442;
+export def SYS_thr_wake: u64 = 443;
+export def SYS_kldunloadf: u64 = 444;
+export def SYS_audit: u64 = 445;
+export def SYS_auditon: u64 = 446;
+export def SYS_getauid: u64 = 447;
+export def SYS_setauid: u64 = 448;
+export def SYS_getaudit: u64 = 449;
+export def SYS_setaudit: u64 = 450;
+export def SYS_getaudit_addr: u64 = 451;
+export def SYS_setaudit_addr: u64 = 452;
+export def SYS_auditctl: u64 = 453;
+export def SYS__umtx_op: u64 = 454;
+export def SYS_thr_new: u64 = 455;
+export def SYS_sigqueue: u64 = 456;
+export def SYS_kmq_open: u64 = 457;
+export def SYS_kmq_setattr: u64 = 458;
+export def SYS_kmq_timedreceive: u64 = 459;
+export def SYS_kmq_timedsend: u64 = 460;
+export def SYS_kmq_notify: u64 = 461;
+export def SYS_kmq_unlink: u64 = 462;
+export def SYS_abort2: u64 = 463;
+export def SYS_thr_set_name: u64 = 464;
+export def SYS_aio_fsync: u64 = 465;
+export def SYS_rtprio_thread: u64 = 466;
+export def SYS_sctp_peeloff: u64 = 471;
+export def SYS_sctp_generic_sendmsg: u64 = 472;
+export def SYS_sctp_generic_sendmsg_iov: u64 = 473;
+export def SYS_sctp_generic_recvmsg: u64 = 474;
+export def SYS_pread: u64 = 475;
+export def SYS_pwrite: u64 = 476;
+export def SYS_mmap: u64 = 477;
+export def SYS_lseek: u64 = 478;
+export def SYS_truncate: u64 = 479;
+export def SYS_ftruncate: u64 = 480;
+export def SYS_thr_kill2: u64 = 481;
+export def SYS_freebsd12_shm_open: u64 = 482;
+export def SYS_shm_unlink: u64 = 483;
+export def SYS_cpuset: u64 = 484;
+export def SYS_cpuset_setid: u64 = 485;
+export def SYS_cpuset_getid: u64 = 486;
+export def SYS_cpuset_getaffinity: u64 = 487;
+export def SYS_cpuset_setaffinity: u64 = 488;
+export def SYS_faccessat: u64 = 489;
+export def SYS_fchmodat: u64 = 490;
+export def SYS_fchownat: u64 = 491;
+export def SYS_fexecve: u64 = 492;
+export def SYS_freebsd11_fstatat: u64 = 493;
+export def SYS_futimesat: u64 = 494;
+export def SYS_linkat: u64 = 495;
+export def SYS_mkdirat: u64 = 496;
+export def SYS_mkfifoat: u64 = 497;
+export def SYS_freebsd11_mknodat: u64 = 498;
+export def SYS_openat: u64 = 499;
+export def SYS_readlinkat: u64 = 500;
+export def SYS_renameat: u64 = 501;
+export def SYS_symlinkat: u64 = 502;
+export def SYS_unlinkat: u64 = 503;
+export def SYS_posix_openpt: u64 = 504;
+export def SYS_gssd_syscall: u64 = 505;
+export def SYS_jail_get: u64 = 506;
+export def SYS_jail_set: u64 = 507;
+export def SYS_jail_remove: u64 = 508;
+export def SYS_freebsd12_closefrom: u64 = 509;
+export def SYS___semctl: u64 = 510;
+export def SYS_msgctl: u64 = 511;
+export def SYS_shmctl: u64 = 512;
+export def SYS_lpathconf: u64 = 513;
+export def SYS___cap_rights_get: u64 = 515;
+export def SYS_cap_enter: u64 = 516;
+export def SYS_cap_getmode: u64 = 517;
+export def SYS_pdfork: u64 = 518;
+export def SYS_pdkill: u64 = 519;
+export def SYS_pdgetpid: u64 = 520;
+export def SYS_pselect: u64 = 522;
+export def SYS_getloginclass: u64 = 523;
+export def SYS_setloginclass: u64 = 524;
+export def SYS_rctl_get_racct: u64 = 525;
+export def SYS_rctl_get_rules: u64 = 526;
+export def SYS_rctl_get_limits: u64 = 527;
+export def SYS_rctl_add_rule: u64 = 528;
+export def SYS_rctl_remove_rule: u64 = 529;
+export def SYS_posix_fallocate: u64 = 530;
+export def SYS_posix_fadvise: u64 = 531;
+export def SYS_wait6: u64 = 532;
+export def SYS_cap_rights_limit: u64 = 533;
+export def SYS_cap_ioctls_limit: u64 = 534;
+export def SYS_cap_ioctls_get: u64 = 535;
+export def SYS_cap_fcntls_limit: u64 = 536;
+export def SYS_cap_fcntls_get: u64 = 537;
+export def SYS_bindat: u64 = 538;
+export def SYS_connectat: u64 = 539;
+export def SYS_chflagsat: u64 = 540;
+export def SYS_accept4: u64 = 541;
+export def SYS_pipe2: u64 = 542;
+export def SYS_aio_mlock: u64 = 543;
+export def SYS_procctl: u64 = 544;
+export def SYS_ppoll: u64 = 545;
+export def SYS_futimens: u64 = 546;
+export def SYS_utimensat: u64 = 547;
+export def SYS_fdatasync: u64 = 550;
+export def SYS_fstat: u64 = 551;
+export def SYS_fstatat: u64 = 552;
+export def SYS_fhstat: u64 = 553;
+export def SYS_getdirentries: u64 = 554;
+export def SYS_statfs: u64 = 555;
+export def SYS_fstatfs: u64 = 556;
+export def SYS_getfsstat: u64 = 557;
+export def SYS_fhstatfs: u64 = 558;
+export def SYS_mknodat: u64 = 559;
+export def SYS_kevent: u64 = 560;
+export def SYS_cpuset_getdomain: u64 = 561;
+export def SYS_cpuset_setdomain: u64 = 562;
+export def SYS_getrandom: u64 = 563;
+export def SYS_getfhat: u64 = 564;
+export def SYS_fhlink: u64 = 565;
+export def SYS_fhlinkat: u64 = 566;
+export def SYS_fhreadlink: u64 = 567;
+export def SYS_funlinkat: u64 = 568;
+export def SYS_copy_file_range: u64 = 569;
+export def SYS___sysctlbyname: u64 = 570;
+export def SYS_shm_open2: u64 = 571;
+export def SYS_shm_rename: u64 = 572;
+export def SYS_sigfastblock: u64 = 573;
+export def SYS___realpathat: u64 = 574;
+export def SYS_close_range: u64 = 575;
+export def SYS_rpctls_syscall: u64 = 576;
+export def SYS___specialfd: u64 = 577;
+export def SYS_aio_writev: u64 = 578;
+export def SYS_aio_readv: u64 = 579;
diff --git a/rt/+freebsd/syscalls.ha b/rt/+freebsd/syscalls.ha
@@ -0,0 +1,84 @@
+fn syscall0(_: u64) u64;
+fn syscall1(_: u64, _: u64) u64;
+fn syscall2(_: u64, _: u64, _: u64) u64;
+fn syscall3(_: u64, _: u64, _: u64, _: u64) u64;
+fn syscall4(_: u64, _: u64, _: u64, _: u64, _: u64) u64;
+fn syscall5(_: u64, _: u64, _: u64, _: u64, _: u64, _: u64) u64;
+fn syscall6(_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64) u64;
+
+export fn write(fd: int, buf: *const void, count: size) size =
+ syscall3(SYS_write, fd: u64, buf: uintptr: u64, count: u64): size;
+
+export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int;
+
+export fn dup2(old: int, new: int) int =
+ syscall2(SYS_dup2, old: u64, new: u64): int;
+
+export fn getpid() int = syscall0(SYS_getpid): int;
+
+export @noreturn fn exit(status: int) void = syscall1(SYS_exit, status: u64);
+
+export fn fork() int = syscall0(SYS_fork): int;
+
+export fn execve(
+ path: *const char,
+ argv: *[*]nullable *const char,
+ envp: *[*]nullable *const char,
+) int = syscall3(SYS_execve,
+ path: uintptr: u64,
+ argv: uintptr: u64,
+ envp: uintptr: u64): int;
+
+export fn wait4(pid: int, status: *int, options: int, rusage: nullable *void) void =
+ syscall4(SYS_wait4, pid: u64, status: uintptr: u64,
+ options: u64, rusage: uintptr: u64);
+
+export fn wifexited(status: int) bool = wtermsig(status) == 0;
+export fn wexitstatus(status: int) int = (status & 0xff00) >> 8;
+
+export fn wtermsig(status: int) int = status & 0x7f;
+export fn wifsignaled(status: int) bool =
+ wtermsig(status) != 0o177 && wtermsig(status) != 0 && status != 0x13;
+
+export fn kill(pid: int, signal: int) int =
+ syscall2(SYS_kill, pid: u64, signal: u64): int;
+
+export fn pipe2(pipefd: *[2]int, flags: int) int =
+ syscall2(SYS_pipe2, pipefd: uintptr: u64, flags: u64): int;
+
+export def MAP_SHARED: uint = 0x0001;
+export def MAP_PRIVATE: uint = 0x0002;
+export def MAP_FIXED: uint = 0x0010;
+export def MAP_HASSEMAPHORE: uint = 0x0200;
+export def MAP_STACK: uint = 0x0400;
+export def MAP_NOSYNC: uint = 0x0800;
+export def MAP_FILE: uint = 0x0000;
+export def MAP_ANON: uint = 0x1000;
+export def MAP_GUARD: uint = 0x00002000;
+export def MAP_EXCL: uint = 0x00004000;
+export def MAP_NOCORE: uint = 0x00020000;
+export def MAP_PREFAULT_READ: uint = 0x00040000;
+export def MAP_32BIT: uint = 0x00080000;
+
+def PROT_NONE: uint = 0x00;
+def PROT_READ: uint = 0x01;
+def PROT_WRITE: uint = 0x02;
+def PROT_EXEC: uint = 0x04;
+
+export fn mmap(
+ addr: nullable *void,
+ length: size,
+ prot: uint,
+ flags: uint,
+ fd: int,
+ offs: size
+) *void = {
+ return syscall6(SYS_mmap, addr: uintptr: u64, length: u64, prot: u64,
+ flags: u64, fd: u64, offs: u64): uintptr: *void;
+};
+
+export fn munmap(addr: *void, length: size) int =
+ syscall2(SYS_munmap, addr: uintptr: u64, length: u64): int;
+
+export def SIGABRT: int = 6;
+export def SIGCHLD: int = 20;
diff --git a/rt/+linux/segmalloc.ha b/rt/+linux/segmalloc.ha
@@ -8,9 +8,3 @@ fn segmalloc(n: size) nullable *void = {
// Frees a segment allocated with segmalloc.
fn segfree(p: *void, s: size) int = munmap(p, s);
-
-// Marks a segment as writable and drops the execute bit.
-fn segwrite(seg: *void, n: size) void = mprotect(seg, n, PROT_READ | PROT_WRITE);
-
-// Marks a segment as executable and drops the write bit.
-fn segexec(seg: *void, n: size) void = mprotect(seg, n, PROT_READ | PROT_EXEC);
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -14,6 +14,9 @@ export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int;
export fn dup3(old: int, new: int, flags: int) int =
syscall3(SYS_dup3, old: u64, new: u64, flags: u64): int;
+export fn dup2(old: int, new: int, flags: int) int =
+ syscall3(SYS_dup3, old: u64, new: u64, 0): int;
+
export fn getpid() int = syscall0(SYS_getpid): int;
export @noreturn fn exit(status: int) void = syscall1(SYS_exit, status: u64);
diff --git a/rt/compile.ha b/rt/compile.ha
@@ -7,7 +7,7 @@ export fn compile(src: const str) int = {
const child = fork();
if (child == 0) {
close(pipefd[1]);
- dup3(pipefd[0], 0, 0);
+ dup2(pipefd[0], 0);
close(1);
close(2);
diff --git a/rt/configure b/rt/configure
@@ -22,6 +22,34 @@ rt() {
rt: libhart.a rt/+linux/start+$arch.o
EOF
;;
+ FreeBSD)
+ case $arch in
+ amd64)
+ arch=x86_64
+ ;;
+ aarch64)
+ ;;
+ *)
+ printf "unsupported FreeBSD arch %s\n" "$(uname)" >&2
+ ;;
+ esac
+ rtstart=rt/+freebsd/start+$arch.o
+ cat <<-EOF
+ rtstart=rt/+freebsd/start+$arch.o
+
+ libhart_srcs=\
+ rt/+freebsd/errno.ha \
+ rt/+freebsd/segmalloc.ha \
+ rt/+freebsd/syscallno.ha \
+ rt/+freebsd/syscalls.ha \
+ rt/types_arch+$arch.ha
+
+ libhart_objs=\
+ rt/+freebsd/syscall+$arch.o
+
+ rt: libhart.a rt/+freebsd/start+$arch.o
+ EOF
+ ;;
*)
printf "rt not supported for %s\n" "$(uname)" >&2
exit 1
diff --git a/src/emit.c b/src/emit.c
@@ -99,10 +99,10 @@ emit_const(struct qbe_value *val, FILE *out)
fprintf(out, "%lu", val->lval);
break;
case Q_SINGLE:
- fprintf(out, "s_%.*g", FLT_DECIMAL_DIG, val->sval);
+ fprintf(out, "s_%.*g", DECIMAL_DIG, val->sval);
break;
case Q_DOUBLE:
- fprintf(out, "d_%.*g", DBL_DECIMAL_DIG, val->dval);
+ fprintf(out, "d_%.*g", DECIMAL_DIG, val->dval);
break;
case Q__VOID:
case Q__AGGREGATE: