mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
[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:
parent
80949c599f
commit
afad335cae
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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]>;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
8
test/MC/Sparc/sparcv8-instructions.s
Normal file
8
test/MC/Sparc/sparcv8-instructions.s
Normal 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
|
Loading…
Reference in New Issue
Block a user