Subject: Re: New in_cksum/in4_cksum implementation
To: Chris Gilbert <chris@dokein.co.uk>
From: Richard Earnshaw <rearnsha@arm.com>
List: port-arm
Date: 09/11/2003 10:47:41
chris@dokein.co.uk said:
> Something it has reminded me I was thinking of trying to do was add a
> define along the lines of: CAN_DO_HALF_LOADS basically so that you can
> tell if ldrh's will work as expected. 

We should add a whole load of "feature tests" to machine/asm.h.   Some of 
which are macros that can be used directly in the code (does processor use 
bx for return rather than mov pc?)

Most of these features can be set up directly from the information that 
gcc passes in via the preprocessor and predefined macros.  GCC could do it 
more cleanly, but I've been scared of changing the way it works for fear 
of breaking fragile user code.

In essence, gcc defines a single macro for the architecture of the 
processor it is compiling for (add -mcpu=xscale or -mcpu=arm10e and you 
get __ARM_ARCH_5TE__ defined, add -mcpu=strongarm and you get 
__ARM_ARCH_4__ defined.  There's no need to worry about the RISC PC ldrh 
problem, it builds kernels with -march=armv3m, which, surprise surprise 
causes __ARCH_ARM_3M__ to be defined).

[asside: in retrospect, the option -mcpu=arm10e should cause all of 
__ARM_ARCH_4__, __ARM_ARCH_4T__, __ARM_ARCH_5__, __ARM_ARCH_5E__, ... to 
be defined.  But as I said above, that might break existing code].

Here's a bit of gloop for starters, not tested (let's at least make the 
code in NetBSD sane):

#ifdef __ARM_ARCH_5TE__
#define __ARM_ARCH_5T__
#define __ARM_ARCH_5E__
#endif

#ifdef __ARM_ARCH_5T__
#define __ARM_ARCH_4T__
#endif

#if defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5E__
#define __ARM_ARCH_5__
#endif

#if defined __ARM_ARCH_5__
#define __ARM_ARCH_4__
#endif

#ifdef __ARM_ARCH_4__
#define __ARM_ARCH_3__
#endif

/* Don't care about arch 2.  */

.macro RET	cond=
#if defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5__
	bx\cond 	lr
#else
	mov\cond	pc, lr
#endif
.endm

/* PLD works on any v5E, but currently only XSCALE does anything useful */
#ifdef __XSCALE__
	#define PLD(addr ...)	pld	addr
#else
	#define PLD(addr ...)
#endif

R.