hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/mips/kernel/jump_label.c
....@@ -40,18 +40,38 @@
4040 {
4141 union mips_instruction *insn_p;
4242 union mips_instruction insn;
43
+ long offset;
4344
4445 insn_p = (union mips_instruction *)msk_isa16_mode(e->code);
45
-
46
- /* Jump only works within an aligned region its delay slot is in. */
47
- BUG_ON((e->target & ~J_RANGE_MASK) != ((e->code + 4) & ~J_RANGE_MASK));
4846
4947 /* Target must have the right alignment and ISA must be preserved. */
5048 BUG_ON((e->target & J_ALIGN_MASK) != J_ISA_BIT);
5149
5250 if (type == JUMP_LABEL_JMP) {
53
- insn.j_format.opcode = J_ISA_BIT ? mm_j32_op : j_op;
54
- insn.j_format.target = e->target >> J_RANGE_SHIFT;
51
+ if (!IS_ENABLED(CONFIG_CPU_MICROMIPS) && MIPS_ISA_REV >= 6) {
52
+ offset = e->target - ((unsigned long)insn_p + 4);
53
+ offset >>= 2;
54
+
55
+ /*
56
+ * The branch offset must fit in the instruction's 26
57
+ * bit field.
58
+ */
59
+ WARN_ON((offset >= (long)BIT(25)) ||
60
+ (offset < -(long)BIT(25)));
61
+
62
+ insn.j_format.opcode = bc6_op;
63
+ insn.j_format.target = offset;
64
+ } else {
65
+ /*
66
+ * Jump only works within an aligned region its delay
67
+ * slot is in.
68
+ */
69
+ WARN_ON((e->target & ~J_RANGE_MASK) !=
70
+ ((e->code + 4) & ~J_RANGE_MASK));
71
+
72
+ insn.j_format.opcode = J_ISA_BIT ? mm_j32_op : j_op;
73
+ insn.j_format.target = e->target >> J_RANGE_SHIFT;
74
+ }
5575 } else {
5676 insn.word = 0; /* nop */
5777 }