From 19ede2f53b78472c3bc3536f00609d22253a7d52 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Mon, 7 Oct 2019 14:01:22 +0000 Subject: [PATCH] [Mips] Fix evaluating J-format branch targets J/JAL/JALX/JALS are absolute branches, but stay within the current 256 MB-aligned region, so we must include the high bits of the instruction address when calculating the branch target. Patch by James Clarke. Differential Revision: https://reviews.llvm.org/D68548 llvm-svn: 373906 --- llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 11 +++++++---- llvm/test/MC/Mips/micromips-jump-pc-region.s | 17 +++++++++++++++++ llvm/test/MC/Mips/mips-jump-pc-region.s | 17 +++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 llvm/test/MC/Mips/micromips-jump-pc-region.s create mode 100644 llvm/test/MC/Mips/mips-jump-pc-region.s diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index ddeec03..79c47d1 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -143,12 +143,15 @@ public: return false; switch (Info->get(Inst.getOpcode()).OpInfo[NumOps - 1].OperandType) { case MCOI::OPERAND_UNKNOWN: - case MCOI::OPERAND_IMMEDIATE: - // jal, bal ... - Target = Inst.getOperand(NumOps - 1).getImm(); + case MCOI::OPERAND_IMMEDIATE: { + // j, jal, jalx, jals + // Absolute branch within the current 256 MB-aligned region + uint64_t Region = Addr & ~uint64_t(0xfffffff); + Target = Region + Inst.getOperand(NumOps - 1).getImm(); return true; + } case MCOI::OPERAND_PCREL: - // b, j, beq ... + // b, beq ... Target = Addr + Inst.getOperand(NumOps - 1).getImm(); return true; default: diff --git a/llvm/test/MC/Mips/micromips-jump-pc-region.s b/llvm/test/MC/Mips/micromips-jump-pc-region.s new file mode 100644 index 0000000..5f598fc --- /dev/null +++ b/llvm/test/MC/Mips/micromips-jump-pc-region.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc -triple=mips -mcpu=mips32 -mattr=+micromips -filetype=obj < %s \ +# RUN: | llvm-objdump -d - | FileCheck %s + +.set noreorder + +# Force us into the second 256 MB region with a non-zero instruction index +.org 256*1024*1024 + 12 +# CHECK-LABEL: 1000000c foo: +# CHECK-NEXT: 1000000c: d4 00 00 06 j 12 +# CHECK-NEXT: 10000010: f4 00 00 08 jal 16 +# CHECK-NEXT: 10000014: f0 00 00 05 jalx 20 +# CHECK-NEXT: 10000018: 74 00 00 0c jals 24 +foo: + j 12 + jal 16 + jalx 20 + jals 24 diff --git a/llvm/test/MC/Mips/mips-jump-pc-region.s b/llvm/test/MC/Mips/mips-jump-pc-region.s new file mode 100644 index 0000000..2d6bbce --- /dev/null +++ b/llvm/test/MC/Mips/mips-jump-pc-region.s @@ -0,0 +1,17 @@ +# RUN: llvm-mc -triple=mips -mcpu=mips32 -filetype=obj < %s \ +# RUN: | llvm-objdump -d - | FileCheck %s +# RUN: llvm-mc -triple=mips64 -mcpu=mips64 -filetype=obj < %s \ +# RUN: | llvm-objdump -d - | FileCheck %s + +.set noreorder + +# Force us into the second 256 MB region with a non-zero instruction index +.org 256*1024*1024 + 12 +# CHECK-LABEL: 1000000c foo: +# CHECK-NEXT: 1000000c: 08 00 00 03 j 12 +# CHECK-NEXT: 10000010: 0c 00 00 04 jal 16 +# CHECK-NEXT: 10000014: 74 00 00 05 jalx 20 +foo: + j 12 + jal 16 + jalx 20 -- 2.7.4