-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[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
base: users/koachan/spr/main.sparcias-add-definitions-for-osa-2011-instructions
Are you sure you want to change the base?
Conversation
Created using spr 1.3.5
@llvm/pr-subscribers-backend-sparc @llvm/pr-subscribers-llvm-binary-utilities Author: Koakuma (koachan) ChangesPatch is 56.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138403.diff 15 Files Affected:
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
index 7e01a4a8a0a06..b87949ab199b5 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
@@ -87,3 +87,4 @@ ELF_RELOC(R_SPARC_GOTDATA_LOX10, 81)
ELF_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82)
ELF_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83)
ELF_RELOC(R_SPARC_GOTDATA_OP, 84)
+ELF_RELOC(R_SPARC_WDISP10, 88)
diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
index 828d638723587..c42e173379a39 100644
--- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
@@ -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);
@@ -340,6 +342,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));
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index cc8b86e6135b5..d37724699be5d 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -50,6 +50,15 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
return (d16hi << 20) | d16lo;
}
+ case Sparc::fixup_sparc_br10: {
+ // 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 Sparc::fixup_sparc_hix22:
return (~Value >> 10) & 0x3fffff;
@@ -162,11 +171,13 @@ namespace {
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {
const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
+ // clang-format off
// name offset bits flags
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br16", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br10", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_13", 19, 13, 0 },
{ "fixup_sparc_hi22", 10, 22, 0 },
{ "fixup_sparc_lo10", 22, 10, 0 },
@@ -205,14 +216,17 @@ namespace {
{ "fixup_sparc_gotdata_hix22", 0, 0, 0 },
{ "fixup_sparc_gotdata_lox10", 0, 0, 0 },
{ "fixup_sparc_gotdata_op", 0, 0, 0 },
+ // clang-format on
};
const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
+ // clang-format off
// name offset bits flags
{ "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br16", 32, 0, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br10", 32, 0, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_13", 0, 13, 0 },
{ "fixup_sparc_hi22", 0, 22, 0 },
{ "fixup_sparc_lo10", 0, 10, 0 },
@@ -251,6 +265,7 @@ namespace {
{ "fixup_sparc_gotdata_hix22", 0, 0, 0 },
{ "fixup_sparc_gotdata_lox10", 0, 0, 0 },
{ "fixup_sparc_gotdata_op", 0, 0, 0 },
+ // clang-format on
};
// Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index f95e5ac1664e6..6b6d352c7736b 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -84,6 +84,8 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
case Sparc::fixup_sparc_br16:
return ELF::R_SPARC_WDISP16;
+ case Sparc::fixup_sparc_br10:
+ return ELF::R_SPARC_WDISP10;
case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22;
case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10;
case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30;
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
index 3b91326589894..ec8f78cd63812 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -11,6 +11,7 @@
#include "llvm/MC/MCFixup.h"
+// clang-format off
namespace llvm {
namespace Sparc {
enum Fixups {
@@ -28,6 +29,9 @@ namespace llvm {
/// fixup_sparc_bpr - 16-bit fixup for bpr
fixup_sparc_br16,
+ /// fixup_sparc_br10 - 10-bit fixup for cbcond
+ fixup_sparc_br10,
+
/// fixup_sparc_13 - 13-bit fixup
fixup_sparc_13,
@@ -112,5 +116,5 @@ namespace llvm {
};
}
}
-
+// clang-format on
#endif
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index 0c9ba6a8a297c..06721db60cdd6 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -71,6 +71,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;
@@ -80,6 +83,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,26 @@ 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();
+
+ llvm_unreachable("simm5 operands can only be used with constants!");
+}
+
unsigned
SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
@@ -239,6 +265,19 @@ getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
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.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups, STI);
+
+ Fixups.push_back(
+ MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br10));
+
+ return 0;
+}
+
#include "SparcGenMCCodeEmitter.inc"
MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 93c3098bd89fe..6e6c887e60e12 100644
--- a/llvm/lib/Target/Sparc/Sparc.td
+++ b/llvm/lib/Target/Sparc/Sparc.td
@@ -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,
diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index 590395c16965b..fa2c62101d30e 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -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<!strconcat(!strconcat("cwb", cond), " $rs1, $rs2, $imm"),
+ (CWBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
+ Requires<[HasOSA2011]>;
+ def : InstAlias<!strconcat(!strconcat("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<!strconcat(!strconcat("cxb", cond), " $rs1, $rs2, $imm"),
+ (CXBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
+ Requires<[HasOSA2011]>;
+ def : InstAlias<!strconcat(!strconcat("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,46 @@ 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 +724,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]
diff --git a/llvm/lib/Target/Sparc/SparcInstrFormats.td b/llvm/lib/Target/Sparc/SparcInstrFormats.td
index 2998f53ef2dbc..fe10bb443348a 100644
--- a/llvm/lib/Target/Sparc/SparcInstrFormats.td
+++ b/llvm/lib/Target/Sparc/SparcInstrFormats.td
@@ -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
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 057eafd734e71..c14d72b33c08c 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -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()); }]>;
@@ -231,6 +237,10 @@ def bprtarget16 : Operand<OtherVT> {
let EncoderMethod = "getBranchOnRegTargetOpValue";
}
+def cbtarget : Operand<OtherVT> {
+ let EncoderMethod = "getCompareAndBranchTargetOpValue";
+}
+
def SparcCallTargetAsmOperand : AsmOperandClass {
let Name = "CallTarget";
let ParserMethod = "parseCallTarget";
@@ -242,6 +252,12 @@ def calltarget : Operand<i32> {
let ParserMatchClass = SparcCallTargetAsmOperand;
}
+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";
diff --git a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
index a1bfcc3dbb652..4da489d23fe43 100644
--- a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
+++ b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
@@ -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.
//===----------------------------------------------------------------------===//
// Convenience template for 4-operand instructions
@@ -16,6 +16,21 @@ 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")>;
+class FourOpImm<string OpcStr, bits<6> op3val, bits<4> op5val,
+ RegisterClass RC>
+ : F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, simm5Op:$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
@@ -38,3 +53,92 @@ 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>;
+
+def AES_EROUND01 : FourOp<"aes_eround01", 0b011001, 0b0000, DFPRegs>;
+def AES_EROUND23 : FourOp<"aes_eround23", 0b011001, 0b0001, DFPRegs>;
+def AES_DROUND01 : FourOp<"aes_dround01", 0b011001, 0b0010, DFPRegs>;
+def AES_DROUND23 : FourOp<"aes_dround23", 0b011001, 0b0011, DFPRegs>;
+def AES_EROUND01_LAST : FourOp<"aes_eround01_l", 0b011001, 0b0100, DFPRegs>;
+def AES_EROUND23_LAST : FourOp<"aes_eround23_l", 0b011001, 0b0101, DFPRegs>;
+def AES_DROUND01_LAST : FourOp<"aes_dround01_l", 0b011001, 0b0110, D...
[truncated]
|
@llvm/pr-subscribers-mc Author: Koakuma (koachan) ChangesPatch is 56.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138403.diff 15 Files Affected:
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
index 7e01a4a8a0a06..b87949ab199b5 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/Sparc.def
@@ -87,3 +87,4 @@ ELF_RELOC(R_SPARC_GOTDATA_LOX10, 81)
ELF_RELOC(R_SPARC_GOTDATA_OP_HIX22, 82)
ELF_RELOC(R_SPARC_GOTDATA_OP_LOX10, 83)
ELF_RELOC(R_SPARC_GOTDATA_OP, 84)
+ELF_RELOC(R_SPARC_WDISP10, 88)
diff --git a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
index 828d638723587..c42e173379a39 100644
--- a/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
+++ b/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
@@ -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);
@@ -340,6 +342,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));
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
index cc8b86e6135b5..d37724699be5d 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
@@ -50,6 +50,15 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
return (d16hi << 20) | d16lo;
}
+ case Sparc::fixup_sparc_br10: {
+ // 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 Sparc::fixup_sparc_hix22:
return (~Value >> 10) & 0x3fffff;
@@ -162,11 +171,13 @@ namespace {
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override {
const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
+ // clang-format off
// name offset bits flags
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br16", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br10", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_13", 19, 13, 0 },
{ "fixup_sparc_hi22", 10, 22, 0 },
{ "fixup_sparc_lo10", 22, 10, 0 },
@@ -205,14 +216,17 @@ namespace {
{ "fixup_sparc_gotdata_hix22", 0, 0, 0 },
{ "fixup_sparc_gotdata_lox10", 0, 0, 0 },
{ "fixup_sparc_gotdata_op", 0, 0, 0 },
+ // clang-format on
};
const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
+ // clang-format off
// name offset bits flags
{ "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_br16", 32, 0, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_sparc_br10", 32, 0, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_sparc_13", 0, 13, 0 },
{ "fixup_sparc_hi22", 0, 22, 0 },
{ "fixup_sparc_lo10", 0, 10, 0 },
@@ -251,6 +265,7 @@ namespace {
{ "fixup_sparc_gotdata_hix22", 0, 0, 0 },
{ "fixup_sparc_gotdata_lox10", 0, 0, 0 },
{ "fixup_sparc_gotdata_op", 0, 0, 0 },
+ // clang-format on
};
// Fixup kinds from .reloc directive are like R_SPARC_NONE. They do
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
index f95e5ac1664e6..6b6d352c7736b 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
@@ -84,6 +84,8 @@ unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
case Sparc::fixup_sparc_br16:
return ELF::R_SPARC_WDISP16;
+ case Sparc::fixup_sparc_br10:
+ return ELF::R_SPARC_WDISP10;
case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22;
case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10;
case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30;
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
index 3b91326589894..ec8f78cd63812 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
@@ -11,6 +11,7 @@
#include "llvm/MC/MCFixup.h"
+// clang-format off
namespace llvm {
namespace Sparc {
enum Fixups {
@@ -28,6 +29,9 @@ namespace llvm {
/// fixup_sparc_bpr - 16-bit fixup for bpr
fixup_sparc_br16,
+ /// fixup_sparc_br10 - 10-bit fixup for cbcond
+ fixup_sparc_br10,
+
/// fixup_sparc_13 - 13-bit fixup
fixup_sparc_13,
@@ -112,5 +116,5 @@ namespace llvm {
};
}
}
-
+// clang-format on
#endif
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index 0c9ba6a8a297c..06721db60cdd6 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -71,6 +71,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;
@@ -80,6 +83,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,26 @@ 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();
+
+ llvm_unreachable("simm5 operands can only be used with constants!");
+}
+
unsigned
SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
@@ -239,6 +265,19 @@ getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
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.isReg() || MO.isImm())
+ return getMachineOpValue(MI, MO, Fixups, STI);
+
+ Fixups.push_back(
+ MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br10));
+
+ return 0;
+}
+
#include "SparcGenMCCodeEmitter.inc"
MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
diff --git a/llvm/lib/Target/Sparc/Sparc.td b/llvm/lib/Target/Sparc/Sparc.td
index 93c3098bd89fe..6e6c887e60e12 100644
--- a/llvm/lib/Target/Sparc/Sparc.td
+++ b/llvm/lib/Target/Sparc/Sparc.td
@@ -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,
diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td
index 590395c16965b..fa2c62101d30e 100644
--- a/llvm/lib/Target/Sparc/SparcInstrAliases.td
+++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td
@@ -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<!strconcat(!strconcat("cwb", cond), " $rs1, $rs2, $imm"),
+ (CWBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
+ Requires<[HasOSA2011]>;
+ def : InstAlias<!strconcat(!strconcat("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<!strconcat(!strconcat("cxb", cond), " $rs1, $rs2, $imm"),
+ (CXBCONDrr cbtarget:$imm, condVal, IntRegs:$rs1, IntRegs:$rs2)>,
+ Requires<[HasOSA2011]>;
+ def : InstAlias<!strconcat(!strconcat("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,46 @@ 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 +724,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]
diff --git a/llvm/lib/Target/Sparc/SparcInstrFormats.td b/llvm/lib/Target/Sparc/SparcInstrFormats.td
index 2998f53ef2dbc..fe10bb443348a 100644
--- a/llvm/lib/Target/Sparc/SparcInstrFormats.td
+++ b/llvm/lib/Target/Sparc/SparcInstrFormats.td
@@ -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
diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td
index 057eafd734e71..c14d72b33c08c 100644
--- a/llvm/lib/Target/Sparc/SparcInstrInfo.td
+++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td
@@ -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()); }]>;
@@ -231,6 +237,10 @@ def bprtarget16 : Operand<OtherVT> {
let EncoderMethod = "getBranchOnRegTargetOpValue";
}
+def cbtarget : Operand<OtherVT> {
+ let EncoderMethod = "getCompareAndBranchTargetOpValue";
+}
+
def SparcCallTargetAsmOperand : AsmOperandClass {
let Name = "CallTarget";
let ParserMethod = "parseCallTarget";
@@ -242,6 +252,12 @@ def calltarget : Operand<i32> {
let ParserMatchClass = SparcCallTargetAsmOperand;
}
+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";
diff --git a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
index a1bfcc3dbb652..4da489d23fe43 100644
--- a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
+++ b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
@@ -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.
//===----------------------------------------------------------------------===//
// Convenience template for 4-operand instructions
@@ -16,6 +16,21 @@ 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")>;
+class FourOpImm<string OpcStr, bits<6> op3val, bits<4> op5val,
+ RegisterClass RC>
+ : F3_4<op3val, op5val, (outs RC:$rd), (ins RC:$rs1, RC:$rs2, simm5Op:$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
@@ -38,3 +53,92 @@ 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>;
+
+def AES_EROUND01 : FourOp<"aes_eround01", 0b011001, 0b0000, DFPRegs>;
+def AES_EROUND23 : FourOp<"aes_eround23", 0b011001, 0b0001, DFPRegs>;
+def AES_DROUND01 : FourOp<"aes_dround01", 0b011001, 0b0010, DFPRegs>;
+def AES_DROUND23 : FourOp<"aes_dround23", 0b011001, 0b0011, DFPRegs>;
+def AES_EROUND01_LAST : FourOp<"aes_eround01_l", 0b011001, 0b0100, DFPRegs>;
+def AES_EROUND23_LAST : FourOp<"aes_eround23_l", 0b011001, 0b0101, DFPRegs>;
+def AES_DROUND01_LAST : FourOp<"aes_dround01_l", 0b011001, 0b0110, D...
[truncated]
|
def FPMADDX : FourOp<"fpmaddx", 0b110111, 0b0000, DFPRegs>; | ||
def FPMADDXHI : FourOp<"fpmaddxhi", 0b110111, 0b0100, DFPRegs>; | ||
|
||
def AES_EROUND01 : FourOp<"aes_eround01", 0b011001, 0b0000, DFPRegs>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Contrary to my comments in other PRs in the stack, I think it is fine to put these instructions in a separate file, as it is a new "class" of instructions (cryptography). I wouldn't bind them to a specific extension name though, something like SparcInstrInfoCrypto.td
maybe?
Not a strong objection (in other PRs too), it is a personal PoV.
Created using spr 1.3.5
Created using spr 1.3.5
No description provided.