OSDN Git Service

Merge remote-tracking branch 'origin/next' into kvm-ppc-next
[uclinux-h8/linux.git] / arch / mips / kernel / branch.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 1996, 97, 2000, 2001 by Ralf Baechle
7  * Copyright (C) 2001 MIPS Technologies, Inc.
8  */
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/signal.h>
12 #include <linux/module.h>
13 #include <asm/branch.h>
14 #include <asm/cpu.h>
15 #include <asm/cpu-features.h>
16 #include <asm/fpu.h>
17 #include <asm/fpu_emulator.h>
18 #include <asm/inst.h>
19 #include <asm/ptrace.h>
20 #include <asm/uaccess.h>
21
22 /*
23  * Calculate and return exception PC in case of branch delay slot
24  * for microMIPS and MIPS16e. It does not clear the ISA mode bit.
25  */
26 int __isa_exception_epc(struct pt_regs *regs)
27 {
28         unsigned short inst;
29         long epc = regs->cp0_epc;
30
31         /* Calculate exception PC in branch delay slot. */
32         if (__get_user(inst, (u16 __user *) msk_isa16_mode(epc))) {
33                 /* This should never happen because delay slot was checked. */
34                 force_sig(SIGSEGV, current);
35                 return epc;
36         }
37         if (cpu_has_mips16) {
38                 if (((union mips16e_instruction)inst).ri.opcode
39                                 == MIPS16e_jal_op)
40                         epc += 4;
41                 else
42                         epc += 2;
43         } else if (mm_insn_16bit(inst))
44                 epc += 2;
45         else
46                 epc += 4;
47
48         return epc;
49 }
50
51 /*
52  * Compute return address and emulate branch in microMIPS mode after an
53  * exception only. It does not handle compact branches/jumps and cannot
54  * be used in interrupt context. (Compact branches/jumps do not cause
55  * exceptions.)
56  */
57 int __microMIPS_compute_return_epc(struct pt_regs *regs)
58 {
59         u16 __user *pc16;
60         u16 halfword;
61         unsigned int word;
62         unsigned long contpc;
63         struct mm_decoded_insn mminsn = { 0 };
64
65         mminsn.micro_mips_mode = 1;
66
67         /* This load never faults. */
68         pc16 = (unsigned short __user *)msk_isa16_mode(regs->cp0_epc);
69         __get_user(halfword, pc16);
70         pc16++;
71         contpc = regs->cp0_epc + 2;
72         word = ((unsigned int)halfword << 16);
73         mminsn.pc_inc = 2;
74
75         if (!mm_insn_16bit(halfword)) {
76                 __get_user(halfword, pc16);
77                 pc16++;
78                 contpc = regs->cp0_epc + 4;
79                 mminsn.pc_inc = 4;
80                 word |= halfword;
81         }
82         mminsn.insn = word;
83
84         if (get_user(halfword, pc16))
85                 goto sigsegv;
86         mminsn.next_pc_inc = 2;
87         word = ((unsigned int)halfword << 16);
88
89         if (!mm_insn_16bit(halfword)) {
90                 pc16++;
91                 if (get_user(halfword, pc16))
92                         goto sigsegv;
93                 mminsn.next_pc_inc = 4;
94                 word |= halfword;
95         }
96         mminsn.next_insn = word;
97
98         mm_isBranchInstr(regs, mminsn, &contpc);
99
100         regs->cp0_epc = contpc;
101
102         return 0;
103
104 sigsegv:
105         force_sig(SIGSEGV, current);
106         return -EFAULT;
107 }
108
109 /*
110  * Compute return address and emulate branch in MIPS16e mode after an
111  * exception only. It does not handle compact branches/jumps and cannot
112  * be used in interrupt context. (Compact branches/jumps do not cause
113  * exceptions.)
114  */
115 int __MIPS16e_compute_return_epc(struct pt_regs *regs)
116 {
117         u16 __user *addr;
118         union mips16e_instruction inst;
119         u16 inst2;
120         u32 fullinst;
121         long epc;
122
123         epc = regs->cp0_epc;
124
125         /* Read the instruction. */
126         addr = (u16 __user *)msk_isa16_mode(epc);
127         if (__get_user(inst.full, addr)) {
128                 force_sig(SIGSEGV, current);
129                 return -EFAULT;
130         }
131
132         switch (inst.ri.opcode) {
133         case MIPS16e_extend_op:
134                 regs->cp0_epc += 4;
135                 return 0;
136
137                 /*
138                  *  JAL and JALX in MIPS16e mode
139                  */
140         case MIPS16e_jal_op:
141                 addr += 1;
142                 if (__get_user(inst2, addr)) {
143                         force_sig(SIGSEGV, current);
144                         return -EFAULT;
145                 }
146                 fullinst = ((unsigned)inst.full << 16) | inst2;
147                 regs->regs[31] = epc + 6;
148                 epc += 4;
149                 epc >>= 28;
150                 epc <<= 28;
151                 /*
152                  * JAL:5 X:1 TARGET[20-16]:5 TARGET[25:21]:5 TARGET[15:0]:16
153                  *
154                  * ......TARGET[15:0].................TARGET[20:16]...........
155                  * ......TARGET[25:21]
156                  */
157                 epc |=
158                     ((fullinst & 0xffff) << 2) | ((fullinst & 0x3e00000) >> 3) |
159                     ((fullinst & 0x1f0000) << 7);
160                 if (!inst.jal.x)
161                         set_isa16_mode(epc);    /* Set ISA mode bit. */
162                 regs->cp0_epc = epc;
163                 return 0;
164
165                 /*
166                  *  J(AL)R(C)
167                  */
168         case MIPS16e_rr_op:
169                 if (inst.rr.func == MIPS16e_jr_func) {
170
171                         if (inst.rr.ra)
172                                 regs->cp0_epc = regs->regs[31];
173                         else
174                                 regs->cp0_epc =
175                                     regs->regs[reg16to32[inst.rr.rx]];
176
177                         if (inst.rr.l) {
178                                 if (inst.rr.nd)
179                                         regs->regs[31] = epc + 2;
180                                 else
181                                         regs->regs[31] = epc + 4;
182                         }
183                         return 0;
184                 }
185                 break;
186         }
187
188         /*
189          * All other cases have no branch delay slot and are 16-bits.
190          * Branches do not cause an exception.
191          */
192         regs->cp0_epc += 2;
193
194         return 0;
195 }
196
197 /**
198  * __compute_return_epc_for_insn - Computes the return address and do emulate
199  *                                  branch simulation, if required.
200  *
201  * @regs:       Pointer to pt_regs
202  * @insn:       branch instruction to decode
203  * @returns:    -EFAULT on error and forces SIGBUS, and on success
204  *              returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
205  *              evaluating the branch.
206  */
207 int __compute_return_epc_for_insn(struct pt_regs *regs,
208                                    union mips_instruction insn)
209 {
210         unsigned int bit, fcr31, dspcontrol;
211         long epc = regs->cp0_epc;
212         int ret = 0;
213
214         switch (insn.i_format.opcode) {
215         /*
216          * jr and jalr are in r_format format.
217          */
218         case spec_op:
219                 switch (insn.r_format.func) {
220                 case jalr_op:
221                         regs->regs[insn.r_format.rd] = epc + 8;
222                         /* Fall through */
223                 case jr_op:
224                         regs->cp0_epc = regs->regs[insn.r_format.rs];
225                         break;
226                 }
227                 break;
228
229         /*
230          * This group contains:
231          * bltz_op, bgez_op, bltzl_op, bgezl_op,
232          * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
233          */
234         case bcond_op:
235                 switch (insn.i_format.rt) {
236                 case bltz_op:
237                 case bltzl_op:
238                         if ((long)regs->regs[insn.i_format.rs] < 0) {
239                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
240                                 if (insn.i_format.rt == bltzl_op)
241                                         ret = BRANCH_LIKELY_TAKEN;
242                         } else
243                                 epc += 8;
244                         regs->cp0_epc = epc;
245                         break;
246
247                 case bgez_op:
248                 case bgezl_op:
249                         if ((long)regs->regs[insn.i_format.rs] >= 0) {
250                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
251                                 if (insn.i_format.rt == bgezl_op)
252                                         ret = BRANCH_LIKELY_TAKEN;
253                         } else
254                                 epc += 8;
255                         regs->cp0_epc = epc;
256                         break;
257
258                 case bltzal_op:
259                 case bltzall_op:
260                         regs->regs[31] = epc + 8;
261                         if ((long)regs->regs[insn.i_format.rs] < 0) {
262                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
263                                 if (insn.i_format.rt == bltzall_op)
264                                         ret = BRANCH_LIKELY_TAKEN;
265                         } else
266                                 epc += 8;
267                         regs->cp0_epc = epc;
268                         break;
269
270                 case bgezal_op:
271                 case bgezall_op:
272                         regs->regs[31] = epc + 8;
273                         if ((long)regs->regs[insn.i_format.rs] >= 0) {
274                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
275                                 if (insn.i_format.rt == bgezall_op)
276                                         ret = BRANCH_LIKELY_TAKEN;
277                         } else
278                                 epc += 8;
279                         regs->cp0_epc = epc;
280                         break;
281
282                 case bposge32_op:
283                         if (!cpu_has_dsp)
284                                 goto sigill;
285
286                         dspcontrol = rddsp(0x01);
287
288                         if (dspcontrol >= 32) {
289                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
290                         } else
291                                 epc += 8;
292                         regs->cp0_epc = epc;
293                         break;
294                 }
295                 break;
296
297         /*
298          * These are unconditional and in j_format.
299          */
300         case jal_op:
301                 regs->regs[31] = regs->cp0_epc + 8;
302         case j_op:
303                 epc += 4;
304                 epc >>= 28;
305                 epc <<= 28;
306                 epc |= (insn.j_format.target << 2);
307                 regs->cp0_epc = epc;
308                 if (insn.i_format.opcode == jalx_op)
309                         set_isa16_mode(regs->cp0_epc);
310                 break;
311
312         /*
313          * These are conditional and in i_format.
314          */
315         case beq_op:
316         case beql_op:
317                 if (regs->regs[insn.i_format.rs] ==
318                     regs->regs[insn.i_format.rt]) {
319                         epc = epc + 4 + (insn.i_format.simmediate << 2);
320                         if (insn.i_format.rt == beql_op)
321                                 ret = BRANCH_LIKELY_TAKEN;
322                 } else
323                         epc += 8;
324                 regs->cp0_epc = epc;
325                 break;
326
327         case bne_op:
328         case bnel_op:
329                 if (regs->regs[insn.i_format.rs] !=
330                     regs->regs[insn.i_format.rt]) {
331                         epc = epc + 4 + (insn.i_format.simmediate << 2);
332                         if (insn.i_format.rt == bnel_op)
333                                 ret = BRANCH_LIKELY_TAKEN;
334                 } else
335                         epc += 8;
336                 regs->cp0_epc = epc;
337                 break;
338
339         case blez_op: /* not really i_format */
340         case blezl_op:
341                 /* rt field assumed to be zero */
342                 if ((long)regs->regs[insn.i_format.rs] <= 0) {
343                         epc = epc + 4 + (insn.i_format.simmediate << 2);
344                         if (insn.i_format.rt == bnel_op)
345                                 ret = BRANCH_LIKELY_TAKEN;
346                 } else
347                         epc += 8;
348                 regs->cp0_epc = epc;
349                 break;
350
351         case bgtz_op:
352         case bgtzl_op:
353                 /* rt field assumed to be zero */
354                 if ((long)regs->regs[insn.i_format.rs] > 0) {
355                         epc = epc + 4 + (insn.i_format.simmediate << 2);
356                         if (insn.i_format.rt == bnel_op)
357                                 ret = BRANCH_LIKELY_TAKEN;
358                 } else
359                         epc += 8;
360                 regs->cp0_epc = epc;
361                 break;
362
363         /*
364          * And now the FPA/cp1 branch instructions.
365          */
366         case cop1_op:
367                 preempt_disable();
368                 if (is_fpu_owner())
369                         asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
370                 else
371                         fcr31 = current->thread.fpu.fcr31;
372                 preempt_enable();
373
374                 bit = (insn.i_format.rt >> 2);
375                 bit += (bit != 0);
376                 bit += 23;
377                 switch (insn.i_format.rt & 3) {
378                 case 0: /* bc1f */
379                 case 2: /* bc1fl */
380                         if (~fcr31 & (1 << bit)) {
381                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
382                                 if (insn.i_format.rt == 2)
383                                         ret = BRANCH_LIKELY_TAKEN;
384                         } else
385                                 epc += 8;
386                         regs->cp0_epc = epc;
387                         break;
388
389                 case 1: /* bc1t */
390                 case 3: /* bc1tl */
391                         if (fcr31 & (1 << bit)) {
392                                 epc = epc + 4 + (insn.i_format.simmediate << 2);
393                                 if (insn.i_format.rt == 3)
394                                         ret = BRANCH_LIKELY_TAKEN;
395                         } else
396                                 epc += 8;
397                         regs->cp0_epc = epc;
398                         break;
399                 }
400                 break;
401 #ifdef CONFIG_CPU_CAVIUM_OCTEON
402         case lwc2_op: /* This is bbit0 on Octeon */
403                 if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
404                      == 0)
405                         epc = epc + 4 + (insn.i_format.simmediate << 2);
406                 else
407                         epc += 8;
408                 regs->cp0_epc = epc;
409                 break;
410         case ldc2_op: /* This is bbit032 on Octeon */
411                 if ((regs->regs[insn.i_format.rs] &
412                     (1ull<<(insn.i_format.rt+32))) == 0)
413                         epc = epc + 4 + (insn.i_format.simmediate << 2);
414                 else
415                         epc += 8;
416                 regs->cp0_epc = epc;
417                 break;
418         case swc2_op: /* This is bbit1 on Octeon */
419                 if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
420                         epc = epc + 4 + (insn.i_format.simmediate << 2);
421                 else
422                         epc += 8;
423                 regs->cp0_epc = epc;
424                 break;
425         case sdc2_op: /* This is bbit132 on Octeon */
426                 if (regs->regs[insn.i_format.rs] &
427                     (1ull<<(insn.i_format.rt+32)))
428                         epc = epc + 4 + (insn.i_format.simmediate << 2);
429                 else
430                         epc += 8;
431                 regs->cp0_epc = epc;
432                 break;
433 #endif
434         }
435
436         return ret;
437
438 sigill:
439         printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
440         force_sig(SIGBUS, current);
441         return -EFAULT;
442 }
443 EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
444
445 int __compute_return_epc(struct pt_regs *regs)
446 {
447         unsigned int __user *addr;
448         long epc;
449         union mips_instruction insn;
450
451         epc = regs->cp0_epc;
452         if (epc & 3)
453                 goto unaligned;
454
455         /*
456          * Read the instruction
457          */
458         addr = (unsigned int __user *) epc;
459         if (__get_user(insn.word, addr)) {
460                 force_sig(SIGSEGV, current);
461                 return -EFAULT;
462         }
463
464         return __compute_return_epc_for_insn(regs, insn);
465
466 unaligned:
467         printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
468         force_sig(SIGBUS, current);
469         return -EFAULT;
470 }