summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>2015-11-30 12:56:18 +0000
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>2015-11-30 12:56:18 +0000
commita887b36167922a8821dc229011336a36409409da (patch)
tree658085df90a803892cfe850e1abbc81ffdcd7f68 /llvm
parentea7932cfb7e352360ba9408dfe87e1e1527b22f1 (diff)
downloadbcm5719-llvm-a887b36167922a8821dc229011336a36409409da.tar.gz
bcm5719-llvm-a887b36167922a8821dc229011336a36409409da.zip
[mips][microMIPS] Fix issue with offset operand of BALC and BC instructions
Value of offset operand for microMIPS BALC and BC instructions is currently shifted 2 bits, but it should be 1 bit. Differential Revision: http://reviews.llvm.org/D14770 llvm-svn: 254296
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp17
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp17
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h7
-rw-r--r--llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td11
-rw-r--r--llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt4
-rw-r--r--llvm/test/MC/Mips/micromips32r6/valid.s4
6 files changed, 54 insertions, 6 deletions
diff --git a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
index f9601839b44..716a96e2c46 100644
--- a/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
+++ b/llvm/lib/Target/Mips/Disassembler/MipsDisassembler.cpp
@@ -229,6 +229,13 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
uint64_t Address,
const void *Decoder);
+// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is
+// shifted left by 1 bit.
+static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
+ unsigned Offset,
+ uint64_t Address,
+ const void *Decoder);
+
// DecodeJumpTargetMM - Decode microMIPS jump target, which is
// shifted left by 1 bit.
static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
@@ -1863,6 +1870,16 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
return MCDisassembler::Success;
}
+static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst,
+ unsigned Offset,
+ uint64_t Address,
+ const void *Decoder) {
+ int32_t BranchOffset = SignExtend32<26>(Offset) << 1;
+
+ Inst.addOperand(MCOperand::createImm(BranchOffset));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
unsigned Insn,
uint64_t Address,
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index 86a5d588218..ed917a4daba 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -350,6 +350,23 @@ getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
return 0;
}
+/// getBranchTarget26OpValueMM - Return binary encoding of the branch
+/// target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
+ const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ const MCOperand &MO = MI.getOperand(OpNo);
+
+ // If the destination is an immediate, divide by 2.
+ if (MO.isImm())
+ return MO.getImm() >> 1;
+
+ // TODO: Push 26 PC fixup.
+ return 0;
+}
+
/// getJumpOffset16OpValue - Return binary encoding of the jump
/// target operand. If the machine operand requires relocation,
/// record the relocation and return zero.
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index c2f4b6a72bb..eb48914b064 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -137,6 +137,13 @@ public:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ // getBranchTarget26OpValueMM - Return binary encoding of the branch
+ // offset operand. If the machine operand requires relocation,
+ // record the relocation and return zero.
+ unsigned getBranchTarget26OpValueMM(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
// getJumpOffset16OpValue - Return binary encoding of the jump
// offset operand. If the machine operand requires relocation,
// record the relocation and return zero.
diff --git a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
index cabaa53b2b1..2dbd20cfad9 100644
--- a/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
+++ b/llvm/lib/Target/Mips/MicroMips32r6InstrInfo.td
@@ -11,6 +11,13 @@
//
//===----------------------------------------------------------------------===//
+def brtarget26_mm : Operand<OtherVT> {
+ let EncoderMethod = "getBranchTarget26OpValueMM";
+ let OperandType = "OPERAND_PCREL";
+ let DecoderMethod = "DecodeBranchTarget26MM";
+ let ParserMatchClass = MipsJumpTargetAsmOperand;
+}
+
//===----------------------------------------------------------------------===//
//
// Instruction Encodings
@@ -238,11 +245,11 @@ class BC_MMR6_DESC_BASE<string instr_asm, DAGOperand opnd>
bit isBarrier = 1;
}
-class BALC_MMR6_DESC : BC_MMR6_DESC_BASE<"balc", brtarget26> {
+class BALC_MMR6_DESC : BC_MMR6_DESC_BASE<"balc", brtarget26_mm> {
bit isCall = 1;
list<Register> Defs = [RA];
}
-class BC_MMR6_DESC : BC_MMR6_DESC_BASE<"bc", brtarget26>;
+class BC_MMR6_DESC : BC_MMR6_DESC_BASE<"bc", brtarget26_mm>;
class BC16_MMR6_DESC : MicroMipsInst16<(outs), (ins brtarget10_mm:$offset),
!strconcat("bc16", "\t$offset"), [],
diff --git a/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt b/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt
index 619ce3faeda..82c5d50df92 100644
--- a/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt
+++ b/llvm/test/MC/Disassembler/Mips/micromips32r6/valid.txt
@@ -44,8 +44,8 @@
0xe0 0x40 0x02 0x9a # CHECK: bgtzalc $2, 1332
0xe0 0x42 0x02 0x9a # CHECK: bltzalc $2, 1332
0xc0 0x40 0x02 0x9a # CHECK: blezalc $2, 1332
-0xb4 0x37 0x96 0xb8 # CHECK: balc 14572256
-0x94 0x37 0x96 0xb8 # CHECK: bc 14572256
+0xb4 0x37 0x96 0xb8 # CHECK: balc 7286128
+0x94 0x37 0x96 0xb8 # CHECK: bc 7286128
0x00 0x44 0x0b 0x3c # CHECK: bitswap $4, $2
0x00 0x00 0x00 0x07 # CHECK: break
0x00 0x07 0x00 0x07 # CHECK: break 7
diff --git a/llvm/test/MC/Mips/micromips32r6/valid.s b/llvm/test/MC/Mips/micromips32r6/valid.s
index b2bce840765..81d4b6c6d45 100644
--- a/llvm/test/MC/Mips/micromips32r6/valid.s
+++ b/llvm/test/MC/Mips/micromips32r6/valid.s
@@ -26,9 +26,9 @@
bgtzalc $2, 1332 # CHECK: bgtzalc $2, 1332 # encoding: [0xe0,0x40,0x02,0x9a]
bltzalc $2, 1332 # CHECK: bltzalc $2, 1332 # encoding: [0xe0,0x42,0x02,0x9a]
blezalc $2, 1332 # CHECK: blezalc $2, 1332 # encoding: [0xc0,0x40,0x02,0x9a]
- balc 14572256 # CHECK: balc 14572256 # encoding: [0xb4,0x37,0x96,0xb8]
+ balc 7286128 # CHECK: balc 7286128 # encoding: [0xb4,0x37,0x96,0xb8]
b 132 # CHECK: bc16 132 # encoding: [0xcc,0x42]
- bc 14572256 # CHECK: bc 14572256 # encoding: [0x94,0x37,0x96,0xb8]
+ bc 7286128 # CHECK: bc 7286128 # encoding: [0x94,0x37,0x96,0xb8]
bc16 132 # CHECK: bc16 132 # encoding: [0xcc,0x42]
beqzc16 $6, 20 # CHECK: beqzc16 $6, 20 # encoding: [0x8f,0x0a]
bnezc16 $6, 20 # CHECK: bnezc16 $6, 20 # encoding: [0xaf,0x0a]
OpenPOWER on IntegriCloud