mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-25 21:11:25 +00:00
[AVR] Fix incorrect decoding of conditional branch instructions
This patch fixes the inaccurate decoding of the offset operand of the conditional branch instructions. Reviewed By: aykevl Differential Revision: https://reviews.llvm.org/D140816
This commit is contained in:
parent
54971c8a39
commit
4d9969ebe3
@ -432,6 +432,8 @@ class FBRsk<bit f, bits<3> s, dag outs, dag ins, string asmstr,
|
||||
let Inst{10} = f;
|
||||
let Inst{9 - 3} = k;
|
||||
let Inst{2 - 0} = s;
|
||||
|
||||
let DecoderMethod = "decodeCondBranch";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -561,6 +563,8 @@ class FSK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
|
||||
let Inst{3} = k{0};
|
||||
let Inst{2 - 0} = s;
|
||||
|
||||
let DecoderMethod = "decodeCondBranch";
|
||||
}
|
||||
|
||||
class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "MCTargetDesc/AVRMCTargetDesc.h"
|
||||
#include "TargetInfo/AVRTargetInfo.h"
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDecoderOps.h"
|
||||
@ -126,6 +129,10 @@ static DecodeStatus decodeMemri(MCInst &Inst, unsigned Insn, uint64_t Address,
|
||||
static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address,
|
||||
const MCDisassembler *Decoder);
|
||||
|
||||
static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
|
||||
uint64_t Address,
|
||||
const MCDisassembler *Decoder);
|
||||
|
||||
static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
|
||||
uint64_t Address,
|
||||
const MCDisassembler *Decoder);
|
||||
@ -287,6 +294,40 @@ static DecodeStatus decodeFBRk(MCInst &Inst, unsigned Insn, uint64_t Address,
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeCondBranch(MCInst &Inst, unsigned Insn,
|
||||
uint64_t Address,
|
||||
const MCDisassembler *Decoder) {
|
||||
// These 8 instructions are not defined as aliases of BRBS/BRBC.
|
||||
DenseMap<unsigned, unsigned> brInsts = {
|
||||
{0x000, AVR::BRLOk}, {0x400, AVR::BRSHk}, {0x001, AVR::BREQk},
|
||||
{0x401, AVR::BRNEk}, {0x002, AVR::BRMIk}, {0x402, AVR::BRPLk},
|
||||
{0x004, AVR::BRLTk}, {0x404, AVR::BRGEk}};
|
||||
|
||||
// Get the relative offset.
|
||||
int16_t Offset = ((int16_t)((Insn & 0x3f8) << 6)) >> 8;
|
||||
|
||||
// Search the instruction pattern.
|
||||
auto NotAlias = [&Insn](const std::pair<unsigned, unsigned> &I) {
|
||||
return (Insn & 0x407) != I.first;
|
||||
};
|
||||
llvm::partition(brInsts, NotAlias);
|
||||
auto It = llvm::partition_point(brInsts, NotAlias);
|
||||
|
||||
// Decode the instruction.
|
||||
if (It != brInsts.end()) {
|
||||
// This instruction is not an alias of BRBC/BRBS.
|
||||
Inst.setOpcode(It->second);
|
||||
Inst.addOperand(MCOperand::createImm(Offset));
|
||||
} else {
|
||||
// Fall back to an ordinary BRBS/BRBC.
|
||||
Inst.setOpcode(Insn & 0x400 ? AVR::BRBCsk : AVR::BRBSsk);
|
||||
Inst.addOperand(MCOperand::createImm(Insn & 7));
|
||||
Inst.addOperand(MCOperand::createImm(Offset));
|
||||
}
|
||||
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeLoadStore(MCInst &Inst, unsigned Insn,
|
||||
uint64_t Address,
|
||||
const MCDisassembler *Decoder) {
|
||||
|
@ -1,12 +1,24 @@
|
||||
; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
|
||||
|
||||
; RUN: llvm-mc -filetype=obj -triple avr < %s \
|
||||
; RUN: | llvm-objdump -d - | FileCheck --check-prefix=INST %s
|
||||
|
||||
foo:
|
||||
|
||||
brbc 3, .+8
|
||||
brbc 0, .-16
|
||||
.short 0xf759
|
||||
.short 0xf752
|
||||
.short 0xf74c
|
||||
.short 0xf4c7
|
||||
|
||||
; CHECK: brvc .Ltmp0+8 ; encoding: [0bAAAAA011,0b111101AA]
|
||||
; CHECK: ; fixup A - offset: 0, value: .Ltmp0+8, kind: fixup_7_pcrel
|
||||
; CHECK: brcc .Ltmp1-16 ; encoding: [0bAAAAA000,0b111101AA]
|
||||
; CHECK: ; fixup A - offset: 0, value: .Ltmp1-16, kind: fixup_7_pcrel
|
||||
|
||||
; INST: brvc .+0
|
||||
; INST: brsh .+0
|
||||
; INST: brne .-42
|
||||
; INST: brpl .-44
|
||||
; INST: brge .-46
|
||||
; INST: brid .+48
|
||||
|
@ -1,12 +1,24 @@
|
||||
; RUN: llvm-mc -triple avr -show-encoding < %s | FileCheck %s
|
||||
|
||||
; RUN: llvm-mc -filetype=obj -triple avr < %s \
|
||||
; RUN: | llvm-objdump -d - | FileCheck --check-prefix=INST %s
|
||||
|
||||
foo:
|
||||
|
||||
brbs 3, .+8
|
||||
brbs 0, .-12
|
||||
.short 0xf359
|
||||
.short 0xf352
|
||||
.short 0xf34c
|
||||
.short 0xf077
|
||||
|
||||
; CHECK: brvs .Ltmp0+8 ; encoding: [0bAAAAA011,0b111100AA]
|
||||
; CHECK: ; fixup A - offset: 0, value: .Ltmp0+8, kind: fixup_7_pcrel
|
||||
; CHECK: brcs .Ltmp1-12 ; encoding: [0bAAAAA000,0b111100AA]
|
||||
; CHECK: ; fixup A - offset: 0, value: .Ltmp1-12, kind: fixup_7_pcrel
|
||||
|
||||
; INST: brvs .+0
|
||||
; INST: brlo .+0
|
||||
; INST: breq .-42
|
||||
; INST brmi .-44
|
||||
; INST brlt .-46
|
||||
; InST: brie .+28
|
||||
|
Loading…
x
Reference in New Issue
Block a user