The result of test,
$ cd gcl/
$ autoconf -i -f
$ ./configure
$ make
$ cd ansi-tests/
$ LISP=../unixport/saved_ansi_gcl make test
2 out of 21727 total tests failed: DECODE-UNIVERSAL-TIME.1,
DECODE-UNIVERSAL-TIME.2.
real time : 148.230 secs
run-gbc time : 58.380 secs
child run time : 80.520 secs
gbc time : 2.820 secs
allocation : 16046 Mbytes
NIL
---
gcl/configure.in | 4 ++
gcl/h/elf64_loongarch64_reloc.h | 93 +++++++++++++++++++++++++
gcl/h/elf64_loongarch64_reloc_special.h | 70 +++++++++++++++++++
gcl/h/loongarch64-linux.h | 27 +++++++
4 files changed, 194 insertions(+)
create mode 100644 gcl/h/elf64_loongarch64_reloc.h
create mode 100644 gcl/h/elf64_loongarch64_reloc_special.h
create mode 100644 gcl/h/loongarch64-linux.h
diff --git a/gcl/configure.in b/gcl/configure.in
index c983ef0c3..358e02889 100644
--- a/gcl/configure.in
+++ b/gcl/configure.in
@@ -47,6 +47,7 @@ case $canonical in
s390*linux*) use=s390-linux;;
ia64*linux*) use=ia64-linux;;
hppa*linux*) use=hppa-linux;;
+ loongarch64*linux*) use=loongarch64-linux;;
powerpc*linux*) use=powerpc-linux;;
powerpc-*-darwin*) use=powerpc-macosx;;
*86*darwin*) use=386-macosx;;
@@ -343,6 +344,9 @@ case $use in
if ! add_arg_to_cflags -msse2 || ! add_arg_to_cflags -mfpmath=sse ; then
add_arg_to_cflags -ffloat-store;
fi;;
+ loongarch64-linux)
+ add_arg_to_cflags -mno-relax
+ add_arg_to_cflags -Wa,-mno-relax;;
386-macosx)
# assert_arg_to_cflags -Wno-error=implicit-function-declaration
add_arg_to_cflags -Wno-incomplete-setjmp-declaration
diff --git a/gcl/h/elf64_loongarch64_reloc.h b/gcl/h/elf64_loongarch64_reloc.h
new file mode 100644
index 000000000..97260111a
--- /dev/null
+++ b/gcl/h/elf64_loongarch64_reloc.h
@@ -0,0 +1,93 @@
+#define get_insn_page(x) ((x) & ~0xffful)
+#define get_page_delta(dest, pc) ({ \
+ ul res = get_insn_page(dest) - get_insn_page(pc); \
+ if ((dest) & 0x800) \
+ res += 0x1000ul - 0x100000000ul; \
+ if (res & 0x80000000) \
+ res += 0x100000000ul; \
+ res; \
+})
+#define get_page_low(dest) ((dest) & 0xfff)
+#define bdest (((long)((s+a)-p))>>2)
+#define bgdest (((long)(((ul)got)-p))>>2)
+
+ case R_LARCH_RELAX:
+ case R_LARCH_ALIGN:
+ massert(!emsg("Unsupport relaxation, please compile with '-mno-relax
-Wa,-mno-relax'\n"));
+ break;
+ case R_LARCH_64:
+ store_val(where,~0L,(s+a));
+ break;
+ case R_LARCH_32:
+ store_val(where,MASK(32),(s+a));
+ break;
+ case R_LARCH_32_PCREL:
+ store_val(where,MASK(32),(s+a)-p);
+ break;
+ case R_LARCH_ADD6:
+ add_val(where,MASK(6),(s+a));
+ break;
+ case R_LARCH_ADD8:
+ add_val(where,MASK(8),(s+a));
+ break;
+ case R_LARCH_ADD16:
+ add_val(where,MASK(16),(s+a));
+ break;
+ case R_LARCH_ADD32:
+ add_val(where,MASK(32),(s+a));
+ break;
+ case R_LARCH_ADD64:
+ add_val(where,~0L,(s+a));
+ break;
+ case R_LARCH_SUB6:
+ add_val(where,MASK(6),-(s+a));
+ break;
+ case R_LARCH_SUB8:
+ add_val(where,MASK(8),-(s+a));
+ break;
+ case R_LARCH_SUB16:
+ add_val(where,MASK(16),-(s+a));
+ break;
+ case R_LARCH_SUB32:
+ add_val(where,MASK(32),-(s+a));
+ break;
+ case R_LARCH_SUB64:
+ add_val(where,~0L,-(s+a));
+ break;
+ case R_LARCH_B16:
+ store_val(where,MASK(16)<<10,bdest<<10);
+ break;
+ case R_LARCH_B21:
+ store_val(where,(MASK(16)<<10)|MASK(5),bdest<<10|((bdest>>16)&0x1f));
+ break;
+ case R_LARCH_B26:
+ {
+ if ((bdest&(~MASK(25)))==0||((~bdest)&(~MASK(25)))==0) {
+ store_val(where,MASK(26),bdest<<10|((bdest>>16)&0x3ff));
+ break;
+ }
+ if (!(sym->st_size&0x2))
+ massert(!emsg("Unresolved R_LARCH_B26 symbol\n"));
+ got+=(sym->st_size>>2)+(sym->st_size&0x1?1:0);
+ store_val(where,MASK(26),bgdest<<10|((bgdest>>16)&0x3ff));
+ memcpy(got,tramp,sizeof(tramp));
+
store_val(got,MASK(20)<<5,(get_insn_page(s+a)-get_insn_page((ul)got))>>12<<5);
+ store_val((ul*)((ul)got+4),MASK(16)<<10,(((s+a)>>2)&0x3ff)<<10);
+ }
+ break;
+ case R_LARCH_PCALA_HI20:
+ store_val(where,MASK(20)<<5,get_page_delta(s+a,p)>>12<<5);
+ break;
+ case R_LARCH_PCALA_LO12:
+ store_val(where,MASK(12)<<10,get_page_low(s+a)<<10);
+ break;
+ case R_LARCH_GOT_PC_HI20:
+ got+=sym->st_size>>2;
+ *got=s+a;
+ store_val(where,MASK(20)<<5,get_page_delta((ul)got,p)>>12<<5);
+ break;
+ case R_LARCH_GOT_PC_LO12:
+ got+=sym->st_size>>2;
+ // *got=s+a;
+ store_val(where,MASK(12)<<10,get_page_low((ul)got)<<10);
+ break;
diff --git a/gcl/h/elf64_loongarch64_reloc_special.h
b/gcl/h/elf64_loongarch64_reloc_special.h
new file mode 100644
index 000000000..50f4811e8
--- /dev/null
+++ b/gcl/h/elf64_loongarch64_reloc_special.h
@@ -0,0 +1,70 @@
+#define R_LARCH_B16 64
+#define R_LARCH_B21 65
+#define R_LARCH_B26 66
+#define R_LARCH_PCALA_HI20 71
+#define R_LARCH_PCALA_LO12 72
+#define R_LARCH_GOT_PC_HI20 75
+#define R_LARCH_GOT_PC_LO12 76
+#define R_LARCH_32_PCREL 99
+#define R_LARCH_RELAX 100
+#define R_LARCH_ALIGN 102
+#define R_LARCH_ADD6 105
+#define R_LARCH_SUB6 106
+
+static unsigned int tramp[] = {
+ 0x1a00000c, /* pcalau12i $t0, %hi(sym) */
+ 0x4c000180 /* jirl $zero, $t0, %lo(sym) */};
+
+static int
+find_special_params(void *v,Shdr *sec1,Shdr *sece,const char *sn,
+ const char *st1,Sym *ds1,Sym *dse,Sym *sym,Sym *syme) {
+ return 0;
+
+}
+
+static int
+label_got_symbols(void *v1,Shdr *sec1,Shdr *sece,Sym *sym1,Sym *syme,const
char *st1,const char *sn,ul *gs) {
+ Rela *r;
+ Sym *sym;
+ Shdr *sec;
+ void *v,*ve;
+ int idx;
+ const int gz = sizeof(ul)/sizeof(ul), tz = sizeof(tramp)/sizeof(ul);
+ massert(gz==1);
+ massert(tz==1);
+
+ for (sym=sym1;sym<syme;sym++)
+ sym->st_size=0;
+
+ /* Count the symbols need to be fixed first. */
+ for (sec=sec1;sec<sece;sec++)
+ if (sec->sh_type==SHT_RELA)
+ for
(v=v1+sec->sh_offset,ve=v+sec->sh_size,r=v;v<ve;v+=sec->sh_entsize,r=v)
+ if (
+ ELF_R_TYPE(r->r_info)==R_LARCH_GOT_PC_HI20 ||
+ ELF_R_TYPE(r->r_info)==R_LARCH_B26
+ ) {
+ sym=sym1+ELF_R_SYM(r->r_info);
+ if (ELF_R_TYPE(r->r_info)==R_LARCH_B26 && LOCAL_SYM(sym))
+ continue;
+
+ if (ELF_R_TYPE(r->r_info)==R_LARCH_GOT_PC_HI20)
+ sym->st_size|=0x1;
+ if (ELF_R_TYPE(r->r_info)==R_LARCH_B26)
+ sym->st_size|=0x2;
+ }
+
+ for (idx=0,sym=sym1;sym<syme;sym++) {
+ if (sym->st_size==0)
+ continue;
+ massert(!(sym->st_size>>2));
+ sym->st_size|=idx<<2;
+ if (sym->st_size&0x1)
+ idx+=gz;
+ if (sym->st_size&0x2)
+ idx+=tz;
+ }
+
+ *gs=idx;
+ return 0;
+}
diff --git a/gcl/h/loongarch64-linux.h b/gcl/h/loongarch64-linux.h
new file mode 100644
index 000000000..d50065ae1
--- /dev/null
+++ b/gcl/h/loongarch64-linux.h
@@ -0,0 +1,27 @@
+#include "linux.h"
+
+#ifdef IN_GBC
+#undef MPROTECT_ACTION_FLAGS
+#define MPROTECT_ACTION_FLAGS SA_RESTART|SA_SIGINFO
+#define GET_FAULT_ADDR(sig,code,sv,a) \
+ ((siginfo_t *)code)->si_addr
+#endif
+
+/*#define NULL_OR_ON_C_STACK(x) ((x)==0 || ((unsigned int)x) > (unsigned
int)(pagetochar(MAXPAGE+1)))*/
+
+/* #define ADDITIONAL_FEATURES \ */
+/* ADD_FEATURE("BSD386"); \ */
+/* ADD_FEATURE("MC68020") */
+
+
+/* #define I386 */
+#define SGC
+
+/* Apparently stack pointers can be 4 byte aligned, at least &argc -- CM */
+#define C_GC_OFFSET 4
+
+#define RELOC_H "elf64_loongarch64_reloc.h"
+#define SPECIAL_RELOC_H "elf64_loongarch64_reloc_special.h"
+/* #define MAX_CODE_ADDRESS (1L<<31)/\*large memory model broken gcc 4.8*\/ */
+
+#define NEED_STACK_CHK_GUARD