1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_M68K_SETUP_H
3 #define _ASM_M68K_SETUP_H
6 #include <linux/linkage.h>
8 /* Status Register bits */
10 /* accrued exception bits */
11 #define FPSR_AEXC_INEX 3
12 #define FPSR_AEXC_DZ 4
13 #define FPSR_AEXC_UNFL 5
14 #define FPSR_AEXC_OVFL 6
15 #define FPSR_AEXC_IOP 7
17 /* exception status bits */
18 #define FPSR_EXC_INEX1 8
19 #define FPSR_EXC_INEX2 9
20 #define FPSR_EXC_DZ 10
21 #define FPSR_EXC_UNFL 11
22 #define FPSR_EXC_OVFL 12
23 #define FPSR_EXC_OPERR 13
24 #define FPSR_EXC_SNAN 14
25 #define FPSR_EXC_BSUN 15
27 /* quotient byte, assumes big-endian, of course */
28 #define FPSR_QUOTIENT(fpsr) (*((signed char *) &(fpsr) + 1))
30 /* condition code bits */
31 #define FPSR_CC_NAN 24
32 #define FPSR_CC_INF 25
34 #define FPSR_CC_NEG 27
37 /* Control register bits */
40 #define FPCR_ROUND_RN 0 /* round to nearest/even */
41 #define FPCR_ROUND_RZ 1 /* round to zero */
42 #define FPCR_ROUND_RM 2 /* minus infinity */
43 #define FPCR_ROUND_RP 3 /* plus infinity */
45 /* rounding precision */
46 #define FPCR_PRECISION_X 0 /* long double */
47 #define FPCR_PRECISION_S 1 /* double */
48 #define FPCR_PRECISION_D 2 /* float */
51 /* Flags to select the debugging output */
61 #define PMDECODE (1<<PDECODE)
62 #define PMEXECUTE (1<<PEXECUTE)
63 #define PMCONV (1<<PCONV)
64 #define PMNORM (1<<PNORM)
65 #define PMREGISTER (1<<PREGISTER)
66 #define PMINSTR (1<<PINSTR)
67 #define PMUNIMPL (1<<PUNIMPL)
68 #define PMMOVEM (1<<PMOVEM)
72 #include <linux/kernel.h>
73 #include <linux/sched.h>
76 unsigned long long m64
;
81 unsigned long long m64
[2];
85 /* internal representation of extended fp numbers */
87 unsigned char lowmant
;
93 /* C representation of FPU registers */
94 /* NOTE: if you change this, you have to change the assembler offsets
95 below and the size in <asm/fpu.h>, too */
97 struct fp_ext fpreg
[8];
103 struct fp_ext temp
[2];
107 extern unsigned int fp_debugprint
;
109 #define dprint(bit, fmt, ...) ({ \
110 if (fp_debugprint & (1 << (bit))) \
111 pr_info(fmt, ##__VA_ARGS__); \
114 #define dprint(bit, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
117 #define uprint(str) ({ \
118 static int __count = 3; \
121 pr_err("You just hit an unimplemented " \
122 "fpu instruction (%s)\n", str); \
123 pr_err("Please report this to ....\n"); \
128 #define FPDATA ((struct fp_data *)current->thread.fp)
130 #else /* __ASSEMBLY__ */
134 /* offsets from the base register to the floating point data in the task struct */
135 #define FPD_FPREG (TASK_THREAD+THREAD_FPREG+0)
136 #define FPD_FPCR (TASK_THREAD+THREAD_FPREG+96)
137 #define FPD_FPSR (TASK_THREAD+THREAD_FPREG+100)
138 #define FPD_FPIAR (TASK_THREAD+THREAD_FPREG+104)
139 #define FPD_PREC (TASK_THREAD+THREAD_FPREG+108)
140 #define FPD_RND (TASK_THREAD+THREAD_FPREG+110)
141 #define FPD_TEMPFP1 (TASK_THREAD+THREAD_FPREG+112)
142 #define FPD_TEMPFP2 (TASK_THREAD+THREAD_FPREG+124)
143 #define FPD_SIZEOF (TASK_THREAD+THREAD_FPREG+136)
145 /* offsets on the stack to access saved registers,
146 * these are only used during instruction decoding
147 * where we always know how deep we're on the stack.
149 #define FPS_DO (PT_OFF_D0)
150 #define FPS_D1 (PT_OFF_D1)
151 #define FPS_D2 (PT_OFF_D2)
152 #define FPS_A0 (PT_OFF_A0)
153 #define FPS_A1 (PT_OFF_A1)
154 #define FPS_A2 (PT_OFF_A2)
155 #define FPS_SR (PT_OFF_SR)
156 #define FPS_PC (PT_OFF_PC)
157 #define FPS_EA (PT_OFF_PC+6)
158 #define FPS_PC2 (PT_OFF_PC+10)
161 lea (FPD_FPREG
,FPDATA
,%d0
.w
*4),%a0
162 lea (%a0
,%d0
.w
*8),%a0
165 /* Macros used to get/put the current program counter.
166 * 020/030 use a different stack frame then 040/060, for the
167 * 040/060 the return pc points already to the next location,
168 * so this only needs to be modified for jump instructions.
170 .macro fp_get_pc dest
171 move
.l (FPS_PC
+4,%sp
),\dest
174 .macro fp_put_pc src
,jump
=0
175 move
.l \src
,(FPS_PC
+4,%sp
)
178 .macro fp_get_instr_data f
,s
,dest
,label
179 getuser
\f,%sp@
(FPS_PC
+4)@
(0),\dest
,\label
,%sp@
(FPS_PC
+4)
180 addq
.l
#\s,%sp@(FPS_PC+4)
183 .macro fp_get_instr_word dest
,label
,addr
184 fp_get_instr_data w
,2,\dest
,\label
,\addr
187 .macro fp_get_instr_long dest
,label
,addr
188 fp_get_instr_data l
,4,\dest
,\label
,\addr
191 /* These macros are used to read from/write to user space
192 * on error we jump to the fixup section, load the fault
193 * address into %a0 and jump to the exit.
194 * (derived from <asm/uaccess.h>)
196 .macro getuser size
,src
,dest
,label
,addr
197 | printf
,"[\size<%08x]",1,\addr
198 .Lu1\@
: moves\size \src
,\dest
202 .Lu2\@
: move
.l
\addr
,%a0
206 .section __ex_table
,"a"
212 .macro putuser size
,src
,dest
,label
,addr
213 | printf
,"[\size>%08x]",1,\addr
214 .Lu1\@
: moves\size \src
,\dest
219 .Lu3\@
: move
.l
\addr
,%a0
223 .section __ex_table
,"a"
230 /* work around binutils idiocy */
237 .macro getuser
.\m src
,dest
,label
,addr
238 getuser
.\m
,\src
,\dest
,\label
,\addr
240 .macro putuser
.\m src
,dest
,label
,addr
241 putuser
.\m
,\src
,\dest
,\label
,\addr
246 .macro movestack nr
,arg1
,arg2
,arg3
,arg4
,arg5
248 movestack (\nr
-1),\arg
2,\arg
3,\arg
4,\arg
5
253 .macro printf bit
=-1,string
,nr
=0,arg1
,arg2
,arg3
,arg4
,arg5
260 movem
.l
%d0
/%d1
/%a0
/%a1
,-(%sp
)
265 btst
%d0
,fp_debugprint
+((31-\bit
)/8)
267 btst
#\bit,fp_debugprint+((31-\bit)/8)
271 movestack
\nr
,\arg
1,\arg
2,\arg
3,\arg
4,\arg
5
274 lea ((\nr
+1)*4,%sp
),%sp
276 movem
.l (%sp
)+,%d0
/%d1
/%a0
/%a1
282 movem
.l
%d0
/%a0
,-(%sp
)
289 .Lx1\@
: printf
\bit
," %c",1,%d0
295 .Lx2\@
: printf
\bit
,"1."
296 .Lx3\@
: printf
\bit
,"%08x%08x",2,%d0
,%a0@
(8)
299 printf
\bit
,"E%04x",1,%d0
301 printf
\bit
," %08x%08x%08x",3,%a0@
,%a0@
(4),%a0@
(8)
303 movem
.l (%sp
)+,%d0
/%a0
307 .macro debug instr
,args
314 #endif /* __ASSEMBLY__ */
316 #endif /* _ASM_M68K_SETUP_H */