Skip to content

[SPARC][IAS] Add definitions for OSA 2011 instructions #138403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
Original file line number Diff line number Diff line change
@@ -261,6 +261,8 @@ DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,

static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder);
static DecodeStatus DecodeSIMM5(MCInst &Inst, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder);
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder);
template <unsigned N>
@@ -336,6 +338,13 @@ static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,
return MCDisassembler::Success;
}

static DecodeStatus DecodeSIMM5(MCInst &MI, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder) {
assert(isUInt<5>(insn));
MI.addOperand(MCOperand::createImm(SignExtend64<5>(insn)));
return MCDisassembler::Success;
}

static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,
const MCDisassembler *Decoder) {
assert(isUInt<13>(insn));
18 changes: 18 additions & 0 deletions llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Original file line number Diff line number Diff line change
@@ -50,6 +50,18 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
return (d16hi << 20) | d16lo;
}

case ELF::R_SPARC_WDISP10: {
// FIXME this really should be an error reporting check.
assert((Value & 0x3) == 0);

// 7.17 Compare and Branch
// Inst{20-19} = d10hi;
// Inst{12-5} = d10lo;
unsigned d10hi = (Value >> 10) & 0x3;
unsigned d10lo = (Value >> 2) & 0xff;
return (d10hi << 19) | (d10lo << 5);
}

case ELF::R_SPARC_HIX22:
return (~Value >> 10) & 0x3fffff;

@@ -61,6 +73,9 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
case Sparc::fixup_sparc_13:
return Value & 0x1fff;

case ELF::R_SPARC_5:
return Value & 0x1f;

case ELF::R_SPARC_LOX10:
return (Value & 0x3ff) | 0x1c00;

@@ -163,6 +178,9 @@ namespace {
case ELF::R_SPARC_PC22:
Info = {"", 10, 22, MCFixupKindInfo::FKF_IsPCRel};
break;
case ELF::R_SPARC_WDISP10:
Info = {"", 0, 32, MCFixupKindInfo::FKF_IsPCRel};
break;
case ELF::R_SPARC_WDISP16:
Info = {"", 0, 32, MCFixupKindInfo::FKF_IsPCRel};
break;
3 changes: 2 additions & 1 deletion llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

#include "llvm/MC/MCFixup.h"

// clang-format off
namespace llvm {
namespace Sparc {
// clang-format off
@@ -28,5 +29,5 @@ namespace llvm {
// clang-format on
}
}

// clang-format on
#endif
43 changes: 43 additions & 0 deletions llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
@@ -72,6 +72,9 @@ class SparcMCCodeEmitter : public MCCodeEmitter {
unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSImm5OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
@@ -81,6 +84,9 @@ class SparcMCCodeEmitter : public MCCodeEmitter {
unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getCompareAndBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
};

} // end anonymous namespace
@@ -141,6 +147,31 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
return 0;
}

unsigned SparcMCCodeEmitter::getSImm5OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNo);

if (MO.isImm())
return MO.getImm();

assert(MO.isExpr() &&
"getSImm5OpValue expects only expressions or an immediate");

const MCExpr *Expr = MO.getExpr();

// Constant value, no fixup is needed
if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
return CE->getValue();

if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
Fixups.push_back(MCFixup::create(0, Expr, SExpr->getFixupKind()));
return 0;
}
Fixups.push_back(MCFixup::create(0, Expr, ELF::R_SPARC_5));
return 0;
}

unsigned
SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
@@ -217,6 +248,18 @@ unsigned SparcMCCodeEmitter::getBranchOnRegTargetOpValue(
return 0;
}

unsigned SparcMCCodeEmitter::getCompareAndBranchTargetOpValue(
const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
const MCOperand &MO = MI.getOperand(OpNo);
if (MO.isImm())
return getMachineOpValue(MI, MO, Fixups, STI);

Fixups.push_back(MCFixup::create(0, MO.getExpr(), ELF::R_SPARC_WDISP10));

return 0;
}

#include "SparcGenMCCodeEmitter.inc"

MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
5 changes: 4 additions & 1 deletion llvm/lib/Target/Sparc/Sparc.td
Original file line number Diff line number Diff line change
@@ -55,6 +55,9 @@ def FeatureUA2005
def FeatureUA2007
: SubtargetFeature<"ua2007", "IsUA2007", "true",
"Enable UltraSPARC Architecture 2007 extensions">;
def FeatureOSA2011
: SubtargetFeature<"osa2011", "IsOSA2011", "true",
"Enable Oracle SPARC Architecture 2011 extensions">;
def FeatureLeon
: SubtargetFeature<"leon", "IsLeon", "true",
"Enable LEON extensions">;
@@ -166,7 +169,7 @@ def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc,
FeatureUA2005, FeatureUA2007]>;
def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc,
FeatureVIS, FeatureVIS2, FeatureVIS3,
FeatureUA2005, FeatureUA2007]>;
FeatureUA2005, FeatureUA2007, FeatureOSA2011]>;

// LEON 2 FT generic
def : Processor<"leon2", LEON2Itineraries,
63 changes: 63 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrAliases.td
Original file line number Diff line number Diff line change
@@ -331,6 +331,25 @@ multiclass reg_cond_alias<string rcond, int condVal> {
Requires<[Is64Bit]>;
}

// Instruction aliases for compare-and-branch.
multiclass cwb_cond_alias<string cond, int condVal> {
def : InstAlias<"cwb" # cond # " $rs1, $rs2, $imm",
(CWBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
Requires<[HasOSA2011]>;
def : InstAlias<"cwb" # cond # " $rs1, $simm5, $imm",
(CWBCONDri cbtarget:$imm, condVal, IntRegs:$rs1, simm5Op:$simm5)>,
Requires<[HasOSA2011]>;
}

multiclass cxb_cond_alias<string cond, int condVal> {
def : InstAlias<"cxb" # cond # " $rs1, $rs2, $imm",
(CXBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
Requires<[HasOSA2011]>;
def : InstAlias<"cxb" # cond # " $rs1, $simm5, $imm",
(CXBCONDri cbtarget:$imm, condVal, IntRegs:$rs1, simm5Op:$simm5)>,
Requires<[HasOSA2011]>;
}

defm : int_cond_alias<"a", 0b1000>;
defm : int_cond_alias<"n", 0b0000>;
defm : int_cond_alias<"ne", 0b1001>;
@@ -408,6 +427,44 @@ defm : reg_cond_alias<"ne", 0b101>;
defm : reg_cond_alias<"gz", 0b110>;
defm : reg_cond_alias<"gez", 0b111>;

defm : cwb_cond_alias<"ne", 0b1001>;
defm : cwb_cond_alias<"e", 0b0001>;
defm : cwb_cond_alias<"g", 0b1010>;
defm : cwb_cond_alias<"le", 0b0010>;
defm : cwb_cond_alias<"ge", 0b1011>;
defm : cwb_cond_alias<"l", 0b0011>;
defm : cwb_cond_alias<"gu", 0b1100>;
defm : cwb_cond_alias<"leu", 0b0100>;
defm : cwb_cond_alias<"cc", 0b1101>;
defm : cwb_cond_alias<"cs", 0b0101>;
defm : cwb_cond_alias<"pos", 0b1110>;
defm : cwb_cond_alias<"neg", 0b0110>;
defm : cwb_cond_alias<"vc", 0b1111>;
defm : cwb_cond_alias<"vs", 0b0111>;
let EmitPriority = 0 in {
defm : cwb_cond_alias<"geu", 0b1101>; // same as cc
defm : cwb_cond_alias<"lu", 0b0101>; // same as cs
}

defm : cxb_cond_alias<"ne", 0b1001>;
defm : cxb_cond_alias<"e", 0b0001>;
defm : cxb_cond_alias<"g", 0b1010>;
defm : cxb_cond_alias<"le", 0b0010>;
defm : cxb_cond_alias<"ge", 0b1011>;
defm : cxb_cond_alias<"l", 0b0011>;
defm : cxb_cond_alias<"gu", 0b1100>;
defm : cxb_cond_alias<"leu", 0b0100>;
defm : cxb_cond_alias<"cc", 0b1101>;
defm : cxb_cond_alias<"cs", 0b0101>;
defm : cxb_cond_alias<"pos", 0b1110>;
defm : cxb_cond_alias<"neg", 0b0110>;
defm : cxb_cond_alias<"vc", 0b1111>;
defm : cxb_cond_alias<"vs", 0b0111>;
let EmitPriority = 0 in {
defm : cxb_cond_alias<"geu", 0b1101>; // same as cc
defm : cxb_cond_alias<"lu", 0b0101>; // same as cs
}

// Section A.3 Synthetic Instructions

// Most are marked as Emit=0, so that they are not used for disassembly. This is
@@ -665,3 +722,9 @@ def : InstAlias<"signx $rs1, $rd", (SRArr IntRegs:$rd, IntRegs:$rs1, G0), 0>, Re

// sir -> sir 0
def : InstAlias<"sir", (SIR 0), 0>;

// pause reg_or_imm -> wrasr %g0, reg_or_imm, %asr27
let Predicates = [HasOSA2011] in {
def : InstAlias<"pause $rs2", (WRASRrr ASR27, G0, IntRegs:$rs2), 1>;
def : InstAlias<"pause $simm13", (WRASRri ASR27, G0, simm13Op:$simm13), 1>;
} // Predicates = [HasOSA2011]
43 changes: 43 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrFormats.td
Original file line number Diff line number Diff line change
@@ -102,6 +102,49 @@ class F2_4<bit annul, bit pred, dag outs, dag ins,
let Inst{13-0} = imm16{13-0};
}

class F2_5<bit cc, dag outs, dag ins, string asmstr,
list<dag> pattern = [], InstrItinClass itin = NoItinerary>
: InstSP<outs, ins, asmstr, pattern, itin> {
bits<10> imm10;
bits<5> rs1;
bits<5> rs2;
bits<4> cond;

let op = 0; // op = 0

let Inst{29} = cond{3};
let Inst{28} = 1;
let Inst{27-25} = cond{2-0};
let Inst{24-22} = 0b011;
let Inst{21} = cc;
let Inst{20-19} = imm10{9-8};
let Inst{18-14} = rs1;
let Inst{13} = 0; // i = 0
let Inst{12-5} = imm10{7-0};
let Inst{4-0} = rs2;
}

class F2_6<bit cc, dag outs, dag ins, string asmstr,
list<dag> pattern = [], InstrItinClass itin = NoItinerary>
: InstSP<outs, ins, asmstr, pattern, itin> {
bits<10> imm10;
bits<5> rs1;
bits<5> simm5;
bits<4> cond;

let op = 0; // op = 0

let Inst{29} = cond{3};
let Inst{28} = 1;
let Inst{27-25} = cond{2-0};
let Inst{24-22} = 0b011;
let Inst{21} = cc;
let Inst{20-19} = imm10{9-8};
let Inst{18-14} = rs1;
let Inst{13} = 1; // i = 1
let Inst{12-5} = imm10{7-0};
let Inst{4-0} = simm5;
}

//===----------------------------------------------------------------------===//
// Format #3 instruction classes in the Sparc
19 changes: 19 additions & 0 deletions llvm/lib/Target/Sparc/SparcInstrInfo.td
Original file line number Diff line number Diff line change
@@ -55,6 +55,10 @@ def HasUA2005 : Predicate<"Subtarget->isUA2005()">,
def HasUA2007 : Predicate<"Subtarget->isUA2007()">,
AssemblerPredicate<(all_of FeatureUA2007)>;

// HasOSA2011 - This is true when the target processor has OSA 2011 extensions.
def HasOSA2011 : Predicate<"Subtarget->isOSA2011()">,
AssemblerPredicate<(all_of FeatureOSA2011)>;

// HasHardQuad - This is true when the target processor supports quad floating
// point instructions.
def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
@@ -93,6 +97,8 @@ def UseDeprecatedInsts : Predicate<"Subtarget->useV8DeprecatedInsts()">;
// FIXME these should have AsmOperandClass.
def uimm3 : PatLeaf<(imm), [{ return isUInt<3>(N->getZExtValue()); }]>;

def simm5 : PatLeaf<(imm), [{ return isInt<5>(N->getSExtValue()); }]>;

def simm10 : PatLeaf<(imm), [{ return isInt<10>(N->getSExtValue()); }]>;

def simm11 : PatLeaf<(imm), [{ return isInt<11>(N->getSExtValue()); }]>;
@@ -153,6 +159,12 @@ def SparcMEMriAsmOperand : AsmOperandClass {
let ParserMethod = "parseMEMOperand";
}

def simm5Op : Operand<iPTR> {
let OperandType = "OPERAND_IMMEDIATE";
let DecoderMethod = "DecodeSIMM5";
let EncoderMethod = "getSImm5OpValue";
}

def simm13Op : Operand<iPTR> {
let OperandType = "OPERAND_IMMEDIATE";
let DecoderMethod = "DecodeSIMM13";
@@ -246,6 +258,13 @@ def bprtarget16 : Operand<OtherVT> {
let OperandType = "OPERAND_PCREL";
}

def cbtarget : Operand<OtherVT> {
let EncoderMethod = "getCompareAndBranchTargetOpValue";
let DecoderMethod = "DecodeDisp<10>";
let PrintMethod = "printCTILabel";
let OperandType = "OPERAND_PCREL";
}

def SparcCallTargetAsmOperand : AsmOperandClass {
let Name = "CallTarget";
let ParserMethod = "parseCallTarget";
23 changes: 22 additions & 1 deletion llvm/lib/Target/Sparc/SparcInstrUAOSA.td
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
//
// This file contains instruction formats, definitions and patterns needed for
// UA 2005 and UA 2007 instructions on SPARC.
// UA 2005, UA 2007, and OSA 2011 instructions on SPARC.
//===----------------------------------------------------------------------===//

class UA2005RegWin<string asmstr, bits<5> fcn>
@@ -23,6 +23,16 @@ class FourOp<string OpcStr, bits<6> op3val, bits<4> op5val,
: F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, RC:$rs3),
!strconcat(OpcStr, " $rs1, $rs2, $rs3, $rd")>;

/// F2_56 multiclass - Define a F2_5/F2_6 pattern in one shot.
multiclass F2_56<string OpcStr, bits<1> cc> {
def rr : F2_5<cc, (outs),
(ins cbtarget:$imm10, CCOp:$cond, IntRegs:$rs1, IntRegs:$rs2),
!strconcat(OpcStr, "$cond $rs1, $rs2, $imm10")>;
def ri : F2_6<cc, (outs),
(ins cbtarget:$imm10, CCOp:$cond, IntRegs:$rs1, simm5Op:$simm5),
!strconcat(OpcStr, "$cond $rs1, $simm5, $imm10")>;
}

// UltraSPARC Architecture 2005 Instructions
let Predicates = [HasUA2005] in {
let hasSideEffects = 1 in {
@@ -45,3 +55,14 @@ def FNMADDD : FourOp<"fnmaddd", 0b110111, 0b1110, DFPRegs>;
def FNMSUBS : FourOp<"fnmsubs", 0b110111, 0b1001, FPRegs>;
def FNMSUBD : FourOp<"fnmsubd", 0b110111, 0b1010, DFPRegs>;
} // Predicates = [HasUA2007]

// Oracle SPARC Architecture 2011 Instructions
let Predicates = [HasOSA2011] in {
let isBranch = 1, isTerminator = 1, hasDelaySlot = 0 in {
defm CWBCOND : F2_56<"cwb", 0>;
defm CXBCOND : F2_56<"cxb", 1>;
}

def FPMADDX : FourOp<"fpmaddx", 0b110111, 0b0000, DFPRegs>;
def FPMADDXHI : FourOp<"fpmaddxhi", 0b110111, 0b0100, DFPRegs>;
} // Predicates = [HasOSA2011]
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.