diff options
| author | Catalin Marinas <catalin.marinas@arm.com> | 2008-01-10 13:16:17 -0500 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-01-26 09:44:02 -0500 |
| commit | b5872db4a2ebe7dbc7a5e4013ae8ee37f3de3b97 (patch) | |
| tree | eab14c59c2b068868a5f53a56eb149fc1f902b13 | |
| parent | 25ebee020bd34d1f4c5678538204f0b10bf9f6d5 (diff) | |
[ARM] 4584/2: ARMv7: Add Advanced SIMD (NEON) extension support
This patch enables the use of the Advanced SIMD (NEON) extension on
ARMv7. The NEON technology is a 64/128-bit hybrid SIMD architecture
for accelerating the performance of multimedia and signal processing
applications. The extension shares the registers with the VFP unit and
enabling/disabling and saving/restoring follow the same rules. In
addition, there are instructions that do not have the appropriate CP
number encoded, the checks being made in the call_fpe function.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/Kconfig | 7 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 38 |
2 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f4eeb03bc6a9..709f9d383c87 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -966,6 +966,13 @@ config VFPv3 | |||
| 966 | depends on VFP | 966 | depends on VFP |
| 967 | default y if CPU_V7 | 967 | default y if CPU_V7 |
| 968 | 968 | ||
| 969 | config NEON | ||
| 970 | bool "Advanced SIMD (NEON) Extension support" | ||
| 971 | depends on VFPv3 && CPU_V7 | ||
| 972 | help | ||
| 973 | Say Y to include support code for NEON, the ARMv7 Advanced SIMD | ||
| 974 | Extension. | ||
| 975 | |||
| 969 | endmenu | 976 | endmenu |
| 970 | 977 | ||
| 971 | menu "Userspace binary formats" | 978 | menu "Userspace binary formats" |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 29dec080a604..8de21f51e48c 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -480,6 +480,13 @@ __und_usr: | |||
| 480 | * co-processor instructions. However, we have to watch out | 480 | * co-processor instructions. However, we have to watch out |
| 481 | * for the ARM6/ARM7 SWI bug. | 481 | * for the ARM6/ARM7 SWI bug. |
| 482 | * | 482 | * |
| 483 | * NEON is a special case that has to be handled here. Not all | ||
| 484 | * NEON instructions are co-processor instructions, so we have | ||
| 485 | * to make a special case of checking for them. Plus, there's | ||
| 486 | * five groups of them, so we have a table of mask/opcode pairs | ||
| 487 | * to check against, and if any match then we branch off into the | ||
| 488 | * NEON handler code. | ||
| 489 | * | ||
| 483 | * Emulators may wish to make use of the following registers: | 490 | * Emulators may wish to make use of the following registers: |
| 484 | * r0 = instruction opcode. | 491 | * r0 = instruction opcode. |
| 485 | * r2 = PC+4 | 492 | * r2 = PC+4 |
| @@ -488,6 +495,23 @@ __und_usr: | |||
| 488 | * lr = unrecognised instruction return address | 495 | * lr = unrecognised instruction return address |
| 489 | */ | 496 | */ |
| 490 | call_fpe: | 497 | call_fpe: |
| 498 | #ifdef CONFIG_NEON | ||
| 499 | adr r6, .LCneon_opcodes | ||
| 500 | 2: | ||
| 501 | ldr r7, [r6], #4 @ mask value | ||
| 502 | cmp r7, #0 @ end mask? | ||
| 503 | beq 1f | ||
| 504 | and r8, r0, r7 | ||
| 505 | ldr r7, [r6], #4 @ opcode bits matching in mask | ||
| 506 | cmp r8, r7 @ NEON instruction? | ||
| 507 | bne 2b | ||
| 508 | get_thread_info r10 | ||
| 509 | mov r7, #1 | ||
| 510 | strb r7, [r10, #TI_USED_CP + 10] @ mark CP#10 as used | ||
| 511 | strb r7, [r10, #TI_USED_CP + 11] @ mark CP#11 as used | ||
| 512 | b do_vfp @ let VFP handler handle this | ||
| 513 | 1: | ||
| 514 | #endif | ||
| 491 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 | 515 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 |
| 492 | #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) | 516 | #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) |
| 493 | and r8, r0, #0x0f000000 @ mask out op-code bits | 517 | and r8, r0, #0x0f000000 @ mask out op-code bits |
| @@ -537,6 +561,20 @@ call_fpe: | |||
| 537 | mov pc, lr @ CP#14 (Debug) | 561 | mov pc, lr @ CP#14 (Debug) |
| 538 | mov pc, lr @ CP#15 (Control) | 562 | mov pc, lr @ CP#15 (Control) |
| 539 | 563 | ||
| 564 | #ifdef CONFIG_NEON | ||
| 565 | .align 6 | ||
| 566 | |||
| 567 | .LCneon_opcodes: | ||
| 568 | .word 0xfe000000 @ mask | ||
| 569 | .word 0xf2000000 @ opcode | ||
| 570 | |||
| 571 | .word 0xff100000 @ mask | ||
| 572 | .word 0xf4000000 @ opcode | ||
| 573 | |||
| 574 | .word 0x00000000 @ mask | ||
| 575 | .word 0x00000000 @ opcode | ||
| 576 | #endif | ||
| 577 | |||
| 540 | do_fpe: | 578 | do_fpe: |
| 541 | enable_irq | 579 | enable_irq |
| 542 | ldr r4, .LCfp | 580 | ldr r4, .LCfp |
