[PATCH v2 1/4] ARCv2 ISA support

Vineet Gupta <[email protected]>
Newsgroups gmane.comp.lib.uclibc.general
Message-ID <[email protected]>
This is next gen Instruction Set Architecture from Synopsys and basis
for the ARC HS family of processors.

http://www.synopsys.com/dw/ipdir.php?ds=arc-hs38-processor&elq_mid=5732&elq_cid=458802
http://www.synopsys.com/IP/ProcessorIP/ARCProcessors/arc-hs/Pages/default.aspx

Signed-off-by: Vineet Gupta <[email protected]>
---
 Rules.mak                                          |  1 +
 extra/Configs/Config.arc                           |  6 ++++
 extra/Configs/Config.in                            |  1 +
 extra/Configs/defconfigs/arc/arcv2_defconfig       | 33 ++++++++++++++++++++++
 include/elf.h                                      |  1 +
 ldso/ldso/arc/dl-sysdep.h                          | 15 ++++++++--
 ldso/ldso/arc/elfinterp.c                          |  4 +++
 libc/string/arc/memcmp.S                           | 29 +++++++++++++++++++
 libc/sysdeps/linux/arc/bits/syscalls.h             | 10 ++++++-
 libc/sysdeps/linux/arc/bits/uClibc_arch_features.h |  7 +++++
 10 files changed, 104 insertions(+), 3 deletions(-)
 create mode 100644 extra/Configs/defconfigs/arc/arcv2_defconfig

diff --git a/Rules.mak b/Rules.mak
index 9f5fe8564376..ea254f1a26c5 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -543,6 +543,7 @@ endif
 ifeq ($(TARGET_ARCH),arc)
 	CPU_CFLAGS-y += -mlock -mswape
 	CPU_CFLAGS-$(CONFIG_ARC_CPU_700) += -mA7
+	CPU_CFLAGS-$(CONFIG_ARC_CPU_HS) += -mcpu=archs
 	CPU_LDFLAGS-y += $(CPU_CFLAGS) -marclinux
 endif
 
diff --git a/extra/Configs/Config.arc b/extra/Configs/Config.arc
index dc32ba4fb2aa..0c0bc71ce2fc 100644
--- a/extra/Configs/Config.arc
+++ b/extra/Configs/Config.arc
@@ -20,6 +20,12 @@ config CONFIG_ARC_CPU_700
 	help
 	  ARCompact ISA based ARC CPU
 
+config CONFIG_ARC_CPU_HS
+	bool "ARC-HS"
+	select ARCH_HAS_MMU
+	help
+	  Next Generation ARCv2 ISA based Processors
+
 endchoice
 
 choice
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 8e603b2adfe0..84659650b5aa 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -255,6 +255,7 @@ config TARGET_SUBARCH
 	default "i486" if CONFIG_486
 	default "i586" if CONFIG_586
 	default "i686" if CONFIG_686
+	default "arcv2" if CONFIG_ARC_CPU_HS
 	default ""
 
 source "extra/Configs/Config.in.arch"
