[Sparc] Add support for parsing fcmp with %fcc registers.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202610 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Venkatraman Govindaraju 2014-03-02 03:39:39 +00:00
parent 80949c599f
commit afad335cae
11 changed files with 99 additions and 18 deletions

View File

@ -68,7 +68,8 @@ class SparcAsmParser : public MCTargetAsmParser {
StringRef Name);
OperandMatchResultTy
parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false);
parseSparcAsmOperand(SparcOperand *&Operand, bool isCall = false,
bool createTokenForFCC = true);
OperandMatchResultTy
parseBranchModifiers(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
@ -631,7 +632,10 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
}
SparcOperand *Op = 0;
ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"));
bool createTokenForFCC = !(Mnemonic == "fcmps" || Mnemonic == "fcmpd"
|| Mnemonic == "fcmpq");
ResTy = parseSparcAsmOperand(Op, (Mnemonic == "call"), createTokenForFCC);
if (ResTy != MatchOperand_Success || !Op)
return MatchOperand_ParseFail;
@ -642,7 +646,8 @@ parseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
}
SparcAsmParser::OperandMatchResultTy
SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall,
bool createTokenForFCC)
{
SMLoc S = Parser.getTok().getLoc();
@ -677,9 +682,11 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op, bool isCall)
break;
case Sparc::FCC0:
assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
Op = SparcOperand::CreateToken("%fcc0", S);
break;
if (createTokenForFCC) {
assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
Op = SparcOperand::CreateToken("%fcc0", S);
break;
}
}
break;
}
@ -783,7 +790,7 @@ bool SparcAsmParser::matchRegisterName(const AsmToken &Tok,
&& !name.substr(3).getAsInteger(10, intVal)
&& intVal < 4) {
// FIXME: check 64bit and handle %fcc1 - %fcc3
RegNo = Sparc::FCC0;
RegNo = Sparc::FCC0 + intVal;
RegKind = SparcOperand::rk_CCReg;
return true;
}

View File

@ -113,6 +113,9 @@ static const unsigned QFPRegDecoderTable[] = {
SP::Q6, SP::Q14, ~0U, ~0U,
SP::Q7, SP::Q15, ~0U, ~0U } ;
static const unsigned FCCRegDecoderTable[] = {
SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
unsigned RegNo,
uint64_t Address,
@ -174,6 +177,16 @@ static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
return MCDisassembler::Success;
}
static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder) {
if (RegNo > 3)
return MCDisassembler::Fail;
Inst.addOperand(MCOperand::CreateReg(FCCRegDecoderTable[RegNo]));
return MCDisassembler::Success;
}
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
const void *Decoder);
static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,

View File

@ -32,6 +32,10 @@ namespace Sparc {
#define PRINT_ALIAS_INSTR
#include "SparcGenAsmWriter.inc"
bool SparcInstPrinter::isV9() const {
return (STI.getFeatureBits() & Sparc::FeatureV9) != 0;
}
void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
{
OS << '%' << StringRef(getRegisterName(RegNo)).lower();
@ -65,6 +69,26 @@ bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O)
return true;
}
}
case SP::V9FCMPS:
case SP::V9FCMPD:
case SP::V9FCMPQ: {
if (isV9()
|| (MI->getNumOperands() != 3)
|| (!MI->getOperand(0).isReg())
|| (MI->getOperand(0).getReg() != SP::FCC0))
return false;
// if V8, skip printing %fcc0.
switch(MI->getOpcode()) {
default:
case SP::V9FCMPS: O << "\tfcmps "; break;
case SP::V9FCMPD: O << "\tfcmpd "; break;
case SP::V9FCMPQ: O << "\tfcmpq "; break;
}
printOperand(MI, 1, O);
O << ", ";
printOperand(MI, 2, O);
return true;
}
}
}

View File

