Browse Source

ARCv2 ISA support

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 <vgupta@synopsys.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Vineet Gupta 9 years ago
parent
commit
afab56958f

+ 1 - 0
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
 

+ 6 - 0
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

+ 1 - 0
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"

+ 33 - 0
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

+ 1 - 0
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).  */
 

+ 13 - 2
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.

+ 4 - 0
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)

+ 29 - 0
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]

+ 9 - 1
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__ */
 

+ 7 - 0
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 */