summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2016-10-26 16:38:22 +0000
committerlaksen <laksen@3ad0048d-3df7-0310-abae-a5850022a9f2>2016-10-26 16:38:22 +0000
commit77910e8c960aed8ffcab7e07b90a1993796296ca (patch)
treef952641f84b3ee54ba681e2fe3e76d326ede75d4
parent3b8ccd7dc6cdb55e234e10fe50a26cdd6d6a099d (diff)
downloadfpc-77910e8c960aed8ffcab7e07b90a1993796296ca.tar.gz
Fix syscalls on RV64. Needed PC rel jump, and qword stack save.
Optimize RV64 entry code. Doesn't clear .bss and uses some shorter instructions forms. Add alignment requirement for linux target info. Add setjump implementation for targets with HW FPU. git-svn-id: http://svn.freepascal.org/svn/fpc/branches/laksen@34766 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--riscv/trunk/compiler/systems/i_linux.pas6
-rw-r--r--riscv/trunk/rtl/linux/Makefile.fpc7
-rw-r--r--riscv/trunk/rtl/linux/riscv64/prt0.as52
-rw-r--r--riscv/trunk/rtl/linux/riscv64/syscall.inc84
-rw-r--r--riscv/trunk/rtl/riscv64/setjump.inc74
-rw-r--r--riscv/trunk/rtl/riscv64/setjumph.inc14
6 files changed, 164 insertions, 73 deletions
diff --git a/riscv/trunk/compiler/systems/i_linux.pas b/riscv/trunk/compiler/systems/i_linux.pas
index 1a3917bde4..02c8d920f2 100644
--- a/riscv/trunk/compiler/systems/i_linux.pas
+++ b/riscv/trunk/compiler/systems/i_linux.pas
@@ -969,7 +969,7 @@ unit i_linux;
shortname : 'Linux';
flags : [tf_needs_symbol_size,tf_smartlink_sections,
tf_needs_symbol_type,tf_files_case_sensitive,
- tf_has_winlike_resources];
+ tf_requires_proper_alignment,tf_has_winlike_resources];
cpu : cpu_riscv32;
unit_env : 'LINUXUNITS';
extradefines : 'UNIX;HASUNIX';
@@ -1035,7 +1035,7 @@ unit i_linux;
shortname : 'Linux';
flags : [tf_needs_symbol_size,tf_smartlink_sections,
tf_needs_symbol_type,tf_files_case_sensitive,
- tf_has_winlike_resources];
+ tf_requires_proper_alignment,tf_has_winlike_resources];
cpu : cpu_riscv64;
unit_env : 'LINUXUNITS';
extradefines : 'UNIX;HASUNIX';
@@ -1081,7 +1081,7 @@ unit i_linux;
constalignmax : 16;
varalignmin : 4;
varalignmax : 16;
- localalignmin : 0;
+ localalignmin : 8;
localalignmax : 16;
recordalignmin : 0;
recordalignmax : 16;
diff --git a/riscv/trunk/rtl/linux/Makefile.fpc b/riscv/trunk/rtl/linux/Makefile.fpc
index 4a54e8364c..0602358250 100644
--- a/riscv/trunk/rtl/linux/Makefile.fpc
+++ b/riscv/trunk/rtl/linux/Makefile.fpc
@@ -176,6 +176,13 @@ ifeq ($(ARCH),arm)
endif
endif
+ifeq ($(ARCH),riscv32)
+ ASTARGET=-m32
+endif
+ifeq ($(ARCH),riscv64)
+ ASTARGET=-m64
+endif
+
#
# Loaders
diff --git a/riscv/trunk/rtl/linux/riscv64/prt0.as b/riscv/trunk/rtl/linux/riscv64/prt0.as
index 524ccc213c..d489b5dcad 100644
--- a/riscv/trunk/rtl/linux/riscv64/prt0.as
+++ b/riscv/trunk/rtl/linux/riscv64/prt0.as
@@ -11,9 +11,9 @@
.globl _dynamic_start
.type _dynamic_start, function
_dynamic_start:
- lui x5,%hi(__dl_fini)
- addi x5,x5,%lo(__dl_fini)
- sd x10, (x5)
+1:
+ auipc x5,%pcrel_hi(__dl_fini)
+ sd x10, %pcrel_lo(1b)(x5)
jal x0, _start
.globl _start
@@ -23,14 +23,6 @@ _start:
auipc gp, %pcrel_hi(__bss_start+0x800)
addi gp, gp, %pcrel_lo(1b)
-# clear the bss segment
- la t0, __bss_start
- la t1, _end
-2:
- sd zero,0(t0)
- addi t0, t0, 8
- bltu t0, t1, 2b
-
/* Get argc, argv, envp */
ld x5,(x2)
addi x6,x2,8
@@ -39,19 +31,15 @@ _start:
add x7,x6,x7
/* Save argc, argv, envp, and initial stack pointer */
- lui x8,%hi(operatingsystem_parameter_argc)
- addi x8,x8,%lo(operatingsystem_parameter_argc)
- sd x5,(x8)
- lui x8,%hi(operatingsystem_parameter_argv)
- addi x8,x8,%lo(operatingsystem_parameter_argv)
- sd x6,(x8)
- lui x8,%hi(operatingsystem_parameter_envp)
- addi x8,x8,%lo(operatingsystem_parameter_envp)
- sd x7,(x8)
- lui x5,%hi(__stkptr)
- addi x5,x8,%lo(__stkptr)
+1:auipc x8,%pcrel_hi(operatingsystem_parameter_argc)
+ sd x5,%pcrel_lo(1b)(x8)
+1:auipc x8,%pcrel_hi(operatingsystem_parameter_argv)
+ sd x6,%pcrel_lo(1b)(x8)
+1:auipc x8,%pcrel_hi(operatingsystem_parameter_envp)
+ sd x7,%pcrel_lo(1b)(x8)
+1:auipc x5,%pcrel_hi(__stkptr)
addi x6, x2, 0
- sd x6,(x5)
+ sd x6,%pcrel_lo(1b)(x5)
/* Initialise FP to zero */
addi x8,x0,0
@@ -62,30 +50,28 @@ _start:
.globl _haltproc
.type _haltproc,function
_haltproc:
- lui x10,%hi(__dl_fini)
- addi x10,x10,%lo(__dl_fini)
- ld x10,(x10)
+1:auipc x10,%pcrel_hi(__dl_fini)
+ ld x10,%pcrel_lo(1b)(x10)
beq x10,x0,.Lexit
jalr x1,x10
.Lexit:
- lui x10,%hi(operatingsystem_result)
- addi x10,x10,%lo(operatingsystem_result)
- ld x10,(x10)
+1:auipc x10,%pcrel_hi(operatingsystem_result)
+ ld x10,%pcrel_lo(1b)(x10)
addi x17, x0, 94
- scall
+ ecall
jal x0, _haltproc
/* Define a symbol for the first piece of initialized data. */
.data
- .align 3
+ .align 4
.globl __data_start
__data_start:
- .long 0
+ .quad 0
.weak data_start
data_start = __data_start
.bss
- .align 3
+ .align 4
.comm __dl_fini,8
.comm __stkptr,8
diff --git a/riscv/trunk/rtl/linux/riscv64/syscall.inc b/riscv/trunk/rtl/linux/riscv64/syscall.inc
index 146250e826..6abf3ac807 100644
--- a/riscv/trunk/rtl/linux/riscv64/syscall.inc
+++ b/riscv/trunk/rtl/linux/riscv64/syscall.inc
@@ -13,12 +13,14 @@ asm
addi x17, sysnr, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
@@ -30,12 +32,14 @@ asm
addi x10, x11, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
@@ -48,12 +52,14 @@ asm
addi x11, x12, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
@@ -67,12 +73,14 @@ asm
addi x12, x13, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
@@ -87,12 +95,14 @@ asm
addi x13, x14, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
@@ -108,12 +118,14 @@ asm
addi x14, x15, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
@@ -130,12 +142,14 @@ asm
addi x15, x16, 0
ecall
bge x10,x0,.Ldone
- sw x1, -4(x2)
- addi x2, x2, -4
+ sd x1, -8(x2)
+ addi x2, x2, -8
sub x10, x0, x10
- jal x1, seterrno
- addi x2, x2, 4
- lw x1, -4(x2)
+.Ll1:
+ auipc x1, %pcrel_hi(seterrno)
+ jalr x1, x1, %pcrel_lo(.Ll1)
+ addi x2, x2, 8
+ ld x1, -8(x2)
addi x10,x0, -1
.Ldone:
end;
diff --git a/riscv/trunk/rtl/riscv64/setjump.inc b/riscv/trunk/rtl/riscv64/setjump.inc
index 2bdbe0a390..bb238b7aba 100644
--- a/riscv/trunk/rtl/riscv64/setjump.inc
+++ b/riscv/trunk/rtl/riscv64/setjump.inc
@@ -31,6 +31,43 @@ function fpc_setjmp(var S : jmp_buf) : longint;assembler;nostackframe;[Public, a
sd s11, 12*8(a0)
sd sp, 13*8(a0)
+{$if defined(FPUFD) or defined(FPUD)}
+ frcsr s0
+
+ sd s0, 14*8(a0)
+
+ fsd f8, 15*8(a0)
+ fsd f9, 16*8(a0)
+ fsd f18, 17*8(a0)
+ fsd f19, 18*8(a0)
+ fsd f20, 19*8(a0)
+ fsd f21, 20*8(a0)
+ fsd f22, 21*8(a0)
+ fsd f23, 22*8(a0)
+ fsd f24, 23*8(a0)
+ fsd f25, 24*8(a0)
+ fsd f26, 25*8(a0)
+ fsd f27, 26*8(a0)
+{$endif FPUFD or FPUD}
+{$if defined(FPUF)}
+ frcsr s0
+
+ sd s0, 14*8(a0)
+
+ fsw f8, 30*4(a0)
+ fsw f9, 31*4(a0)
+ fsw f18, 32*4(a0)
+ fsw f19, 33*4(a0)
+ fsw f20, 34*4(a0)
+ fsw f21, 35*4(a0)
+ fsw f22, 36*4(a0)
+ fsw f23, 37*4(a0)
+ fsw f24, 38*4(a0)
+ fsw f25, 39*4(a0)
+ fsw f26, 40*4(a0)
+ fsw f27, 41*4(a0)
+{$endif FPUF}
+
addi x10, x0, 0
end;
@@ -50,6 +87,43 @@ procedure fpc_longjmp(var S : jmp_buf;value : longint);assembler;nostackframe;[P
ld s9, 10*8(a0)
ld s10,11*8(a0)
ld s11,12*8(a0)
+
+{$if defined(FPUFD) or defined(FPUD)}
+ ld sp, 14*8(a0)
+
+ fld f8, 15*8(a0)
+ fld f9, 16*8(a0)
+ fld f18, 17*8(a0)
+ fld f19, 18*8(a0)
+ fld f20, 19*8(a0)
+ fld f21, 20*8(a0)
+ fld f22, 21*8(a0)
+ fld f23, 22*8(a0)
+ fld f24, 23*8(a0)
+ fld f25, 24*8(a0)
+ fld f26, 25*8(a0)
+ fld f27, 26*8(a0)
+
+ fscsr sp
+{$endif FPUFD or FPUD}
+{$if defined(FPUF)}
+ ld sp, 14*8(a0)
+
+ flw f8, 30*4(a0)
+ flw f9, 31*4(a0)
+ flw f18, 32*4(a0)
+ flw f19, 33*4(a0)
+ flw f20, 34*4(a0)
+ flw f21, 35*4(a0)
+ flw f22, 36*4(a0)
+ flw f23, 37*4(a0)
+ flw f24, 38*4(a0)
+ flw f25, 39*4(a0)
+ flw f26, 40*4(a0)
+ flw f27, 41*4(a0)
+
+ fscsr sp
+{$endif FPUF}
ld sp, 13*8(a0)
sltiu a0, a1, 1
diff --git a/riscv/trunk/rtl/riscv64/setjumph.inc b/riscv/trunk/rtl/riscv64/setjumph.inc
index 7fc080a2ec..fa0c4a14c6 100644
--- a/riscv/trunk/rtl/riscv64/setjumph.inc
+++ b/riscv/trunk/rtl/riscv64/setjumph.inc
@@ -18,8 +18,18 @@ type
jmp_buf = packed record
ra,
x8,x9,x18,x19,x20,x21,
- x22,x23,x24,x25,s26,
- s27,x2: qword;
+ x22,x23,x24,x25,x26,
+ x27,x2: qword;
+{$if defined(FPUFD) or defined(FPUD)}
+ fcsr,
+ f8,f9,f18,f19,f20,f21,
+ f22,f23,f24,f25,f26,f27: qword;
+{$endif FPUFD or FPUD}
+{$if defined(FPUF)}
+ fcsr: qword;
+ f8,f9,f18,f19,f20,f21,
+ f22,f23,f24,f25,f26,f27: longword;
+{$endif FPUF}
end;
pjmp_buf = ^jmp_buf;