diff options
author | Paul Brook <paul@codesourcery.com> | 2008-04-18 17:43:08 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2008-04-18 17:43:08 -0400 |
commit | cb170a45d69b573a08247acfbbff3b9d6e6e2f8f (patch) | |
tree | 695cededbc383091c463f0f1a2808654a091f098 | |
parent | 48d7927bdf071d05cf5d15b816cf06b0937cb84f (diff) |
Linux Thumb-2 support for user-space applications
This patch implements Thumb-2 application support in Linux. Original
implementation by Paul Brook with fixes for VFP and Neon by Catalin
Marinas.
Signed-off-by: Paul Brook <paul@codesourcery.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 5e647eb6b3b9..6fd1460111ec 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -462,10 +462,6 @@ __irq_usr: | |||
462 | __und_usr: | 462 | __und_usr: |
463 | usr_entry | 463 | usr_entry |
464 | 464 | ||
465 | tst r3, #PSR_T_BIT @ Thumb mode? | ||
466 | bne __und_usr_unknown @ ignore FP | ||
467 | sub r4, r2, #4 | ||
468 | |||
469 | @ | 465 | @ |
470 | @ fall through to the emulation code, which returns using r9 if | 466 | @ fall through to the emulation code, which returns using r9 if |
471 | @ it has emulated the instruction, or the more conventional lr | 467 | @ it has emulated the instruction, or the more conventional lr |
@@ -475,7 +471,24 @@ __und_usr: | |||
475 | @ | 471 | @ |
476 | adr r9, ret_from_exception | 472 | adr r9, ret_from_exception |
477 | adr lr, __und_usr_unknown | 473 | adr lr, __und_usr_unknown |
478 | 1: ldrt r0, [r4] | 474 | tst r3, #PSR_T_BIT @ Thumb mode? |
475 | subeq r4, r2, #4 @ ARM instr at LR - 4 | ||
476 | subne r4, r2, #2 @ Thumb instr at LR - 2 | ||
477 | 1: ldreqt r0, [r4] | ||
478 | beq call_fpe | ||
479 | @ Thumb instruction | ||
480 | #if __LINUX_ARM_ARCH__ >= 7 | ||
481 | 2: ldrht r5, [r4], #2 | ||
482 | and r0, r5, #0xf800 @ mask bits 111x x... .... .... | ||
483 | cmp r0, #0xe800 @ 32bit instruction if xx != 0 | ||
484 | blo __und_usr_unknown | ||
485 | 3: ldrht r0, [r4] | ||
486 | add r2, r2, #2 @ r2 is PC + 2, make it PC + 4 | ||
487 | orr r0, r0, r5, lsl #16 | ||
488 | #else | ||
489 | b __und_usr_unknown | ||
490 | #endif | ||
491 | |||
479 | @ | 492 | @ |
480 | @ fallthrough to call_fpe | 493 | @ fallthrough to call_fpe |
481 | @ | 494 | @ |
@@ -484,10 +497,14 @@ __und_usr: | |||
484 | * The out of line fixup for the ldrt above. | 497 | * The out of line fixup for the ldrt above. |
485 | */ | 498 | */ |
486 | .section .fixup, "ax" | 499 | .section .fixup, "ax" |
487 | 2: mov pc, r9 | 500 | 4: mov pc, r9 |
488 | .previous | 501 | .previous |
489 | .section __ex_table,"a" | 502 | .section __ex_table,"a" |
490 | .long 1b, 2b | 503 | .long 1b, 4b |
504 | #if __LINUX_ARM_ARCH__ >= 7 | ||
505 | .long 2b, 4b | ||
506 | .long 3b, 4b | ||
507 | #endif | ||
491 | .previous | 508 | .previous |
492 | 509 | ||
493 | /* | 510 | /* |
@@ -514,9 +531,16 @@ __und_usr: | |||
514 | * r10 = this threads thread_info structure. | 531 | * r10 = this threads thread_info structure. |
515 | * lr = unrecognised instruction return address | 532 | * lr = unrecognised instruction return address |
516 | */ | 533 | */ |
534 | @ | ||
535 | @ Fall-through from Thumb-2 __und_usr | ||
536 | @ | ||
537 | #ifdef CONFIG_NEON | ||
538 | adr r6, .LCneon_thumb_opcodes | ||
539 | b 2f | ||
540 | #endif | ||
517 | call_fpe: | 541 | call_fpe: |
518 | #ifdef CONFIG_NEON | 542 | #ifdef CONFIG_NEON |
519 | adr r6, .LCneon_opcodes | 543 | adr r6, .LCneon_arm_opcodes |
520 | 2: | 544 | 2: |
521 | ldr r7, [r6], #4 @ mask value | 545 | ldr r7, [r6], #4 @ mask value |
522 | cmp r7, #0 @ end mask? | 546 | cmp r7, #0 @ end mask? |
@@ -533,6 +557,7 @@ call_fpe: | |||
533 | 1: | 557 | 1: |
534 | #endif | 558 | #endif |
535 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 | 559 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 |
560 | tstne r0, #0x04000000 @ bit 26 set on both ARM and Thumb-2 | ||
536 | #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) | 561 | #if defined(CONFIG_CPU_ARM610) || defined(CONFIG_CPU_ARM710) |
537 | and r8, r0, #0x0f000000 @ mask out op-code bits | 562 | and r8, r0, #0x0f000000 @ mask out op-code bits |
538 | teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)? | 563 | teqne r8, #0x0f000000 @ SWI (ARM6/7 bug)? |
@@ -584,7 +609,7 @@ call_fpe: | |||
584 | #ifdef CONFIG_NEON | 609 | #ifdef CONFIG_NEON |
585 | .align 6 | 610 | .align 6 |
586 | 611 | ||
587 | .LCneon_opcodes: | 612 | .LCneon_arm_opcodes: |
588 | .word 0xfe000000 @ mask | 613 | .word 0xfe000000 @ mask |
589 | .word 0xf2000000 @ opcode | 614 | .word 0xf2000000 @ opcode |
590 | 615 | ||
@@ -593,6 +618,16 @@ call_fpe: | |||
593 | 618 | ||
594 | .word 0x00000000 @ mask | 619 | .word 0x00000000 @ mask |
595 | .word 0x00000000 @ opcode | 620 | .word 0x00000000 @ opcode |
621 | |||
622 | .LCneon_thumb_opcodes: | ||
623 | .word 0xef000000 @ mask | ||
624 | .word 0xef000000 @ opcode | ||
625 | |||
626 | .word 0xff100000 @ mask | ||
627 | .word 0xf9000000 @ opcode | ||
628 | |||
629 | .word 0x00000000 @ mask | ||
630 | .word 0x00000000 @ opcode | ||
596 | #endif | 631 | #endif |
597 | 632 | ||
598 | do_fpe: | 633 | do_fpe: |