@ -15,21 +15,25 @@
#define SparcINSTPRINTER_H
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCSubtargetInfo.h"
namespace llvm {
class MCOperand;
class SparcInstPrinter : public MCInstPrinter {
const MCSubtargetInfo &STI;
public:
SparcInstPrinter(const MCAsmInfo &MAI,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI)
: MCInstPrinter(MAI, MII, MRI) {}
const MCRegisterInfo &MRI,
const MCSubtargetInfo &sti)
: MCInstPrinter(MAI, MII, MRI), STI(sti) {}
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
bool printSparcAliasInstr(const MCInst *MI, raw_ostream &OS);
bool isV9() const;
// Autogenerated by tblgen.
void printInstruction(const MCInst *MI, raw_ostream &O);

View File

@ -153,7 +153,7 @@ static MCInstPrinter *createSparcMCInstPrinter(const Target &T,
const MCInstrInfo &MII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI) {
return new SparcInstPrinter(MAI, MII, MRI);
return new SparcInstPrinter(MAI, MII, MRI, STI);
}
extern "C" void LLVMInitializeSparcTargetMC() {

View File

@ -228,3 +228,9 @@ def : MnemonicAlias<"addccc", "addxcc">, Requires<[HasV9]>;
def : MnemonicAlias<"subc", "subx">, Requires<[HasV9]>;
def : MnemonicAlias<"subccc", "subxcc">, Requires<[HasV9]>;
def : InstAlias<"fcmps $rs1, $rs2", (V9FCMPS FCC0, FPRegs:$rs1, FPRegs:$rs2)>;
def : InstAlias<"fcmpd $rs1, $rs2", (V9FCMPD FCC0, DFPRegs:$rs1, DFPRegs:$rs2)>;
def : InstAlias<"fcmpq $rs1, $rs2", (V9FCMPQ FCC0, QFPRegs:$rs1, QFPRegs:$rs2)>,
Requires<[HasHardQuad]>;

View File

@ -153,7 +153,6 @@ class F3_3c<bits<2> opVal, bits<6> op3val, bits<9> opfval, dag outs, dag ins,
let op = opVal;
let op3 = op3val;
let rd = 0;
let Inst{13-5} = opfval; // fp opcode
let Inst{4-0} = rs2;

View File

@ -864,7 +864,7 @@ def FDIVQ : F3_3<2, 0b110100, 0b001001111,
// This behavior is modeled with a forced noop after the instruction in
// DelaySlotFiller.
let Defs = [FCC0] in {
let Defs = [FCC0], rd = 0, isCodeGenOnly = 1 in {
def FCMPS : F3_3c<2, 0b110101, 0b001010001,
(outs), (ins FPRegs:$rs1, FPRegs:$rs2),
"fcmps $rs1, $rs2",
@ -1014,6 +1014,19 @@ let Predicates = [HasV9] in {
Requires<[HasHardQuad]>;
}
// Floating-point compare instruction with %fcc0-%fcc1
def V9FCMPS : F3_3c<2, 0b110101, 0b001010001,
(outs FCCRegs:$rd), (ins FPRegs:$rs1, FPRegs:$rs2),
"fcmps $rd, $rs1, $rs2", []>;
def V9FCMPD : F3_3c<2, 0b110101, 0b001010010,
(outs FCCRegs:$rd), (ins DFPRegs:$rs1, DFPRegs:$rs2),
"fcmpd $rd, $rs1, $rs2", []>;
def V9FCMPQ : F3_3c<2, 0b110101, 0b001010011,
(outs FCCRegs:$rd), (ins QFPRegs:$rs1, QFPRegs:$rs2),
"fcmpq $rd, $rs1, $rs2", []>,
Requires<[HasHardQuad]>;
// POPCrr - This does a ctpop of a 64-bit register. As such, we have to clear
// the top 32-bits before using it. To do this clearing, we use a SRLri X,0.
let rs1 = 0 in

View File

@ -120,13 +120,13 @@
# CHECK: fdivq %f0, %f4, %f8
0x91 0xa0 0x09 0xe4
# CHECK: fcmps %f0, %f4
# CHECK: fcmps %fcc0, %f0, %f4
0x81 0xa8 0x0a 0x24
# CHECK: fcmpd %f0, %f4
# CHECK: fcmpd %fcc0, %f0, %f4
0x81 0xa8 0x0a 0x44
# CHECK: fcmpq %f0, %f4
# CHECK: fcmpq %fcc0, %f0, %f4
0x81 0xa8 0x0a 0x64
# CHECK: fxtos %f0, %f4

View File

@ -96,13 +96,20 @@
fdivd %f0, %f4, %f8
fdivq %f0, %f4, %f8
! CHECK: fcmps %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x24]
! CHECK: fcmpd %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x44]
! CHECK: fcmpq %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x64]
! CHECK: fcmps %fcc0, %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x24]
! CHECK: fcmpd %fcc0, %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x44]
! CHECK: fcmpq %fcc0, %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x64]
fcmps %f0, %f4
fcmpd %f0, %f4
fcmpq %f0, %f4
! CHECK: fcmps %fcc2, %f0, %f4 ! encoding: [0x85,0xa8,0x0a,0x24]
! CHECK: fcmpd %fcc2, %f0, %f4 ! encoding: [0x85,0xa8,0x0a,0x44]
! CHECK: fcmpq %fcc2, %f0, %f4 ! encoding: [0x85,0xa8,0x0a,0x64]
fcmps %fcc2, %f0, %f4
fcmpd %fcc2, %f0, %f4
fcmpq %fcc2, %f0, %f4
! CHECK: fxtos %f0, %f4 ! encoding: [0x89,0xa0,0x10,0x80]
! CHECK: fxtod %f0, %f4 ! encoding: [0x89,0xa0,0x11,0x00]
! CHECK: fxtoq %f0, %f4 ! encoding: [0x89,0xa0,0x11,0x80]

View File

@ -0,0 +1,8 @@
! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
! CHECK: fcmps %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x24]
! CHECK: fcmpd %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x44]
! CHECK: fcmpq %f0, %f4 ! encoding: [0x81,0xa8,0x0a,0x64]
fcmps %f0, %f4
fcmpd %f0, %f4
fcmpq %f0, %f4