]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/kernel/entry-armv.S
[ARM] 4584/2: ARMv7: Add Advanced SIMD (NEON) extension support
[linux-2.6-omap-h63xx.git] / arch / arm / kernel / entry-armv.S
index 29dec080a60431dd88bfa7b732940449054374ad..8de21f51e48cc1f4988ba5ad2d5ac75240fab37a 100644 (file)
@@ -480,6 +480,13 @@ __und_usr:
  * co-processor instructions.  However, we have to watch out
  * for the ARM6/ARM7 SWI bug.
  *
+ * NEON is a special case that has to be handled here. Not all
+ * NEON instructions are co-processor instructions, so we have
+ * to make a special case of checking for them. Plus, there's
+ * five groups of them, so we have a table of mask/opcode pairs
+ * to check against, and if any match then we branch off into the
+ * NEON handler code.
+ *
  * Emulators may wish to make use of the following registers:
  *  r0  = instruction opcode.
  *  r2  = PC+4
@@ -488,6 +495,23 @@ __und_usr:
  *  lr  = unrecognised instruction return address
  */
 call_fpe:
+#ifdef CONFIG_NEON
+       adr     r6, .LCneon_opcodes
+2:
+       ldr     r7, [r6], #4                    @ mask value
+       cmp     r7, #0                          @ end mask?
+       beq     1f
+       and     r8, r0, r7
+       ldr     r7, [r6], #4                    @ opcode bits matching in mask
+       cmp     r8, r7                          @ NEON instruction?
+       bne     2b
+       get_thread_info r10
+       mov     r7, #1
+       strb    r7, [r10, #TI_USED_CP + 10]     @ mark CP#10 as used
+       strb    r7, [r10, #TI_USED_CP + 11]     @ mark CP#11 as used
+       b       do_vfp                          @ let VFP handler handle this
+1:
+#endif
        tst     r0, #0x08000000                 @ only CDP/CPRT/LDC/STC have bit 27
 #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710)
        and     r8, r0, #0x0f000000             @ mask out op-code bits
@@ -537,6 +561,20 @@ call_fpe:
        mov     pc, lr                          @ CP#14 (Debug)
        mov     pc, lr                          @ CP#15 (Control)
 
+#ifdef CONFIG_NEON
+       .align  6
+
+.LCneon_opcodes:
+       .word   0xfe000000                      @ mask
+       .word   0xf2000000                      @ opcode
+
+       .word   0xff100000                      @ mask
+       .word   0xf4000000                      @ opcode
+
+       .word   0x00000000                      @ mask
+       .word   0x00000000                      @ opcode
+#endif
+
 do_fpe:
        enable_irq
        ldr     r4, .LCfp