diff --git a/extra/Configs/defconfigs/arc/arcv2_defconfig b/extra/Configs/defconfigs/arc/arcv2_defconfig
new file mode 100644
index 000000000000..d3a7dc7b2399
--- /dev/null
+++ b/extra/Configs/defconfigs/arc/arcv2_defconfig
@@ -0,0 +1,33 @@
+CONFIG_ARC_CPU_HS=y
+ARCH_WANTS_LITTLE_ENDIAN=y
+# UCLIBC_HAS_FPU is not set
+DO_C99_MATH=y
+KERNEL_HEADERS="%KERNEL_HEADERS%"
+# DOPIC is not set
+# LDSO_CACHE_SUPPORT is not set
+LDSO_RUNPATH=y
+# LDSO_SAFE_RUNPATH is not set
+LINUXTHREADS_OLD=y
+PTHREADS_DEBUG_SUPPORT=y
+UCLIBC_HAS_OBSTACK=y
+UCLIBC_SUSV2_LEGACY=y
+UCLIBC_SUSV3_LEGACY=y
+UCLIBC_SUSV4_LEGACY=y
+UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y
+UCLIBC_HAS_OBSOLETE_BSD_SIGNAL=y
+UCLIBC_SV4_DEPRECATED=y
+UCLIBC_HAS_RPC=y
+UCLIBC_HAS_FULL_RPC=y
+UCLIBC_HAS_RESOLVER_SUPPORT=y
+UCLIBC_HAS_LIBRESOLV_STUB=y
+UCLIBC_HAS_LOCALE=y
+UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y
+UCLIBC_HAS_NFTW=y
+UCLIBC_HAS_FTW=y
+UCLIBC_HAS_GNU_GLOB=y
+RUNTIME_PREFIX="%RUNTIME_PREFIX%"
+DEVEL_PREFIX="%DEVEL_PREFIX%"
+CROSS_COMPILER_PREFIX="arc-linux-uclibc-"
+# DOSTRIP is not set
+SUPPORT_LD_DEBUG=y
+UCLIBC_HAS_BACKTRACE=y
diff --git a/include/elf.h b/include/elf.h
index 1979209cde83..facf09cd5ca3 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -378,6 +378,7 @@ typedef struct
 
 /* Xilinx Microblaze (official) */
 #define EM_MICROBLAZE   189
+#define EM_ARCV2	195		/* ARCv2 Cores */
 
 /* Legal values for e_version (version).  */
 
diff --git a/ldso/ldso/arc/dl-sysdep.h b/ldso/ldso/arc/dl-sysdep.h
index 08b3bade8b09..ca62a2c04f35 100644
--- a/ldso/ldso/arc/dl-sysdep.h
+++ b/ldso/ldso/arc/dl-sysdep.h
@@ -69,11 +69,16 @@ do {									\
 } while(0)
 
 /* Here we define the magic numbers that this dynamic loader should accept */
+#ifdef __A7__
 #define MAGIC1 EM_ARCOMPACT
+#define ELF_TARGET "ARCompact"	/* For error messages */
+#elif defined(__HS__)
+#define MAGIC1 EM_ARCV2
+#define ELF_TARGET "ARCv2"	/* For error messages */
+#endif
+
 #undef  MAGIC2
 
-/* Used for error messages */
-#define ELF_TARGET "ARC"
 
 struct elf_resolve;
 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt,
@@ -81,6 +86,8 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt,
 
 extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden;
 
+#ifdef __A7__
+/* using "C" causes an indirection via __umodsi3 -> __udivmodsi4 */
 #define do_rem(result, n, base)  ((result) =				\
 									\
 	__builtin_constant_p (base) ? (n) % (unsigned) (base) :		\
@@ -95,6 +102,10 @@ extern unsigned __udivmodsi4(unsigned, unsigned) attribute_hidden;
 		r1;							\
 	})								\
 )
+#elif defined(__HS__)
+/* ARCv2 has hardware assisted divide/mod */
+#define do_rem(result, n, base)  ((result) = (n) % (unsigned) (base))
+#endif
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
    TLS variable so PLT entries should not be allowed to define the value.
diff --git a/ldso/ldso/arc/elfinterp.c b/ldso/ldso/arc/elfinterp.c
index d26c947058a0..7c31d3ac78f1 100644
--- a/ldso/ldso/arc/elfinterp.c
+++ b/ldso/ldso/arc/elfinterp.c
@@ -11,7 +11,11 @@
  */
 #include "ldso.h"
 
+#ifdef __A7__
 #define ARC_PLT_SIZE	12
+#else
+#define ARC_PLT_SIZE	16
+#endif
 
 unsigned long
 _dl_linux_resolver(struct elf_resolve *tpnt, unsigned int plt_pc)
diff --git a/libc/string/arc/memcmp.S b/libc/string/arc/memcmp.S
index 4c0e39143470..a60757e7a254 100644
--- a/libc/string/arc/memcmp.S
+++ b/libc/string/arc/memcmp.S
@@ -24,14 +24,32 @@ ENTRY(memcmp)
 	ld	r4,[r0,0]
 	ld	r5,[r1,0]
 	lsr.f	lp_count,r3,3
