1 /* SPDX-License-Identifier: GPL-2.0-or-later * 2 /* 3 NetWinder Floating Point Emulator 4 (c) Rebel.COM, 1998 5 (c) 1998, 1999 Philip Blundell 6 7 Direct questions, comments to Scott Bambro< 8 9 */ 10 #include <linux/linkage.h> 11 #include <asm/assembler.h> 12 #include <asm/opcodes.h> 13 14 /* This is the kernel's entry point into the f 15 It is called from the kernel with code similar 16 17 sub r4, r5, #4 18 ldrt r0, [r4] 19 adrsvc al, r9, ret_from_exception 20 adrsvc al, lr, fpundefinstr 21 22 get_current_task r10 23 mov r8, #1 24 strb r8, [r10, #TSK_USED_MATH] 25 add r10, r10, #TSS_FPESAVE 26 ldr r4, .LC2 27 ldr pc, [r4] 28 29 The kernel expects the emulator to return via 30 points of return it passes to the emulator. T 31 successful in its emulation, jumps to ret_from 32 r9) and the kernel takes care of returning con 33 the user code. If the emulator is unable to e 34 it returns via _fpundefinstr (passed via lr) a 35 user program with a core dump. 36 37 On entry to the emulator r10 points to an area 38 reserved in the thread structure for this proc 39 emulator saves its registers across calls. Th 40 is used as a flag to detect the first time a p 41 so that the emulator startup cost can be avoid 42 want it. 43 44 This routine does three things: 45 46 1) The kernel has created a struct pt_regs on 47 user registers into it. See /usr/include/asm/ 48 49 2) It calls EmulateAll to emulate a floating p 50 EmulateAll returns 1 if the emulation was succ 51 52 3) If an instruction has been emulated success 53 the next instruction. If it is a floating poi 54 executes the instruction, without returning to 55 way it repeatedly looks ahead and executes flo 56 until it encounters a non floating point instr 57 returns via _fpreturn. 58 59 This is done to reduce the effect of the trap 60 floating point instructions. GCC attempts to 61 instructions to allow the emulator to spread t 62 several floating point instructions. */ 63 64 #include <asm/asm-offsets.h> 65 66 .globl nwfpe_enter 67 nwfpe_enter: 68 mov r4, lr @ save 69 mov sl, sp @ we a 70 71 ldr r5, [sp, #S_PC] @ get 72 mov r6, r0 @ save 73 emulate: 74 ldr r1, [sp, #S_PSR] @ fetc 75 bl arm_check_condition @ chec 76 cmp r0, #ARM_OPCODE_CONDTEST_PASS 77 78 @ if condition code failed to match, n 79 bne next @ get 80 81 mov r0, r6 @ prep 82 bl EmulateAll @ emul 83 cmp r0, #0 @ was 84 reteq r4 @ no, 85 86 next: 87 uaccess_enable r3 88 .Lx1: ldrt r6, [r5], #4 @ get 89 @ incr 90 uaccess_disable r3 91 and r2, r6, #0x0F000000 @ test 92 teq r2, #0x0C000000 93 teqne r2, #0x0D000000 94 teqne r2, #0x0E000000 95 retne r9 @ retu 96 97 str r5, [sp, #S_PC] @ upda 98 99 mov r0, r6 @ save 100 b emulate @ chec 101 102 @ We need to be prepared for the instr 103 @ to fault. Emit the appropriate exce 104 @ ??? For some reason, faults can happ 105 @ plain LDR instruction. Weird, but i 106 .pushsection .text.fixup,"ax" 107 .align 2 108 .Lrep: str r4, [sp, #S_PC] @ retr 109 .Lfix: ret r9 @ let 110 .popsection 111 112 .pushsection __ex_table,"a" 113 .align 3 114 .long .Lx1, .Lfix 115 .popsection 116 117 @ 118 @ Check whether the instruction is a c 119 @ If yes, we need to call the relevant 120 @ Only FPE instructions are dispatched 121 @ is handled by undef hooks. 122 @ 123 @ Emulators may wish to make use of th 124 @ r4 = PC value to resume execution 125 @ r9 = normal "successful" return ad 126 @ lr = unrecognised instruction retu 127 @ IRQs enabled, FIQs enabled. 128 @ 129 ENTRY(call_fpe) 130 mov r2, r4 131 sub r4, r4, #4 132 USERL( .Lrep, ldrt r0, [r4]) 133 ARM_BE8(rev r0, r0) 134 135 uaccess_disable ip 136 137 get_thread_info r10 138 tst r0, #0x08000000 139 reteq lr 140 and r8, r0, #0x00000f00 141 #ifdef CONFIG_IWMMXT 142 @ Test if we need to give access to iW 143 ldr r5, [r10, #TI_FLAGS] 144 rsbs r7, r8, #(1 << 8) 145 movscs r7, r5, lsr #(TIF_USING_IWMMXT 146 movcs r0, sp 147 bcs iwmmxt_task_enable 148 #endif 149 add pc, pc, r8, lsr #6 150 nop 151 152 ret lr 153 b do_fpe 154 b do_fpe 155 ret lr 156 ret lr 157 ret lr 158 ret lr 159 ret lr 160 ret lr 161 ret lr 162 ret lr 163 ret lr 164 ret lr 165 ret lr 166 ret lr 167 ret lr 168 169 do_fpe: 170 add r10, r10, #TI_FPSTATE 171 ldr_va pc, fp_enter, tmp=r4 172 173 @ 174 @ The FP module is called with these r 175 @ r0 = instruction 176 @ r2 = PC+4 177 @ r9 = normal "successful" return ad 178 @ r10 = FP workspace 179 @ lr = unrecognised FP instruction r 180 @ 181 182 .pushsection .data 183 .align 2 184 ENTRY(fp_enter) 185 .word no_fp 186 .popsection 187 188 no_fp: 189 ret lr 190 ENDPROC(no_fp)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.