From 5cee34013cfd4edea0041bc0b73121cc4ad76ccf Mon Sep 17 00:00:00 2001 From: Victor Huang Date: Thu, 23 Jan 2020 14:01:02 -0600 Subject: [PATCH] [PowerPC][Future] Add prefixed instruction paddi to future CPU Future CPU will include support for prefixed instructions. These prefixed instructions are formed by a 4 byte prefix immediately followed by a 4 byte instruction effectively making an 8 byte instruction. The new instruction paddi is a prefixed form of addi. This patch adds paddi and all of the support required for that instruction. The majority of the patch deals with supporting the new prefixed instructions. The addition of paddi is mainly to allow for testing. Differential Revision: https://reviews.llvm.org/D72569 --- llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp | 7 ++ .../PowerPC/Disassembler/PPCDisassembler.cpp | 34 +++++- .../Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp | 14 +++ .../Target/PowerPC/MCTargetDesc/PPCInstPrinter.h | 2 + .../PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp | 2 +- .../Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h | 2 +- llvm/lib/Target/PowerPC/PPC.td | 7 +- llvm/lib/Target/PowerPC/PPCInstrFormats.td | 4 + llvm/lib/Target/PowerPC/PPCInstrInfo.h | 4 +- llvm/lib/Target/PowerPC/PPCInstrInfo.td | 24 ++++ llvm/lib/Target/PowerPC/PPCInstrPrefix.td | 123 +++++++++++++++++++++ llvm/lib/Target/PowerPC/PPCScheduleP9.td | 6 +- llvm/lib/Target/PowerPC/PPCSubtarget.cpp | 1 + llvm/lib/Target/PowerPC/PPCSubtarget.h | 2 + llvm/test/CodeGen/PowerPC/future-check-features.ll | 19 ++++ .../MC/Disassembler/PowerPC/future-invalid.txt | 5 + llvm/test/MC/Disassembler/PowerPC/futureinsts.txt | 9 ++ llvm/test/MC/PowerPC/future.s | 27 +++++ 18 files changed, 283 insertions(+), 9 deletions(-) create mode 100644 llvm/lib/Target/PowerPC/PPCInstrPrefix.td create mode 100644 llvm/test/CodeGen/PowerPC/future-check-features.ll create mode 100644 llvm/test/MC/Disassembler/PowerPC/future-invalid.txt create mode 100644 llvm/test/MC/Disassembler/PowerPC/futureinsts.txt create mode 100644 llvm/test/MC/PowerPC/future.s diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp index ffa857d..41f4bb6 100644 --- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp +++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp @@ -356,6 +356,12 @@ public: bool isS16ImmX16() const { return Kind == Expression || (Kind == Immediate && isInt<16>(getImm()) && (getImm() & 15) == 0); } + bool isS34Imm() const { + // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit + // ContextImmediate is needed. + return Kind == Expression || (Kind == Immediate && isInt<34>(getImm())); + } + bool isS17Imm() const { switch (Kind) { case Expression: @@ -388,6 +394,7 @@ public: bool isCondBr() const { return Kind == Expression || (Kind == Immediate && isInt<16>(getImm()) && (getImm() & 3) == 0); } + bool isImmZero() const { return Kind == Immediate && getImm() == 0; } bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); } bool isVSRegNumber() const { return Kind == Immediate && isUInt<6>(getImm()); diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index e3c0f95..872fe4b 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -191,6 +191,14 @@ static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, return MCDisassembler::Success; } +static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm, + int64_t Address, const void *Decoder) { + if (Imm != 0) + return MCDisassembler::Fail; + Inst.addOperand(MCOperand::createImm(Imm)); + return MCDisassembler::Success; +} + static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm, int64_t Address, const void *Decoder) { // Decode the memri field (imm, reg), which has the low 16-bits as the @@ -324,6 +332,29 @@ DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, ArrayRef Bytes, uint64_t Address, raw_ostream &CS) const { + auto *ReadFunc = IsLittleEndian ? support::endian::read32le + : support::endian::read32be; + + // If this is an 8-byte prefixed instruction, handle it here. + // Note: prefixed instructions aren't technically 8-byte entities - the prefix + // appears in memory at an address 4 bytes prior to that of the base + // instruction regardless of endianness. So we read the two pieces and + // rebuild the 8-byte instruction. + // TODO: In this function we call decodeInstruction several times with + // different decoder tables. It may be possible to only call once by + // looking at the top 6 bits of the instruction. + if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) { + uint32_t Prefix = ReadFunc(Bytes.data()); + uint32_t BaseInst = ReadFunc(Bytes.data() + 4); + uint64_t Inst = BaseInst | (uint64_t)Prefix << 32; + DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address, + this, STI); + if (result != MCDisassembler::Fail) { + Size = 8; + return result; + } + } + // Get the four bytes of the instruction. Size = 4; if (Bytes.size() < 4) { @@ -332,8 +363,7 @@ DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, } // Read the instruction in the proper endianness. - uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data()) - : support::endian::read32be(Bytes.data()); + uint64_t Inst = ReadFunc(Bytes.data()); if (STI.getFeatureBits()[PPC::FeatureQPX]) { DecodeStatus result = diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp index 9cc1c53..bae5c94 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp @@ -339,6 +339,13 @@ void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo, O << (int)Value; } +void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned int Value = MI->getOperand(OpNo).getImm(); + assert(Value == 0 && "Operand must be zero"); + O << (unsigned int)Value; +} + void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { unsigned int Value = MI->getOperand(OpNo).getImm(); @@ -391,6 +398,13 @@ void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo, printOperand(MI, OpNo, O); } +void PPCInstPrinter::printS34ImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + long long Value = MI->getOperand(OpNo).getImm(); + assert(isInt<34>(Value) && "Invalid s34imm argument!"); + O << (long long)Value; +} + void PPCInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O) { if (MI->getOperand(OpNo).isImm()) diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h index a3ec41a..841eab9 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h @@ -61,7 +61,9 @@ public: void printU10ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU12ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printS16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printS34ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printImmZeroOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); void printTLSCall(const MCInst *MI, unsigned OpNo, raw_ostream &O); diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp index 676efc5..b68f821 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp @@ -257,7 +257,7 @@ static unsigned getOpIdxForMO(const MCInst &MI, const MCOperand &MO) { return ~0U; // Silence any warnings about no return. } -unsigned PPCMCCodeEmitter:: +uint64_t PPCMCCodeEmitter:: getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h index 1324faa..3bc9f20 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.h @@ -80,7 +80,7 @@ public: /// getMachineOpValue - Return binary encoding of operand. If the machine /// operand requires relocation, record the relocation and return zero. - unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, + uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td index bef0a81..a5577a4 100644 --- a/llvm/lib/Target/PowerPC/PPC.td +++ b/llvm/lib/Target/PowerPC/PPC.td @@ -209,6 +209,11 @@ def FeatureVectorsUseTwoUnits : SubtargetFeature<"vectors-use-two-units", "VectorsUseTwoUnits", "true", "Vectors use two units">; +def FeaturePrefixInstrs : SubtargetFeature<"prefix-instrs", "HasPrefixInstrs", + "true", + "Enable prefixed instructions", + [FeatureISA3_0, FeatureP8Vector, + FeatureP9Altivec]>; // Since new processors generally contain a superset of features of those that // came before them, the idea is to make implementations of new processors @@ -298,7 +303,7 @@ def ProcessorFeatures { // For future CPU we assume that all of the existing features from Power 9 // still exist with the exception of those we know are Power 9 specific. list FutureAdditionalFeatures = []; - list FutureSpecificFeatures = []; + list FutureSpecificFeatures = [FeaturePrefixInstrs]; list FutureInheritableFeatures = !listconcat(P9InheritableFeatures, FutureAdditionalFeatures); list FutureFeatures = diff --git a/llvm/lib/Target/PowerPC/PPCInstrFormats.td b/llvm/lib/Target/PowerPC/PPCInstrFormats.td index 30c2698..632d4d9 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrFormats.td +++ b/llvm/lib/Target/PowerPC/PPCInstrFormats.td @@ -41,6 +41,10 @@ class I opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin> bits<1> XFormMemOp = 0; let TSFlags{6} = XFormMemOp; + // Indicate that this instruction is prefixed. + bits<1> Prefixed = 0; + let TSFlags{7} = Prefixed; + // Fields used for relation models. string BaseName = ""; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index a549b82..0e417e4 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -65,7 +65,9 @@ enum { NewDef_Shift = 6, /// This instruction is an X-Form memory operation. - XFormMemOp = 0x1 << NewDef_Shift + XFormMemOp = 0x1 << NewDef_Shift, + /// This instruction is prefixed. + Prefixed = 0x1 << (NewDef_Shift+1) }; } // end namespace PPCII diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index b38ca3a..137a2f3 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -723,6 +723,26 @@ def s17imm : Operand { let ParserMatchClass = PPCS17ImmAsmOperand; let DecoderMethod = "decodeSImmOperand<16>"; } +def PPCS34ImmAsmOperand : AsmOperandClass { + let Name = "S34Imm"; + let PredicateMethod = "isS34Imm"; + let RenderMethod = "addImmOperands"; +} +def s34imm : Operand { + let PrintMethod = "printS34ImmOperand"; + let ParserMatchClass = PPCS34ImmAsmOperand; + let DecoderMethod = "decodeSImmOperand<34>"; +} +def PPCImmZeroAsmOperand : AsmOperandClass { + let Name = "ImmZero"; + let PredicateMethod = "isImmZero"; + let RenderMethod = "addImmOperands"; +} +def immZero : Operand { + let PrintMethod = "printImmZeroOperand"; + let ParserMatchClass = PPCImmZeroAsmOperand; + let DecoderMethod = "decodeImmZeroOperand"; +} def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>; @@ -3331,6 +3351,10 @@ def crnot : OutPatFrag<(ops node:$in), def : Pat<(not i1:$in), (crnot $in)>; +// Prefixed instructions may require access to the above defs at a later +// time so we include this after the def. +include "PPCInstrPrefix.td" + // Patterns for arithmetic i1 operations. def : Pat<(add i1:$a, i1:$b), (CRXOR $a, $b)>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrPrefix.td b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td new file mode 100644 index 0000000..46c8608 --- /dev/null +++ b/llvm/lib/Target/PowerPC/PPCInstrPrefix.td @@ -0,0 +1,123 @@ +// PC Relative flag (for instructions that use the address of the prefix for +// address computations). +class isPCRel { bit PCRel = 1; } + +// Top-level class for prefixed instructions. +class PI pref, bits<6> opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin> : Instruction { + field bits<64> Inst; + field bits<64> SoftFail = 0; + bit PCRel = 0; // Default value, set by isPCRel. + let Size = 8; + + let Namespace = "PPC"; + let OutOperandList = OOL; + let InOperandList = IOL; + let AsmString = asmstr; + let Itinerary = itin; + let Inst{0-5} = pref; + let Inst{32-37} = opcode; + + bits<1> PPC970_First = 0; + bits<1> PPC970_Single = 0; + bits<1> PPC970_Cracked = 0; + bits<3> PPC970_Unit = 0; + + /// These fields correspond to the fields in PPCInstrInfo.h. Any changes to + /// these must be reflected there! See comments there for what these are. + let TSFlags{0} = PPC970_First; + let TSFlags{1} = PPC970_Single; + let TSFlags{2} = PPC970_Cracked; + let TSFlags{5-3} = PPC970_Unit; + + bits<1> Prefixed = 1; // This is a prefixed instruction. + let TSFlags{7} = Prefixed; + + // For cases where multiple instruction definitions really represent the + // same underlying instruction but with one definition for 64-bit arguments + // and one for 32-bit arguments, this bit breaks the degeneracy between + // the two forms and allows TableGen to generate mapping tables. + bit Interpretation64Bit = 0; + + // Fields used for relation models. + string BaseName = ""; +} + +class MLS_DForm_R_SI34_RTA5 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : PI<1, opcode, OOL, IOL, asmstr, itin> { + bits<5> RT; + bits<5> RA; + bits<34> SI; + + let Pattern = pattern; + + // The prefix. + let Inst{6-7} = 2; + let Inst{8-10} = 0; + let Inst{11} = PCRel; + let Inst{12-13} = 0; + let Inst{14-31} = SI{33-16}; + + // The instruction. + let Inst{38-42} = RT; + let Inst{43-47} = RA; + let Inst{48-63} = SI{15-0}; +} + +class MLS_DForm2_r0 opcode, dag OOL, dag IOL, string asmstr, + InstrItinClass itin, list pattern> + : PI<1, opcode, OOL, IOL, asmstr, itin> { + bits<5> RT; + bits<34> SI; + + let Pattern = pattern; + + // The prefix. + let Inst{6-7} = 2; + let Inst{8-10} = 0; + let Inst{11} = 0; + let Inst{12-13} = 0; + let Inst{14-31} = SI{33-16}; + + // The instruction. + let Inst{38-42} = RT; + let Inst{43-47} = 0; + let Inst{48-63} = SI{15-0}; +} + +multiclass MLS_DForm_R_SI34_RTA5_p opcode, dag OOL, dag IOL, + dag PCRel_IOL, string asmstr, + InstrItinClass itin> { + def NAME : MLS_DForm_R_SI34_RTA5; + def pc : MLS_DForm_R_SI34_RTA5, isPCRel; +} + + +def PrefixInstrs : Predicate<"PPCSubTarget->hasPrefixInstrs()">; + +let Predicates = [PrefixInstrs] in { + let Interpretation64Bit = 1, isCodeGenOnly = 1 in { + defm PADDI8 : + MLS_DForm_R_SI34_RTA5_p<14, (outs g8rc:$RT), (ins g8rc:$RA, s34imm:$SI), + (ins immZero:$RA, s34imm:$SI), + "paddi $RT, $RA, $SI", IIC_LdStLFD>; + let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in { + def PLI8 : MLS_DForm2_r0<14, (outs g8rc:$RT), + (ins s34imm:$SI), + "pli $RT, $SI", IIC_IntSimple, []>; + } + } + defm PADDI : + MLS_DForm_R_SI34_RTA5_p<14, (outs gprc:$RT), (ins gprc:$RA, s34imm:$SI), + (ins immZero:$RA, s34imm:$SI), + "paddi $RT, $RA, $SI", IIC_LdStLFD>; + let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in { + def PLI : MLS_DForm2_r0<14, (outs gprc:$RT), + (ins s34imm:$SI), + "pli $RT, $SI", IIC_IntSimple, []>; + } +} + diff --git a/llvm/lib/Target/PowerPC/PPCScheduleP9.td b/llvm/lib/Target/PowerPC/PPCScheduleP9.td index 6a79cca..4f00fb1 100644 --- a/llvm/lib/Target/PowerPC/PPCScheduleP9.td +++ b/llvm/lib/Target/PowerPC/PPCScheduleP9.td @@ -40,9 +40,9 @@ def P9Model : SchedMachineModel { let CompleteModel = 1; - // Do not support QPX (Quad Processing eXtension) or SPE (Signal Procesing - // Engine) on Power 9. - let UnsupportedFeatures = [HasQPX, HasSPE]; + // Do not support QPX (Quad Processing eXtension), SPE (Signal Procesing + // Engine) or prefixed instructions on Power 9. + let UnsupportedFeatures = [HasQPX, HasSPE, PrefixInstrs]; } diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp index e155a82..07e20df 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp @@ -78,6 +78,7 @@ void PPCSubtarget::initializeEnvironment() { HasP8Crypto = false; HasP9Vector = false; HasP9Altivec = false; + HasPrefixInstrs = false; HasFCPSGN = false; HasFSQRT = false; HasFRE = false; diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h index 58cc562..4e1d65e 100644 --- a/llvm/lib/Target/PowerPC/PPCSubtarget.h +++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h @@ -105,6 +105,7 @@ protected: bool HasP8Crypto; bool HasP9Vector; bool HasP9Altivec; + bool HasPrefixInstrs; bool HasFCPSGN; bool HasFSQRT; bool HasFRE, HasFRES, HasFRSQRTE, HasFRSQRTES; @@ -255,6 +256,7 @@ public: bool hasP8Crypto() const { return HasP8Crypto; } bool hasP9Vector() const { return HasP9Vector; } bool hasP9Altivec() const { return HasP9Altivec; } + bool hasPrefixInstrs() const { return HasPrefixInstrs; } bool hasMFOCRF() const { return HasMFOCRF; } bool hasISEL() const { return HasISEL; } bool hasBPERMD() const { return HasBPERMD; } diff --git a/llvm/test/CodeGen/PowerPC/future-check-features.ll b/llvm/test/CodeGen/PowerPC/future-check-features.ll new file mode 100644 index 0000000..c4d4828 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/future-check-features.ll @@ -0,0 +1,19 @@ +; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \ +; RUN: -mtriple=powerpc64le-unknown-unknown -ppc-asm-full-reg-names \ +; RUN: %s -o - 2>&1 | FileCheck %s +; RUN: llc -mattr=prefix-instrs -verify-machineinstrs \ +; RUN: -mtriple=powerpc64-unknown-unknown -ppc-asm-full-reg-names \ +; RUN: %s -o - 2>&1 | FileCheck %s + +define dso_local signext i32 @f() { +entry: + ret i32 0 +} + +; Make sure that all of the features listed are recognized. +; CHECK-NOT: is not a recognized feature for this target + +; Make sure that the test was actually compiled. +; CHECK: li r3, 0 +; CHECK-NEXT: blr + diff --git a/llvm/test/MC/Disassembler/PowerPC/future-invalid.txt b/llvm/test/MC/Disassembler/PowerPC/future-invalid.txt new file mode 100644 index 0000000..263fb7f --- /dev/null +++ b/llvm/test/MC/Disassembler/PowerPC/future-invalid.txt @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -mcpu=future -triple powerpc64-unknown-linux-gnu < %s 2>&1 | FileCheck %s + +# paddi 1, 2, 8589934591, 1. However, RA is not zero with R=1 +# CHECK: warning: invalid instruction encoding +0x06 0x11 0xff 0xff 0x38 0x22 0xff 0xff diff --git a/llvm/test/MC/Disassembler/PowerPC/futureinsts.txt b/llvm/test/MC/Disassembler/PowerPC/futureinsts.txt new file mode 100644 index 0000000..9ff8bff --- /dev/null +++ b/llvm/test/MC/Disassembler/PowerPC/futureinsts.txt @@ -0,0 +1,9 @@ +# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-linux-gnu \ +# RUN: -mcpu=future | FileCheck %s + +# CHECK: paddi 1, 2, 8589934591, 0 +0x06 0x01 0xff 0xff 0x38 0x22 0xff 0xff + +# CHECK: paddi 1, 0, -8589934592, 1 +0x06 0x12 0x00 0x00 0x38 0x20 0x00 0x00 + diff --git a/llvm/test/MC/PowerPC/future.s b/llvm/test/MC/PowerPC/future.s new file mode 100644 index 0000000..afffee1 --- /dev/null +++ b/llvm/test/MC/PowerPC/future.s @@ -0,0 +1,27 @@ +# RUN: llvm-mc -triple powerpc64-unknown-linux-gnu --show-encoding %s | \ +# RUN: FileCheck -check-prefix=CHECK-BE %s +# RUN: llvm-mc -triple powerpc64le-unknown-linux-gnu --show-encoding %s | \ +# RUN: FileCheck -check-prefix=CHECK-LE %s + +# CHECK-BE: paddi 1, 2, 8589934591, 0 # encoding: [0x06,0x01,0xff,0xff +# CHECK-BE-SAME: 0x38,0x22,0xff,0xff] +# CHECK-LE: paddi 1, 2, 8589934591, 0 # encoding: [0xff,0xff,0x01,0x06 +# CHECK-LE-SAME: 0xff,0xff,0x22,0x38] + paddi 1, 2, 8589934591, 0 +# CHECK-BE: paddi 1, 0, -8589934592, 1 # encoding: [0x06,0x12,0x00,0x00 +# CHECK-BE-SAME: 0x38,0x20,0x00,0x00] +# CHECK-LE: paddi 1, 0, -8589934592, 1 # encoding: [0x00,0x00,0x12,0x06 +# CHECK-LE-SAME: 0x00,0x00,0x20,0x38] + paddi 1, 0, -8589934592, 1 +# CHECK-BE: pli 1, -8589934592 # encoding: [0x06,0x02,0x00,0x00 +# CHECK-BE-SAME: 0x38,0x20,0x00,0x00] +# CHECK-LE: pli 1, -8589934592 # encoding: [0x00,0x00,0x02,0x06 +# CHECK-LE-SAME: 0x00,0x00,0x20,0x38] + pli 1, -8589934592 +# CHECK-BE: pli 1, 8589934591 # encoding: [0x06,0x01,0xff,0xff +# CHECK-BE-SAME: 0x38,0x20,0xff,0xff] +# CHECK-LE: pli 1, 8589934591 # encoding: [0xff,0xff,0x01,0x06 +# CHECK-LE-SAME: 0xff,0xff,0x20,0x38] + pli 1, 8589934591 + + -- 2.7.4