[mips][mips64r6] Add b[on]vc

Summary:
This required me to implement the disassembler for MIPS64r6 since the encodings
are ambiguous with other instructions. This in turn revealed a few
assembly/disassembly bugs which I have fixed.

* da[ht]i only take two operands according to the spec, not three.
* DecodeBranchTarget2[16] correctly handles wider immediates than simm16
  * Also made non-functional change to DecodeBranchTarget and
    DecodeBranchTargetMM to keep implementation style consistent between
    them.
* Difficult encodings are handled by a custom decode method on the most
  general encoding in the group. This method will convert the MCInst to a
  different opcode if necessary.

DecodeBranchTarget is not currently the inverse of getBranchTargetOpValue
so disassembling some branch instructions emit incorrect output. This seems
to affect branches with delay slots on all MIPS ISA's. I've left this bug
for now and temporarily removed the check for the immediate on
bc[12]eqz/bc[12]nez in the MIPS32r6/MIPS64r6 tests.

jialc and jic crash the disassembler for some reason. I've left these
instructions commented out for the moment.

Depends on D3760

Reviewers: jkolek, zoran.jovanovic, vmedic

Reviewed By: vmedic

Differential Revision: http://reviews.llvm.org/D3761

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209415 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Daniel Sanders 2014-05-22 11:23:21 +00:00
parent 2447dcc2e8
commit c96096cc0f
10 changed files with 681 additions and 51 deletions

View File

@ -63,6 +63,10 @@ public:
IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
} }
bool isMips32r6() const {
return STI.getFeatureBits() & Mips::FeatureMips32r6;
}
/// getInstruction - See MCDisassembler. /// getInstruction - See MCDisassembler.
DecodeStatus getInstruction(MCInst &instr, DecodeStatus getInstruction(MCInst &instr,
uint64_t &size, uint64_t &size,
@ -286,6 +290,32 @@ static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,
template <typename InsnType> template <typename InsnType>
static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder); const void *Decoder);
template <typename InsnType>
static DecodeStatus
DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
template <typename InsnType>
static DecodeStatus
DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
template <typename InsnType>
static DecodeStatus
DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
template <typename InsnType>
static DecodeStatus
DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
template <typename InsnType>
static DecodeStatus
DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder);
namespace llvm { namespace llvm {
extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
TheMips64elTarget; TheMips64elTarget;
@ -333,6 +363,12 @@ extern "C" void LLVMInitializeMipsDisassembler() {
#include "MipsGenDisassemblerTables.inc" #include "MipsGenDisassemblerTables.inc"
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
return *(RegInfo->getRegClass(RC).begin() + RegNo);
}
template <typename InsnType> template <typename InsnType>
static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
const void *Decoder) { const void *Decoder) {
@ -379,6 +415,202 @@ static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address,
return MCDisassembler::Success; return MCDisassembler::Success;
} }
template <typename InsnType>
static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn,
uint64_t Address,
const void *Decoder) {
// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
// (otherwise we would have matched the ADDI instruction from the earlier
// ISA's instead).
//
// We have:
// 0b001000 sssss ttttt iiiiiiiiiiiiiiii
// BOVC if rs >= rt
// BEQZALC if rs == 0 && rt != 0
// BEQC if rs < rt && rs != 0
InsnType Rs = fieldFromInstruction(insn, 21, 5);
InsnType Rt = fieldFromInstruction(insn, 16, 5);
InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
bool HasRs = false;
if (Rs >= Rt) {
MI.setOpcode(Mips::BOVC);
HasRs = true;
} else if (Rs != 0 && Rs < Rt) {
MI.setOpcode(Mips::BEQC);
HasRs = true;
} else
MI.setOpcode(Mips::BEQZALC);
if (HasRs)
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rs)));
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
MI.addOperand(MCOperand::CreateImm(Imm));
return MCDisassembler::Success;
}
template <typename InsnType>
static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn,
uint64_t Address,
const void *Decoder) {
// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
// (otherwise we would have matched the ADDI instruction from the earlier
// ISA's instead).
//
// We have:
// 0b011000 sssss ttttt iiiiiiiiiiiiiiii
// BNVC if rs >= rt
// BNEZALC if rs == 0 && rt != 0
// BNEC if rs < rt && rs != 0
InsnType Rs = fieldFromInstruction(insn, 21, 5);
InsnType Rt = fieldFromInstruction(insn, 16, 5);
InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
bool HasRs = false;
if (Rs >= Rt) {
MI.setOpcode(Mips::BNVC);
HasRs = true;
} else if (Rs != 0 && Rs < Rt) {
MI.setOpcode(Mips::BNEC);
HasRs = true;
} else
MI.setOpcode(Mips::BNEZALC);
if (HasRs)
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rs)));
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
MI.addOperand(MCOperand::CreateImm(Imm));
return MCDisassembler::Success;
}
template <typename InsnType>
static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn,
uint64_t Address,
const void *Decoder) {
// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
// (otherwise we would have matched the BLEZL instruction from the earlier
// ISA's instead).
//
// We have:
// 0b010110 sssss ttttt iiiiiiiiiiiiiiii
// Invalid if rs == 0
// BLEZC if rs == 0 && rt != 0
// BGEZC if rs == rt && rt != 0
// BGEC if rs != rt && rs != 0 && rt != 0
InsnType Rs = fieldFromInstruction(insn, 21, 5);
InsnType Rt = fieldFromInstruction(insn, 16, 5);
InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
if (Rt == 0)
return MCDisassembler::Fail;
else if (Rs == 0)
MI.setOpcode(Mips::BLEZC);
else if (Rs == Rt)
MI.setOpcode(Mips::BGEZC);
else
return MCDisassembler::Fail; // FIXME: BGEC is not implemented yet.
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
MI.addOperand(MCOperand::CreateImm(Imm));
return MCDisassembler::Success;
}
template <typename InsnType>
static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn,
uint64_t Address,
const void *Decoder) {
// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
// (otherwise we would have matched the BGTZL instruction from the earlier
// ISA's instead).
//
// We have:
// 0b010111 sssss ttttt iiiiiiiiiiiiiiii
// Invalid if rs == 0
// BGTZC if rs == 0 && rt != 0
// BLTZC if rs == rt && rt != 0
// BLTC if rs != rt && rs != 0 && rt != 0
InsnType Rs = fieldFromInstruction(insn, 21, 5);
InsnType Rt = fieldFromInstruction(insn, 16, 5);
InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
if (Rt == 0)
return MCDisassembler::Fail;
else if (Rs == 0)
MI.setOpcode(Mips::BGTZC);
else if (Rs == Rt)
MI.setOpcode(Mips::BLTZC);
else
return MCDisassembler::Fail; // FIXME: BLTC is not implemented yet.
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
MI.addOperand(MCOperand::CreateImm(Imm));
return MCDisassembler::Success;
}
template <typename InsnType>
static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn,
uint64_t Address,
const void *Decoder) {
// If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled
// (otherwise we would have matched the BGTZ instruction from the earlier
// ISA's instead).
//
// We have:
// 0b000111 sssss ttttt iiiiiiiiiiiiiiii
// BGTZ if rt == 0
// BGTZALC if rs == 0 && rt != 0
// BLTZALC if rs != 0 && rs == rt
// BLTUC if rs != 0 && rs != rt
InsnType Rs = fieldFromInstruction(insn, 21, 5);
InsnType Rt = fieldFromInstruction(insn, 16, 5);
InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) << 2;
bool HasRs = false;
bool HasRt = false;
if (Rt == 0) {
MI.setOpcode(Mips::BGTZ);
HasRs = true;
} else if (Rs == 0) {
MI.setOpcode(Mips::BGTZALC);
HasRt = true;
} else if (Rs == Rt) {
MI.setOpcode(Mips::BLTZALC);
HasRs = true;
} else
return MCDisassembler::Fail; // BLTUC not implemented yet
if (HasRs)
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rs)));
if (HasRt)
MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID,
Rt)));
MI.addOperand(MCOperand::CreateImm(Imm));
return MCDisassembler::Success;
}
/// readInstruction - read four bytes from the MemoryObject /// readInstruction - read four bytes from the MemoryObject
/// and return 32 bit word sorted according to the given endianess /// and return 32 bit word sorted according to the given endianess
static DecodeStatus readInstruction32(const MemoryObject &region, static DecodeStatus readInstruction32(const MemoryObject &region,
@ -448,6 +680,15 @@ MipsDisassembler::getInstruction(MCInst &instr,
return MCDisassembler::Fail; return MCDisassembler::Fail;
} }
if (isMips32r6()) {
Result = decodeInstruction(DecoderTableMips32r6_64r632, instr, Insn,
Address, this, STI);
if (Result != MCDisassembler::Fail) {
Size = 4;
return Result;
}
}
// Calling the auto-generated decoder function. // Calling the auto-generated decoder function.
Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
this, STI); this, STI);
@ -491,12 +732,6 @@ Mips64Disassembler::getInstruction(MCInst &instr,
return MCDisassembler::Fail; return MCDisassembler::Fail;
} }
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo();
return *(RegInfo->getRegClass(RC).begin() + RegNo);
}
static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
unsigned RegNo, unsigned RegNo,
uint64_t Address, uint64_t Address,
@ -867,8 +1102,7 @@ static DecodeStatus DecodeBranchTarget(MCInst &Inst,
unsigned Offset, unsigned Offset,
uint64_t Address, uint64_t Address,
const void *Decoder) { const void *Decoder) {
unsigned BranchOffset = Offset & 0xffff; int32_t BranchOffset = (SignExtend32<16>(Offset) << 2) + 4;
BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
Inst.addOperand(MCOperand::CreateImm(BranchOffset)); Inst.addOperand(MCOperand::CreateImm(BranchOffset));
return MCDisassembler::Success; return MCDisassembler::Success;
} }
@ -907,8 +1141,7 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
unsigned Offset, unsigned Offset,
uint64_t Address, uint64_t Address,
const void *Decoder) { const void *Decoder) {
unsigned BranchOffset = Offset & 0xffff; int32_t BranchOffset = SignExtend32<16>(Offset) << 1;
BranchOffset = SignExtend32<18>(BranchOffset << 1);
Inst.addOperand(MCOperand::CreateImm(BranchOffset)); Inst.addOperand(MCOperand::CreateImm(BranchOffset));
return MCDisassembler::Success; return MCDisassembler::Success;
} }