+#ifdef __HS__
+	/* In ARCv2 a branch can't be the last instruction in a zero overhead
+	 * loop.
+	 * So we move the branch to the start of the loop, duplicate it
+	 * after the end, and set up r12 so that the branch isn't taken
+	 *  initially.
+	 */
+	mov_s	r12,WORD2
+	lpne	.Loop_end
+	brne	WORD2,r12,.Lodd
+	ld	WORD2,[r0,4]
+#else
 	lpne	.Loop_end
 	ld_s	WORD2,[r0,4]
+#endif
 	ld_s	r12,[r1,4]
 	brne	r4,r5,.Leven
 	ld.a	r4,[r0,8]
 	ld.a	r5,[r1,8]
+#ifdef __HS__
+.Loop_end:
+	brne	WORD2,r12,.Lodd
+#else
 	brne	WORD2,r12,.Lodd
 .Loop_end:
+#endif
 	asl_s	SHIFT,SHIFT,3
 	bhs_s	.Last_cmp
 	brne	r4,r5,.Leven
@@ -99,14 +117,25 @@ ENTRY(memcmp)
 	ldb	r4,[r0,0]
 	ldb	r5,[r1,0]
 	lsr.f	lp_count,r3
+#ifdef __HS__
+	mov	r12,r3
 	lpne	.Lbyte_end
+	brne	r3,r12,.Lbyte_odd
+#else
+	lpne	.Lbyte_end
+#endif
 	ldb_s	r3,[r0,1]
 	ldb	r12,[r1,1]
 	brne	r4,r5,.Lbyte_even
 	ldb.a	r4,[r0,2]
 	ldb.a	r5,[r1,2]
+#ifdef __HS__
+.Lbyte_end:
+	brne	r3,r12,.Lbyte_odd
+#else
 	brne	r3,r12,.Lbyte_odd
 .Lbyte_end:
+#endif
 	bcc	.Lbyte_even
 	brne	r4,r5,.Lbyte_even
 	ldb_s	r3,[r0,1]
diff --git a/libc/sysdeps/linux/arc/bits/syscalls.h b/libc/sysdeps/linux/arc/bits/syscalls.h
index 5da6aadb3216..248ef7844ce6 100644
--- a/libc/sysdeps/linux/arc/bits/syscalls.h
+++ b/libc/sysdeps/linux/arc/bits/syscalls.h
@@ -98,7 +98,11 @@ extern int __syscall_error (int);
  * for syscall itself.
  *-------------------------------------------------------------------------*/
 
-#define ARC_TRAP_INSN  "trap0	\n\t"
+#ifdef __A7__
+#define ARC_TRAP_INSN	"trap0		\n\t"
+#elif defined(__HS__)
+#define ARC_TRAP_INSN	"trap_s 0	\n\t"
+#endif
 
 #define INTERNAL_SYSCALL_NCS(nm, err, nr_args, args...)	\
 ({							\
@@ -176,7 +180,11 @@ extern int __syscall_error (int);
 
 #else
 
+#ifdef __A7__
 #define ARC_TRAP_INSN	trap0
+#elif defined(__HS__)
+#define ARC_TRAP_INSN	trap_s 0
+#endif
 
 #endif /* __ASSEMBLER__ */
 
diff --git a/libc/sysdeps/linux/arc/bits/uClibc_arch_features.h b/libc/sysdeps/linux/arc/bits/uClibc_arch_features.h
index 8af6eca4c8aa..451575586a33 100755
--- a/libc/sysdeps/linux/arc/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/arc/bits/uClibc_arch_features.h
@@ -47,4 +47,11 @@
 /* The default ';' is a comment on ARC. */
 #define __UCLIBC_ASM_LINE_SEP__ `
 
+/* does your target align 64bit values in register pairs ? (32bit arches only) */
+#if defined(__A7__)
+#undef __UCLIBC_SYSCALL_ALIGN_64BIT__
+#else
+#define __UCLIBC_SYSCALL_ALIGN_64BIT__
+#endif
+
 #endif /* _BITS_UCLIBC_ARCH_FEATURES_H */
-- 
1.9.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.