mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
[mips][mips64r6] Add compact branch instructions
Differential Revision: http://reviews.llvm.org/D3691 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208974 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0885a28635
commit
b8c3bcbbfa
@ -205,6 +205,16 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
|
||||
unsigned Offset,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
|
||||
unsigned Offset,
|
||||
uint64_t Address,
|
||||
const void *Decoder);
|
||||
|
||||
// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
|
||||
// shifted left by 1 bit.
|
||||
static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
|
||||
@ -856,6 +866,26 @@ static DecodeStatus DecodeJumpTarget(MCInst &Inst,
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeBranchTarget21(MCInst &Inst,
|
||||
unsigned Offset,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
int32_t BranchOffset = SignExtend32<21>(Offset) << 2;
|
||||
|
||||
Inst.addOperand(MCOperand::CreateImm(BranchOffset));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeBranchTarget26(MCInst &Inst,
|
||||
unsigned Offset,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
int32_t BranchOffset = SignExtend32<26>(Offset) << 2;
|
||||
|
||||
Inst.addOperand(MCOperand::CreateImm(BranchOffset));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
|
||||
unsigned Offset,
|
||||
uint64_t Address,
|
||||
|
@ -242,6 +242,46 @@ getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getBranchTarget21OpValue - Return binary encoding of the branch
|
||||
/// target operand. If the machine operand requires relocation,
|
||||
/// record the relocation and return zero.
|
||||
unsigned MipsMCCodeEmitter::
|
||||
getBranchTarget21OpValue(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 4.
|
||||
if (MO.isImm()) return MO.getImm() >> 2;
|
||||
|
||||
assert(MO.isExpr() &&
|
||||
"getBranchTarget21OpValue expects only expressions or immediates");
|
||||
|
||||
// TODO: Push 21 PC fixup.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getBranchTarget26OpValue - Return binary encoding of the branch
|
||||
/// target operand. If the machine operand requires relocation,
|
||||
/// record the relocation and return zero.
|
||||
unsigned MipsMCCodeEmitter::
|
||||
getBranchTarget26OpValue(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 4.
|
||||
if (MO.isImm()) return MO.getImm() >> 2;
|
||||
|
||||
assert(MO.isExpr() &&
|
||||
"getBranchTarget26OpValue expects only expressions or immediates");
|
||||
|
||||
// TODO: Push 26 PC fixup.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getJumpTargetOpValue - Return binary encoding of the jump
|
||||
/// target operand. If the machine operand requires relocation,
|
||||
/// record the relocation and return zero.
|
||||
|
@ -88,6 +88,20 @@ public:
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
// getBranchTarget21OpValue - Return binary encoding of the branch
|
||||
// offset operand. If the machine operand requires relocation,
|
||||
// record the relocation and return zero.
|
||||
unsigned getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
// getBranchTarget26OpValue - Return binary encoding of the branch
|
||||
// offset operand. If the machine operand requires relocation,
|
||||
// record the relocation and return zero.
|
||||
unsigned getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
// getMachineOpValue - Return binary encoding of operand. If the machin
|
||||
// operand requires relocation, record the relocation and return zero.
|
||||
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
||||
|
@ -191,6 +191,42 @@ class SPECIAL_3R_FM<bits<5> mulop, bits<6> funct> : MipsR6Inst {
|
||||
let Inst{5-0} = funct;
|
||||
}
|
||||
|
||||
class CMP_BRANCH_OFF16_FM<bits<6> funct> : MipsR6Inst {
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> offset;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = funct;
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-16} = rt;
|
||||
let Inst{15-0} = offset;
|
||||
}
|
||||
|
||||
class CMP_BRANCH_RT_OFF16_FM<bits<6> funct> : CMP_BRANCH_OFF16_FM<funct> {
|
||||
let Inst{25-21} = 0b00000;
|
||||
}
|
||||
|
||||
class CMP_BRANCH_OFF21_FM<bits<6> funct> : MipsR6Inst {
|
||||
bits<5> rs;
|
||||
bits<21> offset;
|
||||
|
||||
bits<32> Inst;
|
||||
|
||||
let Inst{31-26} = funct;
|
||||
let Inst{25-21} = rs;
|
||||
let Inst{20-0} = offset;
|
||||
}
|
||||
|
||||
class BRANCH_OFF26_FM<bits<6> funct> : MipsR6Inst {
|
||||
bits<32> Inst;
|
||||
bits<26> offset;
|
||||
|
||||
let Inst{31-26} = funct;
|
||||
let Inst{25-0} = offset;
|
||||
}
|
||||
|
||||
class SPECIAL3_ALIGN_FM<OPCODE6 Operation> : MipsR6Inst {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
|
@ -52,6 +52,20 @@ include "Mips32r6InstrFormats.td"
|
||||
// Removed: teqi, tgei, tgeiu, tlti, tltiu, tnei
|
||||
// Rencoded: [ls][wd]c2
|
||||
|
||||
def brtarget21 : Operand<OtherVT> {
|
||||
let EncoderMethod = "getBranchTarget21OpValue";
|
||||
let OperandType = "OPERAND_PCREL";
|
||||
let DecoderMethod = "DecodeBranchTarget21";
|
||||
let ParserMatchClass = MipsJumpTargetAsmOperand;
|
||||
}
|
||||
|
||||
def brtarget26 : Operand<OtherVT> {
|
||||
let EncoderMethod = "getBranchTarget26OpValue";
|
||||
let OperandType = "OPERAND_PCREL";
|
||||
let DecoderMethod = "DecodeBranchTarget26";
|
||||
let ParserMatchClass = MipsJumpTargetAsmOperand;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Instruction Encodings
|
||||
@ -63,6 +77,21 @@ class ALIGN_ENC : SPECIAL3_ALIGN_FM<OPCODE6_ALIGN>;
|
||||
class ALUIPC_ENC : PCREL16_FM<OPCODE5_ALUIPC>;
|
||||
class AUI_ENC : AUI_FM;
|
||||
class AUIPC_ENC : PCREL16_FM<OPCODE5_AUIPC>;
|
||||
|
||||
class BALC_ENC : BRANCH_OFF26_FM<0b111010>;
|
||||
class BC_ENC : BRANCH_OFF26_FM<0b110010>;
|
||||
class BEQC_ENC : CMP_BRANCH_OFF16_FM<0b001000>;
|
||||
class BNEC_ENC : CMP_BRANCH_OFF16_FM<0b011000>;
|
||||
|
||||
class BLTZC_ENC : CMP_BRANCH_OFF16_FM<0b010111>;
|
||||
class BGEZC_ENC : CMP_BRANCH_OFF16_FM<0b010110>;
|
||||
|
||||
class BLEZC_ENC : CMP_BRANCH_RT_OFF16_FM<0b010110>;
|
||||
class BGTZC_ENC : CMP_BRANCH_RT_OFF16_FM<0b010111>;
|
||||
|
||||
class BEQZC_ENC : CMP_BRANCH_OFF21_FM<0b110110>;
|
||||
class BNEZC_ENC : CMP_BRANCH_OFF21_FM<0b111110>;
|
||||
|
||||
class BITSWAP_ENC : SPECIAL3_2R_FM<OPCODE6_BITSWAP>;
|
||||
class DIV_ENC : SPECIAL_3R_FM<0b00010, 0b011010>;
|
||||
class DIVU_ENC : SPECIAL_3R_FM<0b00010, 0b011011>;
|
||||
@ -215,6 +244,66 @@ class AUI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
|
||||
|
||||
class AUI_DESC : AUI_DESC_BASE<"aui", GPR32Opnd>;
|
||||
|
||||
class BRANCH_DESC_BASE {
|
||||
bit isBranch = 1;
|
||||
bit isTerminator = 1;
|
||||
bit hasDelaySlot = 0;
|
||||
}
|
||||
|
||||
class BC_DESC_BASE<string instr_asm, DAGOperand opnd> : BRANCH_DESC_BASE {
|
||||
dag InOperandList = (ins opnd:$offset);
|
||||
dag OutOperandList = (outs);
|
||||
string AsmString = !strconcat(instr_asm, "\t$offset");
|
||||
bit isBarrier = 1;
|
||||
}
|
||||
|
||||
class CMP_BC_DESC_BASE<string instr_asm, DAGOperand opnd,
|
||||
RegisterOperand GPROpnd> : BRANCH_DESC_BASE {
|
||||
dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt, opnd:$offset);
|
||||
dag OutOperandList = (outs);
|
||||
string AsmString = !strconcat(instr_asm, "\t$rs, $rt, $offset");
|
||||
list<Register> Defs = [AT];
|
||||
}
|
||||
|
||||
class CMP_CBR_EQNE_Z_DESC_BASE<string instr_asm, DAGOperand opnd,
|
||||
RegisterOperand GPROpnd> : BRANCH_DESC_BASE {
|
||||
dag InOperandList = (ins GPROpnd:$rs, opnd:$offset);
|
||||
dag OutOperandList = (outs);
|
||||
string AsmString = !strconcat(instr_asm, "\t$rs, $offset");
|
||||
list<Register> Defs = [AT];
|
||||
}
|
||||
|
||||
class CMP_CBR_RT_Z_DESC_BASE<string instr_asm, DAGOperand opnd,
|
||||
RegisterOperand GPROpnd> : BRANCH_DESC_BASE {
|
||||
dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt, opnd:$offset);
|
||||
dag OutOperandList = (outs);
|
||||
string AsmString = !strconcat(instr_asm, "\t$rt, $offset");
|
||||
list<Register> Defs = [AT];
|
||||
}
|
||||
|
||||
class BALC_DESC : BC_DESC_BASE<"balc", brtarget26> {
|
||||
bit isCall = 1;
|
||||
list<Register> Defs = [RA];
|
||||
}
|
||||
|
||||
class BC_DESC : BC_DESC_BASE<"bc", brtarget26>;
|
||||
class BEQC_DESC : CMP_BC_DESC_BASE<"beqc", brtarget, GPR32Opnd>;
|
||||
class BNEC_DESC : CMP_BC_DESC_BASE<"bnec", brtarget, GPR32Opnd>;
|
||||
|
||||
class BLTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bltzc", brtarget, GPR32Opnd> {
|
||||
string Constraints = "$rs = $rt";
|
||||
}
|
||||
|
||||
class BGEZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgezc", brtarget, GPR32Opnd> {
|
||||
string Constraints = "$rs = $rt";
|
||||
}
|
||||
|
||||
class BLEZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"blezc", brtarget, GPR32Opnd>;
|
||||
class BGTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgtzc", brtarget, GPR32Opnd>;
|
||||
|
||||
class BEQZC_DESC : CMP_CBR_EQNE_Z_DESC_BASE<"beqzc", brtarget21, GPR32Opnd>;
|
||||
class BNEZC_DESC : CMP_CBR_EQNE_Z_DESC_BASE<"bnezc", brtarget21, GPR32Opnd>;
|
||||
|
||||
class BITSWAP_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
|
||||
dag OutOperandList = (outs GPROpnd:$rd);
|
||||
dag InOperandList = (ins GPROpnd:$rt);
|
||||
@ -316,31 +405,31 @@ def ALIGN : ALIGN_ENC, ALIGN_DESC, ISA_MIPS32R6;
|
||||
def ALUIPC : ALUIPC_ENC, ALUIPC_DESC, ISA_MIPS32R6;
|
||||
def AUI : AUI_ENC, AUI_DESC, ISA_MIPS32R6;
|
||||
def AUIPC : AUIPC_ENC, AUIPC_DESC, ISA_MIPS32R6;
|
||||
def BALC;
|
||||
def BALC : BALC_ENC, BALC_DESC, ISA_MIPS32R6;
|
||||
def BC1EQZ;
|
||||
def BC1NEZ;
|
||||
def BC2EQZ;
|
||||
def BC2NEZ;
|
||||
def BC;
|
||||
def BEQC;
|
||||
def BC : BC_ENC, BC_DESC, ISA_MIPS32R6;
|
||||
def BEQC : BEQC_ENC, BEQC_DESC, ISA_MIPS32R6;
|
||||
def BEQZALC;
|
||||
def BEQZC;
|
||||
def BEQZC : BEQZC_ENC, BEQZC_DESC, ISA_MIPS32R6;
|
||||
def BGEC; // Also aliased to blec with operands swapped
|
||||
def BGEUC; // Also aliased to bleuc with operands swapped
|
||||
def BGEZALC;
|
||||
def BGEZC;
|
||||
def BGEZC : BGEZC_ENC, BGEZC_DESC, ISA_MIPS32R6;
|
||||
def BGTZALC;
|
||||
def BGTZC;
|
||||
def BGTZC : BGTZC_ENC, BGTZC_DESC, ISA_MIPS32R6;
|
||||
def BITSWAP : BITSWAP_ENC, BITSWAP_DESC, ISA_MIPS32R6;
|
||||
def BLEZALC;
|
||||
def BLEZC;
|
||||
def BLEZC : BLEZC_ENC, BLEZC_DESC, ISA_MIPS32R6;
|
||||
def BLTC; // Also aliased to bgtc with operands swapped
|
||||
def BLTUC; // Also aliased to bgtuc with operands swapped
|
||||
def BLTZALC;
|
||||
def BLTZC;
|
||||
def BNEC;
|
||||
def BLTZC : BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6;
|
||||
def BNEC : BNEC_ENC, BNEC_DESC, ISA_MIPS32R6;
|
||||
def BNEZALC;
|
||||
def BNEZC;
|
||||
def BNEZC : BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6;
|
||||
def BNVC;
|
||||
def BOVC;
|
||||
def CLASS_D : CLASS_D_ENC, CLASS_D_DESC, ISA_MIPS32R6;
|
||||
|
@ -110,6 +110,11 @@ private:
|
||||
unsigned getBranchTargetOpValueMM(const MachineInstr &MI,
|
||||
unsigned OpNo) const;
|
||||
|
||||
unsigned getBranchTarget21OpValue(const MachineInstr &MI,
|
||||
unsigned OpNo) const;
|
||||
unsigned getBranchTarget26OpValue(const MachineInstr &MI,
|
||||
unsigned OpNo) const;
|
||||
|
||||
unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||
unsigned getMemEncodingMMImm12(const MachineInstr &MI, unsigned OpNo) const;
|
||||
@ -203,6 +208,18 @@ unsigned MipsCodeEmitter::getBranchTargetOpValueMM(const MachineInstr &MI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getBranchTarget21OpValue(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
llvm_unreachable("Unimplemented function.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getBranchTarget26OpValue(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
llvm_unreachable("Unimplemented function.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
|
||||
unsigned OpNo) const {
|
||||
MachineOperand MO = MI.getOperand(OpNo);
|
||||
|
@ -9,6 +9,16 @@
|
||||
aluipc $3, 56 # CHECK: aluipc $3, 56 # encoding: [0xec,0x7f,0x00,0x38]
|
||||
aui $3,$2,-23 # CHECK: aui $3, $2, -23 # encoding: [0x3c,0x62,0xff,0xe9]
|
||||
auipc $3, -1 # CHECK: auipc $3, -1 # encoding: [0xec,0x7e,0xff,0xff]
|
||||
balc 14572256 # CHECK: balc 14572256 # encoding: [0xe8,0x37,0x96,0xb8]
|
||||
bc 14572256 # CHECK: bc 14572256 # encoding: [0xc8,0x37,0x96,0xb8]
|
||||
beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40]
|
||||
bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40]
|
||||
beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90]
|
||||
bnezc $5, 72256 # CHECK: bnezc $5, 72256 # encoding: [0xf8,0xa0,0x46,0x90]
|
||||
bltzc $5, 256 # CHECK: bltzc $5, 256 # encoding: [0x5c,0xa5,0x00,0x40]
|
||||
bgezc $5, 256 # CHECK: bgezc $5, 256 # encoding: [0x58,0xa5,0x00,0x40]
|
||||
blezc $5, 256 # CHECK: blezc $5, 256 # encoding: [0x58,0x05,0x00,0x40]
|
||||
bgtzc $5, 256 # CHECK: bgtzc $5, 256 # encoding: [0x5c,0x05,0x00,0x40]
|
||||
bitswap $4, $2 # CHECK: bitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x20]
|
||||
cmp.f.s $f2,$f3,$f4 # CHECK: cmp.f.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x80]
|
||||
cmp.f.d $f2,$f3,$f4 # CHECK: cmp.f.d $f2, $f3, $f4 # encoding: [0x46,0xa4,0x18,0x80]
|
||||
|
@ -9,6 +9,16 @@
|
||||
aluipc $3, 56 # CHECK: aluipc $3, 56 # encoding: [0xec,0x7f,0x00,0x38]
|
||||
aui $3,$2,-23 # CHECK: aui $3, $2, -23 # encoding: [0x3c,0x62,0xff,0xe9]
|
||||
auipc $3, -1 # CHECK: auipc $3, -1 # encoding: [0xec,0x7e,0xff,0xff]
|
||||
balc 14572256 # CHECK: balc 14572256 # encoding: [0xe8,0x37,0x96,0xb8]
|
||||
bc 14572256 # CHECK: bc 14572256 # encoding: [0xc8,0x37,0x96,0xb8]
|
||||
beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40]
|
||||
bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40]
|
||||
beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90]
|
||||
bnezc $5, 72256 # CHECK: bnezc $5, 72256 # encoding: [0xf8,0xa0,0x46,0x90]
|
||||
bltzc $5, 256 # CHECK: bltzc $5, 256 # encoding: [0x5c,0xa5,0x00,0x40]
|
||||
bgezc $5, 256 # CHECK: bgezc $5, 256 # encoding: [0x58,0xa5,0x00,0x40]
|
||||
blezc $5, 256 # CHECK: blezc $5, 256 # encoding: [0x58,0x05,0x00,0x40]
|
||||
bgtzc $5, 256 # CHECK: bgtzc $5, 256 # encoding: [0x5c,0x05,0x00,0x40]
|
||||
bitswap $4, $2 # CHECK: bitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x20]
|
||||
cmp.f.s $f2,$f3,$f4 # CHECK: cmp.f.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x80]
|
||||
cmp.f.d $f2,$f3,$f4 # CHECK: cmp.f.d $f2, $f3, $f4 # encoding: [0x46,0xa4,0x18,0x80]
|
||||
|
Loading…
x
Reference in New Issue
Block a user