View File

@ -23,14 +23,23 @@ class MipsR6Inst : MipsInst<(outs), (ins), "", [], NoItinerary, FrmOther>,
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def OPGROUP_COP1 { bits<6> Value = 0b010001; } class OPGROUP<bits<6> Val> {
def OPGROUP_COP2 { bits<6> Value = 0b010010; } bits<6> Value = Val;
def OPGROUP_AUI { bits<6> Value = 0b001111; } }
def OPGROUP_DAUI { bits<6> Value = 0b011101; } def OPGROUP_COP1 : OPGROUP<0b010001>;
def OPGROUP_PCREL { bits<6> Value = 0b111011; } def OPGROUP_COP2 : OPGROUP<0b010010>;
def OPGROUP_REGIMM { bits<6> Value = 0b000001; } def OPGROUP_ADDI : OPGROUP<0b001000>;
def OPGROUP_SPECIAL { bits<6> Value = 0b000000; } def OPGROUP_AUI : OPGROUP<0b001111>;
def OPGROUP_SPECIAL3 { bits<6> Value = 0b011111; } def OPGROUP_BLEZ : OPGROUP<0b000110>;
def OPGROUP_BGTZ : OPGROUP<0b000111>;
def OPGROUP_BLEZL : OPGROUP<0b010110>;
def OPGROUP_BGTZL : OPGROUP<0b010111>;
def OPGROUP_DADDI : OPGROUP<0b011000>;
def OPGROUP_DAUI : OPGROUP<0b011101>;
def OPGROUP_PCREL : OPGROUP<0b111011>;
def OPGROUP_REGIMM : OPGROUP<0b000001>;
def OPGROUP_SPECIAL : OPGROUP<0b000000>;
def OPGROUP_SPECIAL3 : OPGROUP<0b011111>;
class OPCODE2<bits<2> Val> { class OPCODE2<bits<2> Val> {
bits<2> Value = Val; bits<2> Value = Val;
@ -91,6 +100,22 @@ class FIELD_CMP_FORMAT<bits<5> Val> {
def FIELD_CMP_FORMAT_S : FIELD_CMP_FORMAT<0b10100>; def FIELD_CMP_FORMAT_S : FIELD_CMP_FORMAT<0b10100>;
def FIELD_CMP_FORMAT_D : FIELD_CMP_FORMAT<0b10101>; def FIELD_CMP_FORMAT_D : FIELD_CMP_FORMAT<0b10101>;
//===----------------------------------------------------------------------===//
//
// Disambiguators
//
//===----------------------------------------------------------------------===//
//
// Some encodings are ambiguous except by comparing field values.
class DecodeDisambiguates<string Name> {
string DecoderMethod = !strconcat("Decode", Name);
}
class DecodeDisambiguatedBy<string Name> : DecodeDisambiguates<Name> {
string DecoderNamespace = "Mips32r6_64r6_Ambiguous";
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// Encoding Formats // Encoding Formats
@ -220,25 +245,53 @@ class SPECIAL_3R_FM<bits<5> mulop, bits<6> funct> : MipsR6Inst {
let Inst{5-0} = funct; let Inst{5-0} = funct;
} }
class CMP_BRANCH_OFF16_FM<bits<6> funct> : MipsR6Inst { // This class is ambiguous with other branches:
// BEQC/BNEC require that rs > rt
class CMP_BRANCH_2R_OFF16_FM<OPGROUP funct> : MipsR6Inst {
bits<5> rs; bits<5> rs;
bits<5> rt; bits<5> rt;
bits<16> offset; bits<16> offset;
bits<32> Inst; bits<32> Inst;
let Inst{31-26} = funct; let Inst{31-26} = funct.Value;
let Inst{25-21} = rs; let Inst{25-21} = rs;
let Inst{20-16} = rt; let Inst{20-16} = rt;
let Inst{15-0} = offset; let Inst{15-0} = offset;
} }
class CMP_BRANCH_RT_OFF16_FM<bits<6> funct> : CMP_BRANCH_OFF16_FM<funct> { // This class is ambiguous with other branches:
// BLEZC/BGEZC/BEQZALC/BNEZALC/BGTZALC require that rs == 0 && rt != 0
// The '1R_RT' in the name means 1 register in the rt field.
class CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP funct> : MipsR6Inst {
bits<5> rt;
bits<16> offset;
bits<32> Inst;
let Inst{31-26} = funct.Value;
let Inst{25-21} = 0b00000; let Inst{25-21} = 0b00000;
let Inst{20-16} = rt;
let Inst{15-0} = offset;
}
// This class is ambiguous with other branches:
// BLTZC/BGTZC/BLTZALC/BGEZALC require that rs == rt && rt != 0
// The '1R_BOTH' in the name means 1 register in both the rs and rt fields.
class CMP_BRANCH_1R_BOTH_OFF16_FM<OPGROUP funct> : MipsR6Inst {
bits<5> rt;
bits<16> offset;
bits<32> Inst;
let Inst{31-26} = funct.Value;
let Inst{25-21} = rt;
let Inst{20-16} = rt;
let Inst{15-0} = offset;
} }
class CMP_BRANCH_OFF21_FM<bits<6> funct> : MipsR6Inst { class CMP_BRANCH_OFF21_FM<bits<6> funct> : MipsR6Inst {
bits<5> rs; bits<5> rs; // rs != 0
bits<21> offset; bits<21> offset;
bits<32> Inst; bits<32> Inst;

View File

@ -90,21 +90,31 @@ class AUIPC_ENC : PCREL16_FM<OPCODE5_AUIPC>;
class BALC_ENC : BRANCH_OFF26_FM<0b111010>; class BALC_ENC : BRANCH_OFF26_FM<0b111010>;
class BC_ENC : BRANCH_OFF26_FM<0b110010>; class BC_ENC : BRANCH_OFF26_FM<0b110010>;
class BEQC_ENC : CMP_BRANCH_OFF16_FM<0b001000>; class BEQC_ENC : CMP_BRANCH_2R_OFF16_FM<OPGROUP_ADDI>,
class BEQZALC_ENC : CMP_BRANCH_RT_OFF16_FM<0b001000>; DecodeDisambiguates<"AddiGroupBranch">;
class BNEC_ENC : CMP_BRANCH_OFF16_FM<0b011000>; class BEQZALC_ENC : CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP_ADDI>,
class BNEZALC_ENC : CMP_BRANCH_RT_OFF16_FM<0b011000>; DecodeDisambiguatedBy<"DaddiGroupBranch">;
class BNEC_ENC : CMP_BRANCH_2R_OFF16_FM<OPGROUP_DADDI>,
DecodeDisambiguates<"DaddiGroupBranch">;
class BNEZALC_ENC : CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP_DADDI>,
DecodeDisambiguatedBy<"DaddiGroupBranch">;
class BLTZC_ENC : CMP_BRANCH_OFF16_FM<0b010111>; class BLTZC_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM<OPGROUP_BGTZL>,
class BGEZC_ENC : CMP_BRANCH_OFF16_FM<0b010110>; DecodeDisambiguates<"BgtzlGroupBranch">;
class BGTZALC_ENC : CMP_BRANCH_RT_OFF16_FM<0b000111>; class BGEZC_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM<OPGROUP_BLEZL>,
DecodeDisambiguates<"BlezlGroupBranch">;
class BGTZALC_ENC : CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP_BGTZ>,
DecodeDisambiguatedBy<"BgtzGroupBranch">;
class BLEZC_ENC : CMP_BRANCH_RT_OFF16_FM<0b010110>; class BLEZC_ENC : CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP_BLEZL>,
class BLTZALC_ENC : CMP_BRANCH_OFF16_FM<0b000111>; DecodeDisambiguatedBy<"BlezlGroupBranch">;
class BGTZC_ENC : CMP_BRANCH_RT_OFF16_FM<0b010111>; class BLTZALC_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM<OPGROUP_BGTZ>,
DecodeDisambiguates<"BgtzGroupBranch">;
class BGTZC_ENC : CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP_BGTZL>,
DecodeDisambiguatedBy<"BgtzlGroupBranch">;
class BEQZC_ENC : CMP_BRANCH_OFF21_FM<0b110110>; class BEQZC_ENC : CMP_BRANCH_OFF21_FM<0b110110>;
class BGEZALC_ENC : CMP_BRANCH_OFF16_FM<0b000110>; class BGEZALC_ENC : CMP_BRANCH_1R_BOTH_OFF16_FM<OPGROUP_BLEZ>;
class BNEZC_ENC : CMP_BRANCH_OFF21_FM<0b111110>; class BNEZC_ENC : CMP_BRANCH_OFF21_FM<0b111110>;
class BC1EQZ_ENC : COP1_BCCZ_FM<OPCODE5_BC1EQZ>; class BC1EQZ_ENC : COP1_BCCZ_FM<OPCODE5_BC1EQZ>;
@ -116,7 +126,11 @@ class JIALC_ENC : JMP_IDX_COMPACT_FM<0b111110>;
class JIC_ENC : JMP_IDX_COMPACT_FM<0b110110>; class JIC_ENC : JMP_IDX_COMPACT_FM<0b110110>;
class BITSWAP_ENC : SPECIAL3_2R_FM<OPCODE6_BITSWAP>; class BITSWAP_ENC : SPECIAL3_2R_FM<OPCODE6_BITSWAP>;
class BLEZALC_ENC : CMP_BRANCH_RT_OFF16_FM<0b000110>; class BLEZALC_ENC : CMP_BRANCH_1R_RT_OFF16_FM<OPGROUP_BLEZ>;
class BNVC_ENC : CMP_BRANCH_2R_OFF16_FM<OPGROUP_DADDI>,
DecodeDisambiguatedBy<"DaddiGroupBranch">;
class BOVC_ENC : CMP_BRANCH_2R_OFF16_FM<OPGROUP_ADDI>,
DecodeDisambiguatedBy<"AddiGroupBranch">;
class DIV_ENC : SPECIAL_3R_FM<0b00010, 0b011010>; class DIV_ENC : SPECIAL_3R_FM<0b00010, 0b011010>;
class DIVU_ENC : SPECIAL_3R_FM<0b00010, 0b011011>; class DIVU_ENC : SPECIAL_3R_FM<0b00010, 0b011011>;
class MOD_ENC : SPECIAL_3R_FM<0b00011, 0b011010>; class MOD_ENC : SPECIAL_3R_FM<0b00011, 0b011010>;
@ -302,7 +316,7 @@ class CMP_CBR_EQNE_Z_DESC_BASE<string instr_asm, DAGOperand opnd,
class CMP_CBR_RT_Z_DESC_BASE<string instr_asm, DAGOperand opnd, class CMP_CBR_RT_Z_DESC_BASE<string instr_asm, DAGOperand opnd,
RegisterOperand GPROpnd> : BRANCH_DESC_BASE { RegisterOperand GPROpnd> : BRANCH_DESC_BASE {
dag InOperandList = (ins GPROpnd:$rs, GPROpnd:$rt, opnd:$offset); dag InOperandList = (ins GPROpnd:$rt, opnd:$offset);
dag OutOperandList = (outs); dag OutOperandList = (outs);
string AsmString = !strconcat(instr_asm, "\t$rt, $offset"); string AsmString = !strconcat(instr_asm, "\t$rt, $offset");
list<Register> Defs = [AT]; list<Register> Defs = [AT];
@ -317,13 +331,8 @@ class BC_DESC : BC_DESC_BASE<"bc", brtarget26>;
class BEQC_DESC : CMP_BC_DESC_BASE<"beqc", brtarget, GPR32Opnd>; class BEQC_DESC : CMP_BC_DESC_BASE<"beqc", brtarget, GPR32Opnd>;
class BNEC_DESC : CMP_BC_DESC_BASE<"bnec", brtarget, GPR32Opnd>; class BNEC_DESC : CMP_BC_DESC_BASE<"bnec", brtarget, GPR32Opnd>;
class BLTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bltzc", 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>;
}
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 BLEZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"blezc", brtarget, GPR32Opnd>;
class BGTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgtzc", brtarget, GPR32Opnd>; class BGTZC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgtzc", brtarget, GPR32Opnd>;
@ -351,6 +360,9 @@ class COP2_BCCZ_DESC_BASE<string instr_asm> : BRANCH_DESC_BASE {
class BC2EQZ_DESC : COP2_BCCZ_DESC_BASE<"bc2eqz $ct, $offset">; class BC2EQZ_DESC : COP2_BCCZ_DESC_BASE<"bc2eqz $ct, $offset">;
class BC2NEZ_DESC : COP2_BCCZ_DESC_BASE<"bc2nez $ct, $offset">; class BC2NEZ_DESC : COP2_BCCZ_DESC_BASE<"bc2nez $ct, $offset">;
class BOVC_DESC : CMP_BC_DESC_BASE<"bovc", brtarget, GPR32Opnd>;
class BNVC_DESC : CMP_BC_DESC_BASE<"bnvc", brtarget, GPR32Opnd>;
class JMP_IDX_COMPACT_DESC_BASE<string opstr, DAGOperand opnd, class JMP_IDX_COMPACT_DESC_BASE<string opstr, DAGOperand opnd,
RegisterOperand GPROpnd> { RegisterOperand GPROpnd> {
dag InOperandList = (ins GPROpnd:$rt, opnd:$offset); dag InOperandList = (ins GPROpnd:$rt, opnd:$offset);
@ -398,7 +410,6 @@ class BEQZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"beqzalc", brtarget, GPR32Opnd> {
} }
class BGEZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgezalc", brtarget, GPR32Opnd> { class BGEZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bgezalc", brtarget, GPR32Opnd> {
string Constraints = "$rs = $rt";
list<Register> Defs = [RA]; list<Register> Defs = [RA];
} }
@ -411,7 +422,6 @@ class BLEZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"blezalc", brtarget, GPR32Opnd> {
} }
class BLTZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bltzalc", brtarget, GPR32Opnd> { class BLTZALC_DESC : CMP_CBR_RT_Z_DESC_BASE<"bltzalc", brtarget, GPR32Opnd> {
string Constraints = "$rs = $rt";
list<Register> Defs = [RA]; list<Register> Defs = [RA];
} }
@ -533,8 +543,8 @@ def BLTZC : BLTZC_ENC, BLTZC_DESC, ISA_MIPS32R6;
def BNEC : BNEC_ENC, BNEC_DESC, ISA_MIPS32R6; def BNEC : BNEC_ENC, BNEC_DESC, ISA_MIPS32R6;
def BNEZALC : BNEZALC_ENC, BNEZALC_DESC, ISA_MIPS32R6; def BNEZALC : BNEZALC_ENC, BNEZALC_DESC, ISA_MIPS32R6;
def BNEZC : BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6; def BNEZC : BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6;
def BNVC; def BNVC : BNVC_ENC, BNVC_DESC, ISA_MIPS32R6;
def BOVC; def BOVC : BOVC_ENC, BOVC_DESC, ISA_MIPS32R6;
def CLASS_D : CLASS_D_ENC, CLASS_D_DESC, ISA_MIPS32R6; def CLASS_D : CLASS_D_ENC, CLASS_D_DESC, ISA_MIPS32R6;
def CLASS_S : CLASS_S_ENC, CLASS_S_DESC, ISA_MIPS32R6; def CLASS_S : CLASS_S_ENC, CLASS_S_DESC, ISA_MIPS32R6;
defm S : CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGR32Opnd>; defm S : CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGR32Opnd>;

View File

@ -45,9 +45,16 @@ class DMULU_ENC : SPECIAL_3R_FM<0b00010, 0b111001>;
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
class AHI_ATI_DESC_BASE<string instr_asm, RegisterOperand GPROpnd> {
dag OutOperandList = (outs GPROpnd:$rs);
dag InOperandList = (ins GPROpnd:$rt, simm16:$imm);
string AsmString = !strconcat(instr_asm, "\t$rt, $imm");
string Constraints = "$rs = $rt";
}
class DALIGN_DESC : ALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>; class DALIGN_DESC : ALIGN_DESC_BASE<"dalign", GPR64Opnd, uimm3>;
class DAHI_DESC : AUI_DESC_BASE<"dahi", GPR64Opnd>; class DAHI_DESC : AHI_ATI_DESC_BASE<"dahi", GPR64Opnd>;
class DATI_DESC : AUI_DESC_BASE<"dati", GPR64Opnd>; class DATI_DESC : AHI_ATI_DESC_BASE<"dati", GPR64Opnd>;
class DAUI_DESC : AUI_DESC_BASE<"daui", GPR64Opnd>; class DAUI_DESC : AUI_DESC_BASE<"daui", GPR64Opnd>;
class DBITSWAP_DESC : BITSWAP_DESC_BASE<"dbitswap", GPR64Opnd>; class DBITSWAP_DESC : BITSWAP_DESC_BASE<"dbitswap", GPR64Opnd>;
class DDIV_DESC : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd>; class DDIV_DESC : DIVMOD_DESC_BASE<"ddiv", GPR64Opnd>;

View File

@ -0,0 +1,116 @@
# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips32r6 | FileCheck %s
0xec 0x80 0x00 0x19 # CHECK: addiupc $4, 100
0x7c 0x43 0x22 0xa0 # CHECK: align $4, $2, $3, 2
0xec 0x7f 0x00 0x38 # CHECK: aluipc $3, 56
0x3c 0x62 0xff 0xe9 # CHECK: aui $3, $2, -23
0xec 0x7e 0xff 0xff # CHECK: auipc $3, -1
0xe8 0x37 0x96 0xb8 # CHECK: balc 14572256
0xc8 0x37 0x96 0xb8 # CHECK: bc 14572256
# FIXME: Don't check the immediate on these for the moment, the encode/decode
# functions are not inverses of eachother.
# The immediate should be 4 but the disassembler currently emits 8
0x45 0x20 0x00 0x01 # CHECK: bc1eqz $f0,
0x45 0x3f 0x00 0x01 # CHECK: bc1eqz $f31,
0x45 0xa0 0x00 0x01 # CHECK: bc1nez $f0,
0x45 0xbf 0x00 0x01 # CHECK: bc1nez $f31,
# FIXME: Don't check the immediate on these for the moment, the encode/decode
# functions are not inverses of eachother.
# The immediate should be 8 but the disassembler currently emits 12
0x49 0x20 0x00 0x02 # CHECK: bc2eqz $0,
0x49 0x3f 0x00 0x02 # CHECK: bc2eqz $31,
0x49 0xa0 0x00 0x02 # CHECK: bc2nez $0,
0x49 0xbf 0x00 0x02 # CHECK: bc2nez $31,
0x20 0xa6 0x00 0x40 # CHECK: beqc $5, $6, 256
# FIXME: Don't check the immediate on the bcczal's for the moment, the
# encode/decode functions are not inverses of eachother.
0x20 0x02 0x01 0x4d # CHECK: beqzalc $2,
0x60 0xa6 0x00 0x40 # CHECK: bnec $5, $6, 256
0x60 0x02 0x01 0x4d # CHECK: bnezalc $2,
0xd8 0xa0 0x46 0x90 # CHECK: beqzc $5, 72256
0x18 0x42 0x01 0x4d # CHECK: bgezalc $2,
0xf8 0xa0 0x46 0x90 # CHECK: bnezc $5, 72256
0x5c 0xa5 0x00 0x40 # CHECK: bltzc $5, 256
0x58 0xa5 0x00 0x40 # CHECK: bgezc $5, 256
0x1c 0x02 0x01 0x4d # CHECK: bgtzalc $2,
0x58 0x05 0x00 0x40 # CHECK: blezc $5, 256
0x1c 0x42 0x01 0x4d # CHECK: bltzalc $2,
0x5c 0x05 0x00 0x40 # CHECK: bgtzc $5, 256
0x7c 0x02 0x20 0x20 # CHECK: bitswap $4, $2
0x18 0x02 0x01 0x4d # CHECK: blezalc $2,
0x60 0x00 0x00 0x01 # CHECK: bnvc $zero, $zero, 4
0x60 0x40 0x00 0x01 # CHECK: bnvc $2, $zero, 4
0x60 0x82 0x00 0x01 # CHECK: bnvc $4, $2, 4
0x20 0x00 0x00 0x01 # CHECK: bovc $zero, $zero, 4
0x20 0x40 0x00 0x01 # CHECK: bovc $2, $zero, 4
0x20 0x82 0x00 0x01 # CHECK: bovc $4, $2, 4
0x46 0x84 0x18 0x80 # CHECK: cmp.f.s $f2, $f3, $f4
0x46 0xa4 0x18 0x80 # CHECK: cmp.f.d $f2, $f3, $f4
0x46 0x84 0x18 0x81 # CHECK: cmp.un.s $f2, $f3, $f4
0x46 0xa4 0x18 0x81 # CHECK: cmp.un.d $f2, $f3, $f4
0x46 0x84 0x18 0x82 # CHECK: cmp.eq.s $f2, $f3, $f4
0x46 0xa4 0x18 0x82 # CHECK: cmp.eq.d $f2, $f3, $f4
0x46 0x84 0x18 0x83 # CHECK: cmp.ueq.s $f2, $f3, $f4
0x46 0xa4 0x18 0x83 # CHECK: cmp.ueq.d $f2, $f3, $f4
0x46 0x84 0x18 0x84 # CHECK: cmp.olt.s $f2, $f3, $f4
0x46 0xa4 0x18 0x84 # CHECK: cmp.olt.d $f2, $f3, $f4
0x46 0x84 0x18 0x85 # CHECK: cmp.ult.s $f2, $f3, $f4
0x46 0xa4 0x18 0x85 # CHECK: cmp.ult.d $f2, $f3, $f4
0x46 0x84 0x18 0x86 # CHECK: cmp.ole.s $f2, $f3, $f4
0x46 0xa4 0x18 0x86 # CHECK: cmp.ole.d $f2, $f3, $f4
0x46 0x84 0x18 0x87 # CHECK: cmp.ule.s $f2, $f3, $f4
0x46 0xa4 0x18 0x87 # CHECK: cmp.ule.d $f2, $f3, $f4
0x46 0x84 0x18 0x88 # CHECK: cmp.sf.s $f2, $f3, $f4
0x46 0xa4 0x18 0x88 # CHECK: cmp.sf.d $f2, $f3, $f4
0x46 0x84 0x18 0x89 # CHECK: cmp.ngle.s $f2, $f3, $f4
0x46 0xa4 0x18 0x89 # CHECK: cmp.ngle.d $f2, $f3, $f4
0x46 0x84 0x18 0x8a # CHECK: cmp.seq.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8a # CHECK: cmp.seq.d $f2, $f3, $f4
0x46 0x84 0x18 0x8b # CHECK: cmp.ngl.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8b # CHECK: cmp.ngl.d $f2, $f3, $f4
0x46 0x84 0x18 0x8c # CHECK: cmp.lt.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8c # CHECK: cmp.lt.d $f2, $f3, $f4
0x46 0x84 0x18 0x8d # CHECK: cmp.nge.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8d # CHECK: cmp.nge.d $f2, $f3, $f4
0x46 0x84 0x18 0x8e # CHECK: cmp.le.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8e # CHECK: cmp.le.d $f2, $f3, $f4
0x46 0x84 0x18 0x8f # CHECK: cmp.ngt.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8f # CHECK: cmp.ngt.d $f2, $f3, $f4
0x00 0x64 0x10 0x9a # CHECK: div $2, $3, $4
0x00 0x64 0x10 0x9b # CHECK: divu $2, $3, $4
# 0xf8 0x05 0x01 0x00 # CHECK-TODO: jialc $5, 256
# 0xd8 0x05 0x01 0x00 # CHECK-TODO: jic $5, 256
0xec 0x48 0x00 0x43 # CHECK: lwpc $2, 268
0xec 0x50 0x00 0x43 # CHECK: lwupc $2, 268
0x00 0x64 0x10 0xda # CHECK: mod $2, $3, $4
0x00 0x64 0x10 0xdb # CHECK: modu $2, $3, $4
0x00 0x64 0x10 0x98 # CHECK: mul $2, $3, $4
0x00 0x64 0x10 0xd8 # CHECK: muh $2, $3, $4
0x00 0x64 0x10 0x99 # CHECK: mulu $2, $3, $4
0x00 0x64 0x10 0xd9 # CHECK: muhu $2, $3, $4
0x46 0x04 0x18 0x98 # CHECK: maddf.s $f2, $f3, $f4
0x46 0x24 0x18 0x98 # CHECK: maddf.d $f2, $f3, $f4
0x46 0x04 0x18 0x99 # CHECK: msubf.s $f2, $f3, $f4
0x46 0x24 0x18 0x99 # CHECK: msubf.d $f2, $f3, $f4
0x46 0x22 0x08 0x10 # CHECK: sel.d $f0, $f1, $f2
0x46 0x02 0x08 0x10 # CHECK: sel.s $f0, $f1, $f2
0x00 0x64 0x10 0x35 # CHECK: seleqz $2, $3, $4
0x00 0x64 0x10 0x37 # CHECK: selnez $2, $3, $4
0x46 0x04 0x10 0x1d # CHECK: max.s $f0, $f2, $f4
0x46 0x24 0x10 0x1d # CHECK: max.d $f0, $f2, $f4
0x46 0x04 0x10 0x1c # CHECK: min.s $f0, $f2, $f4
0x46 0x24 0x10 0x1c # CHECK: min.d $f0, $f2, $f4
0x46 0x04 0x10 0x1f # CHECK: maxa.s $f0, $f2, $f4
0x46 0x24 0x10 0x1f # CHECK: maxa.d $f0, $f2, $f4
0x46 0x04 0x10 0x1e # CHECK: mina.s $f0, $f2, $f4
0x46 0x24 0x10 0x1e # CHECK: mina.d $f0, $f2, $f4
0x46 0x04 0x10 0x14 # CHECK: seleqz.s $f0, $f2, $f4
0x46 0x24 0x10 0x14 # CHECK: seleqz.d $f0, $f2, $f4
0x46 0x04 0x10 0x17 # CHECK: selnez.s $f0, $f2, $f4
0x46 0x24 0x10 0x17 # CHECK: selnez.d $f0, $f2, $f4
0x46 0x00 0x20 0x9a # CHECK: rint.s $f2, $f4
0x46 0x20 0x20 0x9a # CHECK: rint.d $f2, $f4
0x46 0x00 0x20 0x9b # CHECK: class.s $f2, $f4
0x46 0x20 0x20 0x9b # CHECK: class.d $f2, $f4

View File

@ -0,0 +1,129 @@
# RUN: llvm-mc --disassemble %s -triple=mips-unknown-linux -mcpu=mips64r6 | FileCheck %s
0xec 0x80 0x00 0x19 # CHECK: addiupc $4, 100
0x7c 0x43 0x22 0xa0 # CHECK: align $4, $2, $3, 2
0xec 0x7f 0x00 0x38 # CHECK: aluipc $3, 56
0x3c 0x62 0xff 0xe9 # CHECK: aui $3, $2, -23
0xec 0x7e 0xff 0xff # CHECK: auipc $3, -1
0xe8 0x37 0x96 0xb8 # CHECK: balc 14572256
0xc8 0x37 0x96 0xb8 # CHECK: bc 14572256
# FIXME: Don't check the immediate on these for the moment, the encode/decode
# functions are not inverses of eachother.
# The immediate should be 4 but the disassembler currently emits 8
0x45 0x20 0x00 0x01 # CHECK: bc1eqz $f0,
0x45 0x3f 0x00 0x01 # CHECK: bc1eqz $f31,
0x45 0xa0 0x00 0x01 # CHECK: bc1nez $f0,
0x45 0xbf 0x00 0x01 # CHECK: bc1nez $f31,
# FIXME: Don't check the immediate on these for the moment, the encode/decode
# functions are not inverses of eachother.
# The immediate should be 8 but the disassembler currently emits 12
0x49 0x20 0x00 0x02 # CHECK: bc2eqz $0,
0x49 0x3f 0x00 0x02 # CHECK: bc2eqz $31,
0x49 0xa0 0x00 0x02 # CHECK: bc2nez $0,
0x49 0xbf 0x00 0x02 # CHECK: bc2nez $31,
0x20 0xa6 0x00 0x40 # CHECK: beqc $5, $6, 256
# FIXME: Don't check the immediate on the bcczal's for the moment, the
# encode/decode functions are not inverses of eachother.
0x20 0x02 0x01 0x4d # CHECK: beqzalc $2,
0x60 0xa6 0x00 0x40 # CHECK: bnec $5, $6, 256
0x60 0x02 0x01 0x4d # CHECK: bnezalc $2,
0xd8 0xa0 0x46 0x90 # CHECK: beqzc $5, 72256
0x18 0x42 0x01 0x4d # CHECK: bgezalc $2,
0xf8 0xa0 0x46 0x90 # CHECK: bnezc $5, 72256
0x5c 0xa5 0x00 0x40 # CHECK: bltzc $5, 256
0x58 0xa5 0x00 0x40 # CHECK: bgezc $5, 256
0x1c 0x02 0x01 0x4d # CHECK: bgtzalc $2,
0x58 0x05 0x00 0x40 # CHECK: blezc $5, 256
0x1c 0x42 0x01 0x4d # CHECK: bltzalc $2,
0x5c 0x05 0x00 0x40 # CHECK: bgtzc $5, 256
0x7c 0x02 0x20 0x20 # CHECK: bitswap $4, $2
0x18 0x02 0x01 0x4d # CHECK: blezalc $2,
0x60 0x00 0x00 0x01 # CHECK: bnvc $zero, $zero, 4
0x60 0x40 0x00 0x01 # CHECK: bnvc $2, $zero, 4
0x60 0x82 0x00 0x01 # CHECK: bnvc $4, $2, 4
0x20 0x00 0x00 0x01 # CHECK: bovc $zero, $zero, 4
0x20 0x40 0x00 0x01 # CHECK: bovc $2, $zero, 4
0x20 0x82 0x00 0x01 # CHECK: bovc $4, $2, 4
0x46 0x84 0x18 0x80 # CHECK: cmp.f.s $f2, $f3, $f4
0x46 0xa4 0x18 0x80 # CHECK: cmp.f.d $f2, $f3, $f4
0x46 0x84 0x18 0x81 # CHECK: cmp.un.s $f2, $f3, $f4
0x46 0xa4 0x18 0x81 # CHECK: cmp.un.d $f2, $f3, $f4
0x46 0x84 0x18 0x82 # CHECK: cmp.eq.s $f2, $f3, $f4
0x46 0xa4 0x18 0x82 # CHECK: cmp.eq.d $f2, $f3, $f4
0x46 0x84 0x18 0x83 # CHECK: cmp.ueq.s $f2, $f3, $f4
0x46 0xa4 0x18 0x83 # CHECK: cmp.ueq.d $f2, $f3, $f4
0x46 0x84 0x18 0x84 # CHECK: cmp.olt.s $f2, $f3, $f4
0x46 0xa4 0x18 0x84 # CHECK: cmp.olt.d $f2, $f3, $f4
0x46 0x84 0x18 0x85 # CHECK: cmp.ult.s $f2, $f3, $f4
0x46 0xa4 0x18 0x85 # CHECK: cmp.ult.d $f2, $f3, $f4
0x46 0x84 0x18 0x86 # CHECK: cmp.ole.s $f2, $f3, $f4
0x46 0xa4 0x18 0x86 # CHECK: cmp.ole.d $f2, $f3, $f4
0x46 0x84 0x18 0x87 # CHECK: cmp.ule.s $f2, $f3, $f4
0x46 0xa4 0x18 0x87 # CHECK: cmp.ule.d $f2, $f3, $f4
0x46 0x84 0x18 0x88 # CHECK: cmp.sf.s $f2, $f3, $f4
0x46 0xa4 0x18 0x88 # CHECK: cmp.sf.d $f2, $f3, $f4
0x46 0x84 0x18 0x89 # CHECK: cmp.ngle.s $f2, $f3, $f4
0x46 0xa4 0x18 0x89 # CHECK: cmp.ngle.d $f2, $f3, $f4
0x46 0x84 0x18 0x8a # CHECK: cmp.seq.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8a # CHECK: cmp.seq.d $f2, $f3, $f4
0x46 0x84 0x18 0x8b # CHECK: cmp.ngl.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8b # CHECK: cmp.ngl.d $f2, $f3, $f4
0x46 0x84 0x18 0x8c # CHECK: cmp.lt.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8c # CHECK: cmp.lt.d $f2, $f3, $f4
0x46 0x84 0x18 0x8d # CHECK: cmp.nge.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8d # CHECK: cmp.nge.d $f2, $f3, $f4
0x46 0x84 0x18 0x8e # CHECK: cmp.le.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8e # CHECK: cmp.le.d $f2, $f3, $f4
0x46 0x84 0x18 0x8f # CHECK: cmp.ngt.s $f2, $f3, $f4
0x46 0xa4 0x18 0x8f # CHECK: cmp.ngt.d $f2, $f3, $f4
0x7c 0x43 0x23 0x64 # CHECK: dalign $4, $2, $3, 5
0x74 0x62 0x12 0x34 # CHECK: daui $3, $2, 4660
0x04 0x66 0x56 0x78 # CHECK: dahi $3, 22136
0x04 0x7e 0xab 0xcd # CHECK: dati $3, -21555
0x7c 0x02 0x20 0x24 # CHECK: dbitswap $4, $2
0x00 0x64 0x10 0x9a # CHECK: div $2, $3, $4
0x00 0x64 0x10 0x9b # CHECK: divu $2, $3, $4
# 0xf8 0x05 0x01 0x00 # CHECK-TODO: jialc $5, 256
# 0xd8 0x05 0x01 0x00 # CHECK-TODO: jic $5, 256
0xec 0x48 0x00 0x43 # CHECK: lwpc $2, 268
0xec 0x50 0x00 0x43 # CHECK: lwupc $2, 268
0x00 0x64 0x10 0xda # CHECK: mod $2, $3, $4
0x00 0x64 0x10 0xdb # CHECK: modu $2, $3, $4
0x00 0x64 0x10 0x9e # CHECK: ddiv $2, $3, $4
0x00 0x64 0x10 0x9f # CHECK: ddivu $2, $3, $4
0x00 0x64 0x10 0xde # CHECK: dmod $2, $3, $4
0x00 0x64 0x10 0xdf # CHECK: dmodu $2, $3, $4
0x00 0x64 0x10 0x98 # CHECK: mul $2, $3, $4
0x00 0x64 0x10 0xd8 # CHECK: muh $2, $3, $4
0x00 0x64 0x10 0x99 # CHECK: mulu $2, $3, $4
0x00 0x64 0x10 0xd9 # CHECK: muhu $2, $3, $4
0x00 0x64 0x10 0xb8 # CHECK: dmul $2, $3, $4
0x00 0x64 0x10 0xf8 # CHECK: dmuh $2, $3, $4
0x00 0x64 0x10 0xb9 # CHECK: dmulu $2, $3, $4
0x00 0x64 0x10 0xf9 # CHECK: dmuhu $2, $3, $4
0x46 0x04 0x18 0x98 # CHECK: maddf.s $f2, $f3, $f4
0x46 0x24 0x18 0x98 # CHECK: maddf.d $f2, $f3, $f4
0x46 0x04 0x18 0x99 # CHECK: msubf.s $f2, $f3, $f4
0x46 0x24 0x18 0x99 # CHECK: msubf.d $f2, $f3, $f4
0x46 0x22 0x08 0x10 # CHECK: sel.d $f0, $f1, $f2
0x46 0x02 0x08 0x10 # CHECK: sel.s $f0, $f1, $f2
0x00 0x64 0x10 0x35 # CHECK: seleqz $2, $3, $4
0x00 0x64 0x10 0x37 # CHECK: selnez $2, $3, $4
0x46 0x04 0x10 0x1d # CHECK: max.s $f0, $f2, $f4
0x46 0x24 0x10 0x1d # CHECK: max.d $f0, $f2, $f4
0x46 0x04 0x10 0x1c # CHECK: min.s $f0, $f2, $f4
0x46 0x24 0x10 0x1c # CHECK: min.d $f0, $f2, $f4
0x46 0x04 0x10 0x1f # CHECK: maxa.s $f0, $f2, $f4
0x46 0x24 0x10 0x1f # CHECK: maxa.d $f0, $f2, $f4
0x46 0x04 0x10 0x1e # CHECK: mina.s $f0, $f2, $f4
0x46 0x24 0x10 0x1e # CHECK: mina.d $f0, $f2, $f4
0x46 0x04 0x10 0x14 # CHECK: seleqz.s $f0, $f2, $f4
0x46 0x24 0x10 0x14 # CHECK: seleqz.d $f0, $f2, $f4
0x46 0x04 0x10 0x17 # CHECK: selnez.s $f0, $f2, $f4
0x46 0x24 0x10 0x17 # CHECK: selnez.d $f0, $f2, $f4
0x46 0x00 0x20 0x9a # CHECK: rint.s $f2, $f4
0x46 0x20 0x20 0x9a # CHECK: rint.d $f2, $f4
0x46 0x00 0x20 0x9b # CHECK: class.s $f2, $f4
0x46 0x20 0x20 0x9b # CHECK: class.d $f2, $f4

View File

@ -0,0 +1,19 @@
# Instructions that should be valid but currently fail for known reasons (e.g.
# they aren't implemented yet).
# This test is set up to XPASS if any instruction generates an encoding.
#
# RUN: not llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 | not FileCheck %s
# CHECK-NOT: encoding
# XFAIL: *
.set noat
bovc $0, $2, 4 # TODO: bovc $0, $2, 4 # encoding: [0x20,0x40,0x00,0x01]
bovc $2, $4, 4 # TODO: bovc $2, $4, 4 # encoding: [0x20,0x82,0x00,0x01]
bnvc $0, $2, 4 # TODO: bnvc $0, $2, 4 # encoding: [0x60,0x40,0x00,0x01]
bnvc $2, $4, 4 # TODO: bnvc $2, $4, 4 # encoding: [0x60,0x82,0x00,0x01]
beqc $0, $6, 256 # TODO: beqc $6, $zero, 256 # encoding: [0x20,0xc0,0x00,0x40]
beqc $5, $0, 256 # TODO: beqc $5, $zero, 256 # encoding: [0x20,0xa0,0x00,0x40]
beqc $6, $5, 256 # TODO: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40]
bnec $0, $6, 256 # TODO: bnec $6, $zero, 256 # encoding: [0x60,0xc0,0x00,0x40]
bnec $5, $0, 256 # TODO: bnec $5, $zero, 256 # encoding: [0x60,0xa0,0x00,0x40]
bnec $6, $5, 256 # TODO: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40]

View File

@ -1,5 +1,15 @@
# Instructions that are valid # Instructions that are valid
# #
# Branches have some unusual encoding rules in MIPS32r6 so we need to test:
# rs == 0
# rs != 0
# rt == 0
# rt != 0
# rs < rt
# rs == rt
# rs > rt
# appropriately for each branch instruction
#
# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 | FileCheck %s # RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 | FileCheck %s
.set noat .set noat
@ -19,8 +29,12 @@
bc2eqz $31,8 # CHECK: bc2eqz $31, 8 # encoding: [0x49,0x3f,0x00,0x02] bc2eqz $31,8 # CHECK: bc2eqz $31, 8 # encoding: [0x49,0x3f,0x00,0x02]
bc2nez $0,8 # CHECK: bc2nez $0, 8 # encoding: [0x49,0xa0,0x00,0x02] bc2nez $0,8 # CHECK: bc2nez $0, 8 # encoding: [0x49,0xa0,0x00,0x02]
bc2nez $31,8 # CHECK: bc2nez $31, 8 # encoding: [0x49,0xbf,0x00,0x02] bc2nez $31,8 # CHECK: bc2nez $31, 8 # encoding: [0x49,0xbf,0x00,0x02]
# beqc requires rs < rt && rs != 0 but we also accept when this is not true. See also bovc
# FIXME: Testcases are in valid-xfail.s at the moment
beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40] beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40]
beqzalc $2, 1332 # CHECK: beqzalc $2, 1332 # encoding: [0x20,0x02,0x01,0x4d] beqzalc $2, 1332 # CHECK: beqzalc $2, 1332 # encoding: [0x20,0x02,0x01,0x4d]
# bnec requires rs < rt && rs != 0 but we accept when this is not true. See also bnvc
# FIXME: Testcases are in valid-xfail.s at the moment
bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40] bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40]
bnezalc $2, 1332 # CHECK: bnezalc $2, 1332 # encoding: [0x60,0x02,0x01,0x4d] bnezalc $2, 1332 # CHECK: bnezalc $2, 1332 # encoding: [0x60,0x02,0x01,0x4d]
beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90] beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90]
@ -34,6 +48,14 @@
bgtzc $5, 256 # CHECK: bgtzc $5, 256 # encoding: [0x5c,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] bitswap $4, $2 # CHECK: bitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x20]
blezalc $2, 1332 # CHECK: blezalc $2, 1332 # encoding: [0x18,0x02,0x01,0x4d] blezalc $2, 1332 # CHECK: blezalc $2, 1332 # encoding: [0x18,0x02,0x01,0x4d]
# bnvc requires that rs >= rt but we accept both. See also bnec
bnvc $0, $0, 4 # CHECK: bnvc $zero, $zero, 4 # encoding: [0x60,0x00,0x00,0x01]
bnvc $2, $0, 4 # CHECK: bnvc $2, $zero, 4 # encoding: [0x60,0x40,0x00,0x01]
bnvc $4, $2, 4 # CHECK: bnvc $4, $2, 4 # encoding: [0x60,0x82,0x00,0x01]
# bovc requires that rs >= rt but we accept both. See also beqc
bovc $0, $0, 4 # CHECK: bovc $zero, $zero, 4 # encoding: [0x20,0x00,0x00,0x01]
bovc $2, $0, 4 # CHECK: bovc $2, $zero, 4 # encoding: [0x20,0x40,0x00,0x01]
bovc $4, $2, 4 # CHECK: bovc $4, $2, 4 # encoding: [0x20,0x82,0x00,0x01]
cmp.f.s $f2,$f3,$f4 # CHECK: cmp.f.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x80] 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] cmp.f.d $f2,$f3,$f4 # CHECK: cmp.f.d $f2, $f3, $f4 # encoding: [0x46,0xa4,0x18,0x80]
cmp.un.s $f2,$f3,$f4 # CHECK: cmp.un.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x81] cmp.un.s $f2,$f3,$f4 # CHECK: cmp.un.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x81]

