branch.c 6.7 KB

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