mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-03 01:06:05 +00:00
Thumb2 assembly parsing and encoding for TBB/TBH.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140078 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
463158fdb8
commit
7f739bee26
@ -203,6 +203,20 @@ def t2addrmode_so_reg : Operand<i32>,
|
|||||||
let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
|
let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Addresses for the TBB/TBH instructions.
|
||||||
|
def addrmode_tbb_asmoperand : AsmOperandClass { let Name = "MemTBB"; }
|
||||||
|
def addrmode_tbb : Operand<i32> {
|
||||||
|
let PrintMethod = "printAddrModeTBB";
|
||||||
|
let ParserMatchClass = addrmode_tbb_asmoperand;
|
||||||
|
let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm);
|
||||||
|
}
|
||||||
|
def addrmode_tbh_asmoperand : AsmOperandClass { let Name = "MemTBH"; }
|
||||||
|
def addrmode_tbh : Operand<i32> {
|
||||||
|
let PrintMethod = "printAddrModeTBH";
|
||||||
|
let ParserMatchClass = addrmode_tbh_asmoperand;
|
||||||
|
let MIOperandInfo = (ops GPR:$Rn, rGPR:$Rm);
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Multiclass helpers...
|
// Multiclass helpers...
|
||||||
//
|
//
|
||||||
@ -3135,8 +3149,8 @@ def t2TBB_JT : t2PseudoInst<(outs),
|
|||||||
def t2TBH_JT : t2PseudoInst<(outs),
|
def t2TBH_JT : t2PseudoInst<(outs),
|
||||||
(ins GPR:$index, i32imm:$jt, i32imm:$id), 0, IIC_Br, []>;
|
(ins GPR:$index, i32imm:$jt, i32imm:$id), 0, IIC_Br, []>;
|
||||||
|
|
||||||
def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
|
def t2TBB : T2I<(outs), (ins addrmode_tbb:$addr), IIC_Br,
|
||||||
"tbb", "\t[$Rn, $Rm]", []> {
|
"tbb", "\t$addr", []> {
|
||||||
bits<4> Rn;
|
bits<4> Rn;
|
||||||
bits<4> Rm;
|
bits<4> Rm;
|
||||||
let Inst{31-20} = 0b111010001101;
|
let Inst{31-20} = 0b111010001101;
|
||||||
@ -3144,10 +3158,12 @@ def t2TBB : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
|
|||||||
let Inst{15-5} = 0b11110000000;
|
let Inst{15-5} = 0b11110000000;
|
||||||
let Inst{4} = 0; // B form
|
let Inst{4} = 0; // B form
|
||||||
let Inst{3-0} = Rm;
|
let Inst{3-0} = Rm;
|
||||||
|
|
||||||
|
let DecoderMethod = "DecodeThumbTableBranch";
|
||||||
}
|
}
|
||||||
|
|
||||||
def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
|
def t2TBH : T2I<(outs), (ins addrmode_tbh:$addr), IIC_Br,
|
||||||
"tbh", "\t[$Rn, $Rm, lsl #1]", []> {
|
"tbh", "\t$addr", []> {
|
||||||
bits<4> Rn;
|
bits<4> Rn;
|
||||||
bits<4> Rm;
|
bits<4> Rm;
|
||||||
let Inst{31-20} = 0b111010001101;
|
let Inst{31-20} = 0b111010001101;
|
||||||
@ -3155,6 +3171,8 @@ def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,
|
|||||||
let Inst{15-5} = 0b11110000000;
|
let Inst{15-5} = 0b11110000000;
|
||||||
let Inst{4} = 1; // H form
|
let Inst{4} = 1; // H form
|
||||||
let Inst{3-0} = Rm;
|
let Inst{3-0} = Rm;
|
||||||
|
|
||||||
|
let DecoderMethod = "DecodeThumbTableBranch";
|
||||||
}
|
}
|
||||||
} // isNotDuplicable, isIndirectBranch
|
} // isNotDuplicable, isIndirectBranch
|
||||||
|
|
||||||
|
@ -687,6 +687,18 @@ public:
|
|||||||
return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
|
return (Val >= -1020 && Val <= 1020 && ((Val & 3) == 0)) ||
|
||||||
Val == INT32_MIN;
|
Val == INT32_MIN;
|
||||||
}
|
}
|
||||||
|
bool isMemTBB() const {
|
||||||
|
if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
|
||||||
|
Mem.ShiftType != ARM_AM::no_shift)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool isMemTBH() const {
|
||||||
|
if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative ||
|
||||||
|
Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm != 1)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
bool isMemRegOffset() const {
|
bool isMemRegOffset() const {
|
||||||
if (Kind != Memory || !Mem.OffsetRegNum)
|
if (Kind != Memory || !Mem.OffsetRegNum)
|
||||||
return false;
|
return false;
|
||||||
@ -1205,6 +1217,18 @@ public:
|
|||||||
Inst.addOperand(MCOperand::CreateImm(Val));
|
Inst.addOperand(MCOperand::CreateImm(Val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addMemTBBOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 2 && "Invalid number of operands!");
|
||||||
|
Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
|
||||||
|
Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addMemTBHOperands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 2 && "Invalid number of operands!");
|
||||||
|
Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
|
||||||
|
Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
|
||||||
|
}
|
||||||
|
|
||||||
void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
|
void addMemRegOffsetOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 3 && "Invalid number of operands!");
|
assert(N == 3 && "Invalid number of operands!");
|
||||||
unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
|
unsigned Val = ARM_AM::getAM2Opc(Mem.isNegative ? ARM_AM::sub : ARM_AM::add,
|
||||||
|
@ -287,6 +287,8 @@ static DecodeStatus DecodeThumbBLXOffset(llvm::MCInst &Inst, unsigned Insn,
|
|||||||
uint64_t Address, const void *Decoder);
|
uint64_t Address, const void *Decoder);
|
||||||
static DecodeStatus DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val,
|
static DecodeStatus DecodeT2AddrModeImm12(llvm::MCInst &Inst, unsigned Val,
|
||||||
uint64_t Address, const void *Decoder);
|
uint64_t Address, const void *Decoder);
|
||||||
|
static DecodeStatus DecodeThumbTableBranch(llvm::MCInst &Inst, unsigned Val,
|
||||||
|
uint64_t Address, const void *Decoder);
|
||||||
static DecodeStatus DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Val,
|
static DecodeStatus DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Val,
|
||||||
uint64_t Address, const void *Decoder);
|
uint64_t Address, const void *Decoder);
|
||||||
static DecodeStatus DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val,
|
static DecodeStatus DecodeT2SOImm(llvm::MCInst &Inst, unsigned Val,
|
||||||
@ -2898,6 +2900,22 @@ static DecodeStatus DecodeCoprocessor(llvm::MCInst &Inst, unsigned Val,
|
|||||||
return MCDisassembler::Success;
|
return MCDisassembler::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DecodeStatus
|
||||||
|
DecodeThumbTableBranch(llvm::MCInst &Inst, unsigned Insn,
|
||||||
|
uint64_t Address, const void *Decoder) {
|
||||||
|
DecodeStatus S = MCDisassembler::Success;
|
||||||
|
|
||||||
|
unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
|
||||||
|
unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
|
||||||
|
|
||||||
|
if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
|
||||||
|
if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
|
||||||
|
return MCDisassembler::Fail;
|
||||||
|
if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
|
||||||
|
return MCDisassembler::Fail;
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
static DecodeStatus
|
static DecodeStatus
|
||||||
DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Insn,
|
DecodeThumb2BCCInstruction(llvm::MCInst &Inst, unsigned Insn,
|
||||||
uint64_t Address, const void *Decoder) {
|
uint64_t Address, const void *Decoder) {
|
||||||
|
@ -307,6 +307,22 @@ void ARMInstPrinter::printAM2PostIndexOp(const MCInst *MI, unsigned Op,
|
|||||||
<< " #" << ShImm;
|
<< " #" << ShImm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMInstPrinter::printAddrModeTBB(const MCInst *MI, unsigned Op,
|
||||||
|
raw_ostream &O) {
|
||||||
|
const MCOperand &MO1 = MI->getOperand(Op);
|
||||||
|
const MCOperand &MO2 = MI->getOperand(Op+1);
|
||||||
|
O << "[" << getRegisterName(MO1.getReg()) << ", "
|
||||||
|
<< getRegisterName(MO2.getReg()) << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ARMInstPrinter::printAddrModeTBH(const MCInst *MI, unsigned Op,
|
||||||
|
raw_ostream &O) {
|
||||||
|
const MCOperand &MO1 = MI->getOperand(Op);
|
||||||
|
const MCOperand &MO2 = MI->getOperand(Op+1);
|
||||||
|
O << "[" << getRegisterName(MO1.getReg()) << ", "
|
||||||
|
<< getRegisterName(MO2.getReg()) << ", lsl #1]";
|
||||||
|
}
|
||||||
|
|
||||||
void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
|
void ARMInstPrinter::printAddrMode2Operand(const MCInst *MI, unsigned Op,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
const MCOperand &MO1 = MI->getOperand(Op);
|
const MCOperand &MO1 = MI->getOperand(Op);
|
||||||
|
@ -41,6 +41,8 @@ public:
|
|||||||
void printSORegRegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printSORegRegOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printSORegImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printSORegImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
|
|
||||||
|
void printAddrModeTBB(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
|
void printAddrModeTBH(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printAddrMode2Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printAM2PostIndexOp(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
|
void printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned OpNum,
|
||||||
|
@ -2614,6 +2614,24 @@ _func:
|
|||||||
@ CHECK: sxthne.w r2, r2, ror #16 @ encoding: [0x0f,0xfa,0xa2,0xf2]
|
@ CHECK: sxthne.w r2, r2, ror #16 @ encoding: [0x0f,0xfa,0xa2,0xf2]
|
||||||
|
|
||||||
|
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
@ TBB/TBH
|
||||||
|
@------------------------------------------------------------------------------
|
||||||
|
tbb [r3, r8]
|
||||||
|
tbh [r3, r8, lsl #1]
|
||||||
|
it eq
|
||||||
|
tbbeq [r3, r8]
|
||||||
|
it cs
|
||||||
|
tbhcs [r3, r8, lsl #1]
|
||||||
|
|
||||||
|
@ CHECK: tbb [r3, r8] @ encoding: [0xd3,0xe8,0x08,0xf0]
|
||||||
|
@ CHECK: tbh [r3, r8, lsl #1] @ encoding: [0xd3,0xe8,0x18,0xf0]
|
||||||
|
@ CHECK: it eq @ encoding: [0x08,0xbf]
|
||||||
|
@ CHECK: tbbeq [r3, r8] @ encoding: [0xd3,0xe8,0x08,0xf0]
|
||||||
|
@ CHECK: it hs @ encoding: [0x28,0xbf]
|
||||||
|
@ CHECK: tbhhs [r3, r8, lsl #1] @ encoding: [0xd3,0xe8,0x18,0xf0]
|
||||||
|
|
||||||
|
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
@ TEQ
|
@ TEQ
|
||||||
@------------------------------------------------------------------------------
|
@------------------------------------------------------------------------------
|
||||||
|
@ -686,6 +686,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
|||||||
MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R
|
MISC("t_addrmode_rr", "kOperandTypeThumbAddrModeRR"); // R, R
|
||||||
MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I
|
MISC("t_addrmode_sp", "kOperandTypeThumbAddrModeSP"); // R, I
|
||||||
MISC("t_addrmode_pc", "kOperandTypeThumbAddrModePC"); // R, I
|
MISC("t_addrmode_pc", "kOperandTypeThumbAddrModePC"); // R, I
|
||||||
|
MISC("addrmode_tbb", "kOperandTypeThumbAddrModeRR"); // R, R
|
||||||
|
MISC("addrmode_tbh", "kOperandTypeThumbAddrModeRR"); // R, R
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user