View File

@ -0,0 +1,19 @@
# Instructions that should be valid but currently fail for known reasons (e.g.
# they aren't implemented yet).
# This test is set up to XPASS if any instruction generates an encoding.
#
# RUN: not llvm-mc %s -triple=mips64-unknown-linux -show-encoding -mcpu=mips64r6 | not FileCheck %s
# CHECK-NOT: encoding
# XFAIL: *
.set noat
bovc $0, $2, 4 # TODO: bovc $0, $2, 4 # encoding: [0x20,0x40,0x00,0x01]
bovc $2, $4, 4 # TODO: bovc $2, $4, 4 # encoding: [0x20,0x82,0x00,0x01]
bnvc $0, $2, 4 # TODO: bnvc $0, $2, 4 # encoding: [0x60,0x40,0x00,0x01]
bnvc $2, $4, 4 # TODO: bnvc $2, $4, 4 # encoding: [0x60,0x82,0x00,0x01]
beqc $0, $6, 256 # TODO: beqc $6, $zero, 256 # encoding: [0x20,0xc0,0x00,0x40]
beqc $5, $0, 256 # TODO: beqc $5, $zero, 256 # encoding: [0x20,0xa0,0x00,0x40]
beqc $6, $5, 256 # TODO: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40]
bnec $0, $6, 256 # TODO: bnec $6, $zero, 256 # encoding: [0x60,0xc0,0x00,0x40]
bnec $5, $0, 256 # TODO: bnec $5, $zero, 256 # encoding: [0x60,0xa0,0x00,0x40]
bnec $6, $5, 256 # TODO: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40]

