branch.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 <asm/branch.h>
  13. #include <asm/cpu.h>
  14. #include <asm/cpu-features.h>
  15. #include <asm/fpu.h>
  16. #include <asm/inst.h>
  17. #include <asm/ptrace.h>
  18. #include <asm/uaccess.h>
  19. /*
  20. * Compute the return address and do emulate branch simulation, if required.
  21. */
  22. int __compute_return_epc(struct pt_regs *regs)
  23. {
  24. unsigned int __user *addr;
  25. unsigned int bit, fcr31, dspcontrol;
  26. long epc;
  27. union mips_instruction insn;
  28. epc = regs->cp0_epc;
  29. if (epc & 3)
  30. goto unaligned;
  31. /*
  32. * Read the instruction
  33. */
  34. addr = (unsigned int __user *) epc;
  35. if (__get_user(insn.word, addr)) {
  36. force_sig(SIGSEGV, current);
  37. return -EFAULT;
  38. }
  39. regs->regs[0] = 0;
  40. switch (insn.i_format.opcode) {
  41. /*
  42. * jr and jalr are in r_format format.
  43. */
  44. case spec_op:
  45. switch (insn.r_format.func) {
  46. case jalr_op:
  47. regs->regs[insn.r_format.rd] = epc + 8;
  48. /* Fall through */
  49. case jr_op:
  50. regs->cp0_epc = regs->regs[insn.r_format.rs];
  51. break;
  52. }
  53. break;
  54. /*
  55. * This group contains:
  56. * bltz_op, bgez_op, bltzl_op, bgezl_op,
  57. * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
  58. */
  59. case bcond_op:
  60. switch (insn.i_format.rt) {
  61. case bltz_op:
  62. case bltzl_op:
  63. if ((long)regs->regs[insn.i_format.rs] < 0)
  64. epc = epc + 4 + (insn.i_format.simmediate << 2);
  65. else
  66. epc += 8;
  67. regs->cp0_epc = epc;
  68. break;
  69. case bgez_op:
  70. case bgezl_op:
  71. if ((long)regs->regs[insn.i_format.rs] >= 0)
  72. epc = epc + 4 + (insn.i_format.simmediate << 2);
  73. else
  74. epc += 8;
  75. regs->cp0_epc = epc;
  76. break;
  77. case bltzal_op:
  78. case bltzall_op:
  79. regs->regs[31] = epc + 8;
  80. if ((long)regs->regs[insn.i_format.rs] < 0)
  81. epc = epc + 4 + (insn.i_format.simmediate << 2);
  82. else
  83. epc += 8;
  84. regs->cp0_epc = epc;
  85. break;
  86. case bgezal_op:
  87. case bgezall_op:
  88. regs->regs[31] = epc + 8;
  89. if ((long)regs->regs[insn.i_format.rs] >= 0)
  90. epc = epc + 4 + (insn.i_format.simmediate << 2);
  91. else
  92. epc += 8;
  93. regs->cp0_epc = epc;
  94. break;
  95. case bposge32_op:
  96. if (!cpu_has_dsp)
  97. goto sigill;
  98. dspcontrol = rddsp(0x01);
  99. if (dspcontrol >= 32) {
  100. epc = epc + 4 + (insn.i_format.simmediate << 2);
  101. } else
  102. epc += 8;
  103. regs->cp0_epc = epc;
  104. break;
  105. }
  106. break;
  107. /*
  108. * These are unconditional and in j_format.
  109. */
  110. case jal_op:
  111. regs->regs[31] = regs->cp0_epc + 8;
  112. case j_op:
  113. epc += 4;
  114. epc >>= 28;
  115. epc <<= 28;
  116. epc |= (insn.j_format.target << 2);
  117. regs->cp0_epc = epc;
  118. break;
  119. /*
  120. * These are conditional and in i_format.
  121. */
  122. case beq_op:
  123. case beql_op:
  124. if (regs->regs[insn.i_format.rs] ==
  125. regs->regs[insn.i_format.rt])
  126. epc = epc + 4 + (insn.i_format.simmediate << 2);
  127. else
  128. epc += 8;
  129. regs->cp0_epc = epc;
  130. break;
  131. case bne_op:
  132. case bnel_op:
  133. if (regs->regs[insn.i_format.rs] !=
  134. regs->regs[insn.i_format.rt])
  135. epc = epc + 4 + (insn.i_format.simmediate << 2);
  136. else
  137. epc += 8;
  138. regs->cp0_epc = epc;
  139. break;
  140. case blez_op: /* not really i_format */
  141. case blezl_op:
  142. /* rt field assumed to be zero */
  143. if ((long)regs->regs[insn.i_format.rs] <= 0)
  144. epc = epc + 4 + (insn.i_format.simmediate << 2);
  145. else
  146. epc += 8;
  147. regs->cp0_epc = epc;
  148. break;
  149. case bgtz_op:
  150. case bgtzl_op:
  151. /* rt field assumed to be zero */
  152. if ((long)regs->regs[insn.i_format.rs] > 0)
  153. epc = epc + 4 + (insn.i_format.simmediate << 2);
  154. else
  155. epc += 8;
  156. regs->cp0_epc = epc;
  157. break;
  158. /*
  159. * And now the FPA/cp1 branch instructions.
  160. */
  161. case cop1_op:
  162. preempt_disable();
  163. if (is_fpu_owner())
  164. asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
  165. else
  166. fcr31 = current->thread.fpu.fcr31;
  167. preempt_enable();
  168. bit = (insn.i_format.rt >> 2);
  169. bit += (bit != 0);
  170. bit += 23;
  171. switch (insn.i_format.rt & 3) {
  172. case 0: /* bc1f */
  173. case 2: /* bc1fl */
  174. if (~fcr31 & (1 << bit))
  175. epc = epc + 4 + (insn.i_format.simmediate << 2);
  176. else
  177. epc += 8;
  178. regs->cp0_epc = epc;
  179. break;
  180. case 1: /* bc1t */
  181. case 3: /* bc1tl */
  182. if (fcr31 & (1 << bit))
  183. epc = epc + 4 + (insn.i_format.simmediate << 2);
  184. else
  185. epc += 8;
  186. regs->cp0_epc = epc;
  187. break;
  188. }
  189. break;
  190. #ifdef CONFIG_CPU_CAVIUM_OCTEON
  191. case lwc2_op: /* This is bbit0 on Octeon */
  192. if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
  193. == 0)
  194. epc = epc + 4 + (insn.i_format.simmediate << 2);
  195. else
  196. epc += 8;
  197. regs->cp0_epc = epc;
  198. break;
  199. case ldc2_op: /* This is bbit032 on Octeon */
  200. if ((regs->regs[insn.i_format.rs] &
  201. (1ull<<(insn.i_format.rt+32))) == 0)
  202. epc = epc + 4 + (insn.i_format.simmediate << 2);
  203. else
  204. epc += 8;
  205. regs->cp0_epc = epc;
  206. break;
  207. case swc2_op: /* This is bbit1 on Octeon */
  208. if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
  209. epc = epc + 4 + (insn.i_format.simmediate << 2);
  210. else
  211. epc += 8;
  212. regs->cp0_epc = epc;
  213. break;
  214. case sdc2_op: /* This is bbit132 on Octeon */
  215. if (regs->regs[insn.i_format.rs] &
  216. (1ull<<(insn.i_format.rt+32)))
  217. epc = epc + 4 + (insn.i_format.simmediate << 2);
  218. else
  219. epc += 8;
  220. regs->cp0_epc = epc;
  221. break;
  222. #endif
  223. }
  224. return 0;
  225. unaligned:
  226. printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
  227. force_sig(SIGBUS, current);
  228. return -EFAULT;
  229. sigill:
  230. printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
  231. force_sig(SIGBUS, current);
  232. return -EFAULT;
  233. }