111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (C) 2008 The Android Open Source Project
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * All rights reserved.
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Redistribution and use in source and binary forms, with or without
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * modification, are permitted provided that the following conditions
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * are met:
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  * Redistributions of source code must retain the above copyright
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    notice, this list of conditions and the following disclaimer.
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  * Redistributions in binary form must reproduce the above copyright
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    notice, this list of conditions and the following disclaimer in
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    the documentation and/or other materials provided with the
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *    distribution.
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * SUCH DAMAGE.
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _ARM_MACHINE_CPU_FEATURES_H
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _ARM_MACHINE_CPU_FEATURES_H
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* The purpose of this file is to define several macros corresponding
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * to CPU features that may or may not be available at build time on
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * on the target CPU.
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * This is done to abstract us from the various ARM Architecture
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * quirks and alphabet soup.
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * IMPORTANT: We have no intention to support anything below an ARMv4T !
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* __ARM_ARCH__ is a number corresponding to the ARM revision
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * we're going to support
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * it looks like our toolchain doesn't define __ARM_ARCH__
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * so try to guess it.
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef __ARM_ARCH__
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined __ARM_ARCH_7__   || defined __ARM_ARCH_7A__ || \
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      defined __ARM_ARCH_7R__  || defined __ARM_ARCH_7M__
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define __ARM_ARCH__ 7
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined __ARM_ARCH_6__   || defined __ARM_ARCH_6J__ || \
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      defined __ARM_ARCH_6K__  || defined __ARM_ARCH_6Z__ || \
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define __ARM_ARCH__ 6
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined __ARM_ARCH_5__ || defined __ARM_ARCH_5T__ || \
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define __ARM_ARCH__ 5
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined __ARM_ARCH_4T__
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define __ARM_ARCH__ 4
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  elif defined __ARM_ARCH_4__
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error ARMv4 is not supported, please use ARMv4T at a minimum
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    error Unknown or unsupported ARM architecture
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* experimental feature used to check that our ARMv4 workarounds
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * work correctly without a real ARMv4 machine */
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef BIONIC_EXPERIMENTAL_FORCE_ARMV4
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  undef  __ARM_ARCH__
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_ARCH__  4
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_5TE if we have the ARMv5TE instructions */
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ > 5
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_5TE  1
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#elif __ARM_ARCH__ == 5
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#    define __ARM_HAVE_5TE  1
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* instructions introduced in ARMv5 */
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 5
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_BLX  1
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_CLZ  1
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_LDC2 1
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_MCR2 1
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_MRC2 1
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_STC2 1
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* ARMv5TE introduces a few instructions */
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_HAVE_5TE
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_PLD   1
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_MCRR  1
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_MRRC  1
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_HALFWORD_MULTIPLY when half-word multiply instructions
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * this means variants of: smul, smulw, smla, smlaw, smlal
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_HAVE_5TE
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_HALFWORD_MULTIPLY  1
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_PAIR_LOAD_STORE when 64-bit memory loads and stored
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * into/from a pair of 32-bit registers is supported throuhg 'ldrd' and 'strd'
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_HAVE_5TE
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_PAIR_LOAD_STORE 1
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_SATURATED_ARITHMETIC is you have the saturated integer
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * arithmetic instructions: qdd, qdadd, qsub, qdsub
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_HAVE_5TE
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  __ARM_HAVE_SATURATED_ARITHMETIC 1
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_PC_INTERWORK when a direct assignment to the
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * pc register will switch into thumb/ARM mode depending on bit 0
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * of the new instruction address. Before ARMv5, this was not the
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * case, and you have to write:
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *     mov  r0, [<some address>]
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *     bx   r0
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * instead of:
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *     ldr  pc, [<some address>]
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * note that this affects any instruction that explicitly changes the
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * value of the pc register, including ldm { ...,pc } or 'add pc, #offset'
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 5
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_HAVE_PC_INTERWORK
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_LDREX_STREX for ARMv6 and ARMv7 architecture to be
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * used in replacement of deprecated swp instruction
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 6
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_HAVE_LDREX_STREX
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_DMB for ARMv7 architecture
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 7
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_HAVE_DMB
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define __ARM_HAVE_LDREXD for ARMv7 architecture
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * (also present in ARMv6K, but not implemented in ARMv7-M, neither of which
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * we care about)
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 7
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_HAVE_LDREXD
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define _ARM_HAVE_VFP if we have VFPv3
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_HAVE_VFP
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Neon SIMD instruction set extensions. This also implies
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * that VFPv3-D32 is supported.
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define __ARM_HAVE_NEON
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* Assembly-only macros */
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef __ASSEMBLY__
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/* define a handy PLD(address) macro since the cache preload
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * is an optional opcode
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __ARM_HAVE_PLD
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  PLD(reg,offset)    pld    [reg, offset]
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  define  PLD(reg,offset)    /* nothing */
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* ! __ASSEMBLY__ */
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif /* _ARM_MACHINE_CPU_FEATURES_H */
202