View File

@ -1,5 +1,15 @@
# Instructions that are valid # Instructions that are valid
# #
# Branches have some unusual encoding rules in MIPS32r6 so we need to test:
# rs == 0
# rs != 0
# rt == 0
# rt != 0
# rs < rt
# rs == rt
# rs > rt
# appropriately for each branch instruction
#
# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r6 | FileCheck %s # RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips64r6 | FileCheck %s
.set noat .set noat
@ -19,8 +29,12 @@
bc2eqz $31,8 # CHECK: bc2eqz $31, 8 # encoding: [0x49,0x3f,0x00,0x02] bc2eqz $31,8 # CHECK: bc2eqz $31, 8 # encoding: [0x49,0x3f,0x00,0x02]
bc2nez $0,8 # CHECK: bc2nez $0, 8 # encoding: [0x49,0xa0,0x00,0x02] bc2nez $0,8 # CHECK: bc2nez $0, 8 # encoding: [0x49,0xa0,0x00,0x02]
bc2nez $31,8 # CHECK: bc2nez $31, 8 # encoding: [0x49,0xbf,0x00,0x02] bc2nez $31,8 # CHECK: bc2nez $31, 8 # encoding: [0x49,0xbf,0x00,0x02]
# beqc requires rs < rt && rs != 0 but we also accept when this is not true. See also bovc
# FIXME: Testcases are in valid-xfail.s at the moment
beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40] beqc $5, $6, 256 # CHECK: beqc $5, $6, 256 # encoding: [0x20,0xa6,0x00,0x40]
beqzalc $2, 1332 # CHECK: beqzalc $2, 1332 # encoding: [0x20,0x02,0x01,0x4d] beqzalc $2, 1332 # CHECK: beqzalc $2, 1332 # encoding: [0x20,0x02,0x01,0x4d]
# bnec requires rs < rt && rs != 0 but we accept when this is not true. See also bnvc
# FIXME: Testcases are in valid-xfail.s at the moment
bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40] bnec $5, $6, 256 # CHECK: bnec $5, $6, 256 # encoding: [0x60,0xa6,0x00,0x40]
bnezalc $2, 1332 # CHECK: bnezalc $2, 1332 # encoding: [0x60,0x02,0x01,0x4d] bnezalc $2, 1332 # CHECK: bnezalc $2, 1332 # encoding: [0x60,0x02,0x01,0x4d]
beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90] beqzc $5, 72256 # CHECK: beqzc $5, 72256 # encoding: [0xd8,0xa0,0x46,0x90]
@ -34,6 +48,14 @@
bgtzc $5, 256 # CHECK: bgtzc $5, 256 # encoding: [0x5c,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] bitswap $4, $2 # CHECK: bitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x20]
blezalc $2, 1332 # CHECK: blezalc $2, 1332 # encoding: [0x18,0x02,0x01,0x4d] blezalc $2, 1332 # CHECK: blezalc $2, 1332 # encoding: [0x18,0x02,0x01,0x4d]
# bnvc requires that rs >= rt but we accept both. See also bnec
bnvc $0, $0, 4 # CHECK: bnvc $zero, $zero, 4 # encoding: [0x60,0x00,0x00,0x01]
bnvc $2, $0, 4 # CHECK: bnvc $2, $zero, 4 # encoding: [0x60,0x40,0x00,0x01]
bnvc $4, $2, 4 # CHECK: bnvc $4, $2, 4 # encoding: [0x60,0x82,0x00,0x01]
# bovc requires that rs >= rt but we accept both. See also beqc
bovc $0, $0, 4 # CHECK: bovc $zero, $zero, 4 # encoding: [0x20,0x00,0x00,0x01]
bovc $2, $0, 4 # CHECK: bovc $2, $zero, 4 # encoding: [0x20,0x40,0x00,0x01]
bovc $4, $2, 4 # CHECK: bovc $4, $2, 4 # encoding: [0x20,0x82,0x00,0x01]
cmp.f.s $f2,$f3,$f4 # CHECK: cmp.f.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x80] 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] cmp.f.d $f2,$f3,$f4 # CHECK: cmp.f.d $f2, $f3, $f4 # encoding: [0x46,0xa4,0x18,0x80]
cmp.un.s $f2,$f3,$f4 # CHECK: cmp.un.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x81] cmp.un.s $f2,$f3,$f4 # CHECK: cmp.un.s $f2, $f3, $f4 # encoding: [0x46,0x84,0x18,0x81]
@ -68,9 +90,9 @@
cmp.ngt.d $f2,$f3,$f4 # CHECK: cmp.ngt.d $f2, $f3, $f4 # encoding: [0x46,0xa4,0x18,0x8f] cmp.ngt.d $f2,$f3,$f4 # CHECK: cmp.ngt.d $f2, $f3, $f4 # encoding: [0x46,0xa4,0x18,0x8f]
dalign $4,$2,$3,5 # CHECK: dalign $4, $2, $3, 5 # encoding: [0x7c,0x43,0x23,0x64] dalign $4,$2,$3,5 # CHECK: dalign $4, $2, $3, 5 # encoding: [0x7c,0x43,0x23,0x64]
daui $3,$2,0x1234 # CHECK: daui $3, $2, 4660 # encoding: [0x74,0x62,0x12,0x34] daui $3,$2,0x1234 # CHECK: daui $3, $2, 4660 # encoding: [0x74,0x62,0x12,0x34]
dahi $3,$3,0x5678 # CHECK: dahi $3, $3, 22136 # encoding: [0x04,0x66,0x56,0x78] dahi $3,0x5678 # CHECK: dahi $3, 22136 # encoding: [0x04,0x66,0x56,0x78]
dati $3,$3,0xabcd # CHECK: dati $3, $3, 43981 # encoding: [0x04,0x7e,0xab,0xcd] dati $3,0xabcd # CHECK: dati $3, 43981 # encoding: [0x04,0x7e,0xab,0xcd]
dbitswap $4, $2 # CHECK: bitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x24] dbitswap $4, $2 # CHECK: dbitswap $4, $2 # encoding: [0x7c,0x02,0x20,0x24]
div $2,$3,$4 # CHECK: div $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9a] div $2,$3,$4 # CHECK: div $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9a]
divu $2,$3,$4 # CHECK: divu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9b] divu $2,$3,$4 # CHECK: divu $2, $3, $4 # encoding: [0x00,0x64,0x10,0x9b]
jialc $5, 256 # CHECK: jialc $5, 256 # encoding: [0xf8,0x05,0x01,0x00] jialc $5, 256 # CHECK: jialc $5, 256 # encoding: [0xf8,0x05,0x01,0x00]