Index: lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp =================================================================== --- lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -12,6 +12,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstBuilder.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCParser/MCTargetAsmParser.h" #include "llvm/MC/MCStreamer.h" @@ -322,6 +323,7 @@ bool isVR64() const { return isReg(VR64Reg); } bool isVF128() const { return false; } bool isVR128() const { return isReg(VR128Reg); } + bool isAnyGRFP() const { return (isReg(GR64Reg) || isReg(FP64Reg)); } bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); } bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); } bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, ADDR64Reg); } @@ -342,6 +344,7 @@ bool isS16Imm() const { return isImm(-32768, 32767); } bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); } bool isS32Imm() const { return isImm(-(1LL << 31), (1LL << 31) - 1); } + bool isU48Imm() const { return isImm(0, (1LL << 48) - 1); } }; class SystemZAsmParser : public MCTargetAsmParser { @@ -371,10 +374,14 @@ RegisterGroup Group, const unsigned *Regs, RegisterKind Kind); + OperandMatchResultTy parseAnyGRFPRegister(OperandVector &Operands); + bool parseAddress(unsigned &Base, const MCExpr *&Disp, unsigned &Index, bool &IsVector, const MCExpr *&Length, const unsigned *Regs, RegisterKind RegKind); + bool ParseDirectiveInsn(SMLoc L); + OperandMatchResultTy parseAddress(OperandVector &Operands, MemoryKind MemKind, const unsigned *Regs, RegisterKind RegKind); @@ -451,6 +458,9 @@ OperandMatchResultTy parseVR128(OperandVector &Operands) { return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg); } + OperandMatchResultTy parseAnyGRFP(OperandVector &Operands) { + return parseAnyGRFPRegister(Operands); + } OperandMatchResultTy parseBDAddr32(OperandVector &Operands) { return parseAddress(Operands, BDMem, SystemZMC::GR32Regs, ADDR32Reg); } @@ -487,6 +497,37 @@ #define GET_MATCHER_IMPLEMENTATION #include "SystemZGenAsmMatcher.inc" +// Used for .insn directives, returns an MCInst opcode from the format string. +static uint64_t getOpcodeFromFormat(StringRef Format) { + return StringSwitch(Format.lower()) + .Case("e", SystemZ::InsnE) + .Case("ri", SystemZ::InsnRI) + .Case("rie", SystemZ::InsnRIE) + .Case("ril", SystemZ::InsnRIL) + .Case("rilu", SystemZ::InsnRILU) + .Case("ris", SystemZ::InsnRIS) + .Case("rr", SystemZ::InsnRR) + .Case("rre", SystemZ::InsnRRE) + .Case("rrf", SystemZ::InsnRRF) + .Case("rrs", SystemZ::InsnRRS) + .Case("rs", SystemZ::InsnRS) + .Case("rse", SystemZ::InsnRSE) + .Case("rsi", SystemZ::InsnRSI) + .Case("rsy", SystemZ::InsnRSY) + .Case("rx", SystemZ::InsnRX) + .Case("rxe", SystemZ::InsnRXE) + .Case("rxf", SystemZ::InsnRXF) + .Case("rxy", SystemZ::InsnRXY) + .Case("s", SystemZ::InsnS) + .Case("si", SystemZ::InsnSI) + .Case("siy", SystemZ::InsnSIY) + .Case("sil", SystemZ::InsnSIL) + .Case("ss", SystemZ::InsnSS) + .Case("sse", SystemZ::InsnSSE) + .Case("ssf", SystemZ::InsnSSF) + .Default(0); +} + void SystemZOperand::print(raw_ostream &OS) const { llvm_unreachable("Not implemented"); } @@ -569,6 +610,47 @@ return MatchOperand_Success; } +// Parse any GR or FP type register (including integers) and add it to Operands. +SystemZAsmParser::OperandMatchResultTy +SystemZAsmParser::parseAnyGRFPRegister(OperandVector &Operands) { + // Handle integer values as registers. + if (Parser.getTok().is(AsmToken::Integer)) { + const MCExpr *Register; + SMLoc StartLoc = Parser.getTok().getLoc(); + if (Parser.parseExpression(Register)) + return MatchOperand_ParseFail; + + SMLoc EndLoc = + SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); + + Operands.push_back(SystemZOperand::createImm(Register, StartLoc, EndLoc)); + } + else { + Register Reg; + if (parseRegister(Reg)) + return MatchOperand_ParseFail; + + // Map to a GR or FP register. + RegisterKind Kind; + unsigned RegNo; + if (Reg.Group == RegGR) { + Kind = GR64Reg; + RegNo = SystemZMC::GR64Regs[Reg.Num]; + } + else if (Reg.Group == RegFP) { + Kind = FP64Reg; + RegNo = SystemZMC::FP64Regs[Reg.Num]; + } + else { + return MatchOperand_ParseFail; + } + + Operands.push_back(SystemZOperand::createReg(Kind, RegNo, + Reg.StartLoc, Reg.EndLoc)); + } + return MatchOperand_Success; +} + // Parse a memory operand into Base, Disp, Index and Length. // Regs maps asm register numbers to LLVM register numbers and RegKind // says what kind of address register we're using (ADDR32Reg or ADDR64Reg). @@ -678,9 +760,62 @@ } bool SystemZAsmParser::ParseDirective(AsmToken DirectiveID) { + StringRef IDVal = DirectiveID.getIdentifier(); + + if (IDVal == ".insn") + return ParseDirectiveInsn(DirectiveID.getLoc()); + return true; } +/// ParseDirectiveInsn +/// ::= .insn [ format, encoding, (operands (, operands)*) ] +bool SystemZAsmParser::ParseDirectiveInsn(SMLoc L) { + MCAsmParser &Parser = getParser(); + + // Expect instruction format as identifier. + StringRef Format; + if (Parser.parseIdentifier(Format)) + return Error(L, "expected instruction format in directive"); + + if (getLexer().isNot(AsmToken::Comma)) + return Error(L, "unexpected token in directive"); + Lex(); + + SmallVector, 8> Operands; + + StringRef Mnemonic = StringRef("Insn" + Format.upper()); + + // Parse the directive. + ParseInstructionInfo Info; + if (ParseInstruction(Info, Mnemonic, L, Operands)) + return true; + + // Build the instruction with the parsed operands. + uint64_t Opcode = getOpcodeFromFormat(Format); + MCInst Inst = MCInstBuilder(Opcode); + + // Skip first operand; the first operand is the mnemonic. + for (size_t i = 1; i < Operands.size(); i++) { + auto &Operand = static_cast(*Operands[i]); + if (Operand.isReg()) + Operand.addRegOperands(Inst, 1); + else if (Operand.isMem(BDMem)) + Operand.addBDAddrOperands(Inst, 2); + else if (Operand.isMem(BDXMem)) + Operand.addBDXAddrOperands(Inst, 3); + else if (Operand.isImm()) + Operand.addImmOperands(Inst, 1); + else + llvm_unreachable("unexpected operand type"); + } + + // Emit as a regular instruction. + Parser.getStreamer().EmitInstruction(Inst, getSTI()); + + return false; +} + bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) { Register Reg; Index: lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h =================================================================== --- lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h +++ lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h @@ -61,6 +61,7 @@ void printU16ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printS32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printU32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); + void printU48ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printPCRelOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printPCRelTLSOperand(const MCInst *MI, int OpNum, raw_ostream &O); void printAccessRegOperand(const MCInst *MI, int OpNum, raw_ostream &O); Index: lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp =================================================================== --- lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp +++ lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp @@ -134,6 +134,11 @@ printUImmOperand<32>(MI, OpNum, O); } +void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum, + raw_ostream &O) { + printUImmOperand<48>(MI, OpNum, O); +} + void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum, raw_ostream &O) { uint64_t Value = MI->getOperand(OpNum).getImm(); Index: lib/Target/SystemZ/SystemZInstrFormats.td =================================================================== --- lib/Target/SystemZ/SystemZInstrFormats.td +++ lib/Target/SystemZ/SystemZInstrFormats.td @@ -158,6 +158,14 @@ // //===----------------------------------------------------------------------===// +class InstE op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<2, outs, ins, asmstr, pattern> { + field bits<16> Inst; + field bits<16> SoftFail = 0; + + let Inst = op; +} + class InstI op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<2, outs, ins, asmstr, pattern> { field bits<16> Inst; @@ -487,6 +495,21 @@ let Inst{15-0} = BD2; } +class InstRSI op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<4, outs, ins, asmstr, pattern> { + field bits<32> Inst; + field bits<32> SoftFail = 0; + + bits<4> R1; + bits<4> R3; + bits<16> RI2; + + let Inst{31-24} = op; + let Inst{23-20} = R1; + let Inst{19-16} = R3; + let Inst{15-0} = RI2; +} + class InstRSY op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; @@ -560,6 +583,51 @@ let Inst{15-0} = BD2; } +class InstSSd op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<20> XBD1; + bits<16> BD2; + bits<4> R3; + + let Inst{47-40} = op; + let Inst{39-36} = XBD1{19-16}; + let Inst{35-32} = R3; + let Inst{31-16} = XBD1{15-0}; + let Inst{15-0} = BD2; +} + +class InstSSE op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<16> BD1; + bits<16> BD2; + + let Inst{47-32} = op; + let Inst{31-16} = BD1; + let Inst{15-0} = BD2; +} + +class InstSSF op, dag outs, dag ins, string asmstr, list pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<16> BD1; + bits<16> BD2; + bits<4> R3; + + let Inst{47-40} = op{11-4}; + let Inst{39-36} = R3; + let Inst{35-32} = op{3-0}; + let Inst{31-16} = BD1; + let Inst{15-0} = BD2; +} + class InstS op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<4, outs, ins, asmstr, pattern> { field bits<32> Inst; @@ -948,6 +1016,204 @@ } //===----------------------------------------------------------------------===// +// Instruction classes for .insn directives +//===----------------------------------------------------------------------===// + +class DirectiveInsnE pattern> + : InstE<0, outs, ins, asmstr, pattern> { + bits<16> enc; + + let Inst = enc; +} + +class DirectiveInsnRI pattern> + : InstRI<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-24} = enc{31-24}; + let Inst{19-16} = enc{19-16}; +} + +class DirectiveInsnRIE pattern> + : InstRIEd<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRIL pattern> + : InstRIL<0, outs, ins, asmstr, pattern> { + bits<48> enc; + string type; + + let Inst{47-40} = enc{47-40}; + let Inst{35-32} = enc{35-32}; +} + +class DirectiveInsnRIS pattern> + : InstRIS<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRR pattern> + : InstRR<0, outs, ins, asmstr, pattern> { + bits<16> enc; + + let Inst{15-8} = enc{15-8}; +} + +class DirectiveInsnRRE pattern> + : InstRRE<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-16} = enc{31-16}; +} + +class DirectiveInsnRRF pattern> + : InstRRF<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-16} = enc{31-16}; +} + +class DirectiveInsnRRS pattern> + : InstRRS<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRS pattern> + : InstRS<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-24} = enc{31-24}; +} + +class DirectiveInsnRSE pattern> + : InstSystemZ<6, outs, ins, asmstr, pattern> { + field bits<48> Inst; + field bits<48> SoftFail = 0; + + bits<48> enc; + + bits<4> R1; + bits<16> BD2; + bits<4> R3; + + let Inst{47-40} = enc{47-40}; + let Inst{39-36} = R1; + let Inst{35-32} = R3; + let Inst{31-16} = BD2; + let Inst{15-8} = 0; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRSI pattern> + : InstRSI<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-24} = enc{31-24}; +} + +class DirectiveInsnRSY pattern> + : InstRSY<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRX pattern> + : InstRX<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-24} = enc{31-24}; +} + +class DirectiveInsnRXE pattern> + : InstRXE<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let M3 = 0; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRXF pattern> + : InstRXF<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnRXY pattern> + : InstRXY<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnS pattern> + : InstS<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-16} = enc{31-16}; +} + +class DirectiveInsnSI pattern> + : InstSI<0, outs, ins, asmstr, pattern> { + bits<32> enc; + + let Inst{31-24} = enc{31-24}; +} + +class DirectiveInsnSIY pattern> + : InstSIY<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{7-0} = enc{7-0}; +} + +class DirectiveInsnSIL pattern> + : InstSIL<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-32} = enc{47-32}; +} + +class DirectiveInsnSS pattern> + : InstSSd<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; +} + +class DirectiveInsnSSE pattern> + : InstSSE<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-32} = enc{47-32}; +} + +class DirectiveInsnSSF pattern> + : InstSSF<0, outs, ins, asmstr, pattern> { + bits<48> enc; + + let Inst{47-40} = enc{47-40}; + let Inst{35-32} = enc{35-32}; +} + +//===----------------------------------------------------------------------===// // Instruction definitions with semantics //===----------------------------------------------------------------------===// // Index: lib/Target/SystemZ/SystemZInstrInfo.td =================================================================== --- lib/Target/SystemZ/SystemZInstrInfo.td +++ lib/Target/SystemZ/SystemZInstrInfo.td @@ -331,6 +331,11 @@ def BRCTG : BranchUnaryRI<"brctg", 0xA77, GR64>; } +def BRXH : InstRSI<0x84, (outs), (ins GR64:$R1, GR64:$R3, brtarget16:$RI2), + "brxh\t$R1, $R3, $RI2", []>; +def BRXLE : InstRSI<0x85, (outs), (ins GR64:$R1, GR64:$R3, brtarget16:$RI2), + "brxle\t$R1, $R3, $RI2", []>; + //===----------------------------------------------------------------------===// // Select instructions //===----------------------------------------------------------------------===// @@ -1668,6 +1673,210 @@ "exrl\t$R1, $I2", []>; } +let Defs = [CC] in { + def PR : InstE<0x0101, (outs), (ins), "pr", []>; + def MVCK : InstSSd<0xD9, (outs), + (ins bdxaddr12only:$XBD1, bdaddr12only:$BD2, + GR64:$R3), + "mvck\t$XBD1, $BD2, $R3", []>; +} + +def STRAG : InstSSE<0xE502, (outs), (ins bdaddr12only:$BD1, bdaddr12only:$BD2), + "strag\t$BD1, $BD2", []>; + +let Defs = [R0D, R1D] in + def ECTG : InstSSF<0xC81, (outs), + (ins bdaddr12only:$BD1, bdaddr12only:$BD2, GR64:$R3), + "ectg\t$BD1, $BD2, $R3", []>; + +//===----------------------------------------------------------------------===// +// .insn directive instructions +//===----------------------------------------------------------------------===// + +let isCodeGenOnly = 1 in { + def InsnE : DirectiveInsnE<(outs), (ins imm64zx16:$enc), ".insn e,$enc", []>; + def InsnRI : DirectiveInsnRI<(outs), (ins imm64zx32:$enc, AnyGRFP:$R1, + imm32sx16:$I2), + ".insn ri,$enc,$R1,$I2", []>; + def InsnRIE : DirectiveInsnRIE<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, brtarget16:$I2), + ".insn rie,$enc,$R1,$R3,$I2", []>; + def InsnRIL : DirectiveInsnRIL<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + brtarget32:$I2), + ".insn ril,$enc,$R1,$I2", []>; + def InsnRILU : DirectiveInsnRIL<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + uimm32:$I2), + ".insn rilu,$enc,$R1,$I2", []>; + def InsnRIS : DirectiveInsnRIS<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + imm32sx8:$I2, imm32zx4:$M3, + bdaddr12only:$BD4), + ".insn ris,$enc,$R1,$I2,$M3,$BD4", []>; + def InsnRR : DirectiveInsnRR<(outs), + (ins imm64zx16:$enc, AnyGRFP:$R1, AnyGRFP:$R2), + ".insn rr,$enc,$R1,$R2", []>; + def InsnRRE : DirectiveInsnRRE<(outs), (ins imm64zx32:$enc, + AnyGRFP:$R1, AnyGRFP:$R2), + ".insn rre,$enc,$R1,$R2", []>; + def InsnRRF : DirectiveInsnRRF<(outs), + (ins imm64zx32:$enc, AnyGRFP:$R1, AnyGRFP:$R2, + AnyGRFP:$R3, imm32zx4:$R4), + ".insn rrf,$enc,$R1,$R2,$R3,$R4", []>; + def InsnRRS : DirectiveInsnRRS<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R2, imm32zx4:$M3, + bdaddr12only:$BD4), + ".insn rrs,$enc,$R1,$R2,$M3,$BD4", []>; + def InsnRS : DirectiveInsnRS<(outs), + (ins imm64zx32:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdaddr12only:$BD2), + ".insn rs,$enc,$R1,$R3,$BD2", []>; + def InsnRSE : DirectiveInsnRSE<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdaddr12only:$BD2), + ".insn rse,$enc,$R1,$R3,$BD2", []>; + def InsnRSI : DirectiveInsnRSI<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, brtarget16:$RI2), + ".insn rsi,$enc,$R1,$R3,$RI2", []>; + def InsnRSY : DirectiveInsnRSY<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdaddr20only:$BD2), + ".insn rsy,$enc,$R1,$R3,$BD2", []>; + def InsnRX : DirectiveInsnRX<(outs), (ins imm64zx32:$enc, AnyGRFP:$R1, + bdxaddr12only:$XBD2), + ".insn rx,$enc,$R1,$XBD2", []>; + def InsnRXE : DirectiveInsnRXE<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + bdxaddr12only:$XBD2), + ".insn rxe,$enc,$R1,$XBD2", []>; + def InsnRXF : DirectiveInsnRXF<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdxaddr12only:$XBD2), + ".insn rxf,$enc,$R1,$R3,$XBD2", []>; + def InsnRXY : DirectiveInsnRXY<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + bdxaddr20only:$XBD2), + ".insn rxy,$enc,$R1,$XBD2", []>; + def InsnS : DirectiveInsnS<(outs), + (ins imm64zx32:$enc, bdaddr12only:$BD2), + ".insn s,$enc,$BD2", []>; + def InsnSI : DirectiveInsnSI<(outs), + (ins imm64zx32:$enc, bdaddr12only:$BD1, + imm32sx8:$I2), + ".insn si,$enc,$BD1,$I2", []>; + def InsnSIY : DirectiveInsnSIY<(outs), + (ins imm64zx48:$enc, + bdaddr20only:$BD1, imm32zx8:$I2), + ".insn siy,$enc,$BD1,$I2", []>; + def InsnSIL : DirectiveInsnSIL<(outs), + (ins imm64zx48:$enc, bdaddr12only:$BD1, + imm32zx16:$I2), + ".insn sil,$enc,$BD1,$I2", []>; + def InsnSS : DirectiveInsnSS<(outs), + (ins imm64zx48:$enc, bdxaddr12only:$XBD1, + bdaddr12only:$BD2, AnyGRFP:$R3), + ".insn ss,$enc,$XBD1,$BD2,$R3", []>; + def InsnSSE : DirectiveInsnSSE<(outs), + (ins imm64zx48:$enc, + bdaddr12only:$BD1,bdaddr12only:$BD2), + ".insn sse,$enc,$BD1,$BD2", []>; + def InsnSSF : DirectiveInsnSSF<(outs), + (ins imm64zx48:$enc, bdaddr12only:$BD1, + bdaddr12only:$BD2, AnyGRFP:$R3), + ".insn ssf,$enc,$BD1,$BD2,$R3", []>; +} + +let isAsmParserOnly = 1 in { + def AsmInsnE : DirectiveInsnE<(outs), (ins imm64zx16:$enc), "InsnE,$enc", []>; + def AsmInsnRI : DirectiveInsnRI<(outs), (ins imm64zx32:$enc, AnyGRFP:$R1, + imm32sx16:$I2), + "InsnRI,$enc,$R1,$I2", []>; + def AsmInsnRIE : DirectiveInsnRIE<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, brtarget16:$I2), + "InsnRIE,$enc,$R1,$R3,$I2", []>; + def AsmInsnRIL : DirectiveInsnRIL<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + brtarget32:$I2), + "InsnRIL,$enc,$R1,$I2", []>; + def AsmInsnRILU : DirectiveInsnRIL<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + uimm32:$I2), + "InsnRILU,$enc,$R1,$I2", []>; + def AsmInsnRIS : DirectiveInsnRIS<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + imm32sx8:$I2, imm32zx4:$M3, + bdaddr12only:$BD4), + "InsnRIS,$enc,$R1,$I2,$M3,$BD4", []>; + def AsmInsnRR : DirectiveInsnRR<(outs), + (ins imm64zx16:$enc, AnyGRFP:$R1, AnyGRFP:$R2), + "InsnRR,$enc,$R1,$R2", []>; + def AsmInsnRRE : DirectiveInsnRRE<(outs), (ins imm64zx32:$enc, + AnyGRFP:$R1, AnyGRFP:$R2), + "InsnRRE,$enc,$R1,$R2", []>; + def AsmInsnRRF : DirectiveInsnRRF<(outs), + (ins imm64zx32:$enc, AnyGRFP:$R1, + AnyGRFP:$R2, AnyGRFP:$R3, + imm32zx4:$R4), + "InsnRRF,$enc,$R1,$R2,$R3,$R4", []>; + def AsmInsnRRS : DirectiveInsnRRS<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R2, imm32zx4:$M3, + bdaddr12only:$BD4), + "InsnRRS,$enc,$R1,$R2,$M3,$BD4", []>; + def AsmInsnRS : DirectiveInsnRS<(outs), + (ins imm64zx32:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdaddr12only:$BD2), + "InsnRS,$enc,$R1,$R3,$BD2", []>; + def AsmInsnRSE : DirectiveInsnRSE<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdaddr12only:$BD2), + "InsnRSE,$enc,$R1,$R3,$BD2", []>; + def AsmInsnRSI : DirectiveInsnRSI<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, brtarget16:$RI2), + "InsnRSI,$enc,$R1,$R3,$RI2", []>; + def AsmInsnRSY : DirectiveInsnRSY<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdaddr20only:$BD2), + "InsnRSY,$enc,$R1,$R3,$BD2", []>; + def AsmInsnRX : DirectiveInsnRX<(outs), (ins imm64zx32:$enc, AnyGRFP:$R1, + bdxaddr12only:$XBD2), + "InsnRX,$enc,$R1,$XBD2", []>; + def AsmInsnRXE : DirectiveInsnRXE<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + bdxaddr12only:$XBD2), + "InsnRXE,$enc,$R1,$XBD2", []>; + def AsmInsnRXF : DirectiveInsnRXF<(outs), + (ins imm64zx48:$enc, AnyGRFP:$R1, + AnyGRFP:$R3, bdxaddr12only:$XBD2), + "InsnRXF,$enc,$R1,$R3,$XBD2", []>; + def AsmInsnRXY : DirectiveInsnRXY<(outs), (ins imm64zx48:$enc, AnyGRFP:$R1, + bdxaddr20only:$XBD2), + "InsnRXY,$enc,$R1,$XBD2", []>; + def AsmInsnS : DirectiveInsnS<(outs), + (ins imm64zx32:$enc, bdaddr12only:$BD2), + "InsnS,$enc,$BD2", []>; + def AsmInsnSI : DirectiveInsnSI<(outs), + (ins imm64zx32:$enc, bdaddr12only:$BD1, + imm32sx8:$I2), + "InsnSI,$enc,$BD1,$I2", []>; + def AsmInsnSIY : DirectiveInsnSIY<(outs), + (ins imm64zx48:$enc, + bdaddr20only:$BD1, imm32zx8:$I2), + "InsnSIY,$enc,$BD1,$I2", []>; + def AsmInsnSIL : DirectiveInsnSIL<(outs), + (ins imm64zx48:$enc, bdaddr12only:$BD1, + imm32zx16:$I2), + "InsnSIL,$enc,$BD1,$I2", []>; + def AsmInsnSS : DirectiveInsnSS<(outs), + (ins imm64zx48:$enc, bdxaddr12only:$XBD1, + bdaddr12only:$BD2, AnyGRFP:$R3), + "InsnSS,$enc,$XBD1,$BD2,$R3", []>; + def AsmInsnSSE : DirectiveInsnSSE<(outs), + (ins imm64zx48:$enc, + bdaddr12only:$BD1,bdaddr12only:$BD2), + "InsnSSE,$enc,$BD1,$BD2", []>; + def AsmInsnSSF : DirectiveInsnSSF<(outs), + (ins imm64zx48:$enc, bdaddr12only:$BD1, + bdaddr12only:$BD2, AnyGRFP:$R3), + "InsnSSF,$enc,$BD1,$BD2,$R3", []>; +} //===----------------------------------------------------------------------===// // Peepholes. Index: lib/Target/SystemZ/SystemZOperands.td =================================================================== --- lib/Target/SystemZ/SystemZOperands.td +++ lib/Target/SystemZ/SystemZOperands.td @@ -230,6 +230,12 @@ MVT::i64); }]>; +// Truncate an immediate to a 48-bit unsigned quantity. +def UIMM48 : SDNodeXFormgetTargetConstant(uint64_t(N->getZExtValue()) & 0xffffffffffff, + SDLoc(N), MVT::i64); +}]>; + // Negate and then truncate an immediate to a 32-bit unsigned quantity. def NEGIMM32 : SDNodeXFormgetTargetConstant(uint32_t(-N->getZExtValue()), SDLoc(N), @@ -252,6 +258,7 @@ def U16Imm : ImmediateAsmOperand<"U16Imm">; def S32Imm : ImmediateAsmOperand<"S32Imm">; def U32Imm : ImmediateAsmOperand<"U32Imm">; +def U48Imm : ImmediateAsmOperand<"U48Imm">; //===----------------------------------------------------------------------===// // i32 immediates @@ -425,6 +432,10 @@ return isUInt<32>(-N->getSExtValue()); }], NEGIMM32, "U32Imm">; +def imm64zx48 : Immediate(N->getZExtValue()); +}], UIMM48, "U48Imm">; + def imm64 : ImmLeaf, Operand; //===----------------------------------------------------------------------===// Index: lib/Target/SystemZ/SystemZRegisterInfo.td =================================================================== --- lib/Target/SystemZ/SystemZRegisterInfo.td +++ lib/Target/SystemZ/SystemZRegisterInfo.td @@ -121,6 +121,12 @@ // of a GR128. defm ADDR128 : SystemZRegClass<"ADDR128", [untyped], 128, (sub GR128Bit, R0Q)>; +// Any GR or FP type register. Used for .insn directives when we don't know +// what the register types will be. +defm AnyGRFP : SystemZRegClass<"AnyGRFP", [i64, f64], 64, + (add (sequence "R%uD", 0, 15), + (sequence "F%uD", 0, 15))>; + //===----------------------------------------------------------------------===// // Floating-point registers //===----------------------------------------------------------------------===// Index: test/MC/Disassembler/SystemZ/insns-pcrel.txt =================================================================== --- test/MC/Disassembler/SystemZ/insns-pcrel.txt +++ test/MC/Disassembler/SystemZ/insns-pcrel.txt @@ -1762,3 +1762,51 @@ # 0x00000a02: # CHECK: exrl %r15, 0x100000a00 0xc6 0xf0 0x7f 0xff 0xff 0xff + +# 0x00000a08: +# CHECK: brxh %r0, %r1, 0xa08 +0x84 0x01 0x00 0x00 + +# 0x00000a0c: +# CHECK: brxh %r14, %r1, 0xa0c +0x84 0xe1 0x00 0x00 + +# 0x00000a10: +# CHECK: brxh %r15, %r1, 0xa10 +0x84 0xf1 0x00 0x00 + +# 0x00000a14: +# CHECK: brxh %r0, %r1, 0xa12 +0x84 0x01 0xff 0xff + +# 0x00000a18: +# CHECK: brxh %r14, %r1, 0xffffffffffff0a18 +0x84 0xe1 0x80 0x00 + +# 0x00000a1c: +# CHECK: brxh %r15, %r1, 0x10a1a +0x84 0xf1 0x7f 0xff + +# 0x00000a20: +# CHECK: brxle %r0, %r1, 0xa20 +0x85 0x01 0x00 0x00 + +# 0x00000a24: +# CHECK: brxle %r14, %r1, 0xa24 +0x85 0xe1 0x00 0x00 + +# 0x00000a28: +# CHECK: brxle %r15, %r1, 0xa28 +0x85 0xf1 0x00 0x00 + +# 0x00000a2c: +# CHECK: brxle %r0, %r1, 0xa2a +0x85 0x01 0xff 0xff + +# 0x00000a30: +# CHECK: brxle %r14, %r1, 0xffffffffffff0a30 +0x85 0xe1 0x80 0x00 + +# 0x00000a34: +# CHECK: brxle %r15, %r1, 0x10a32 +0x85 0xf1 0x7f 0xff Index: test/MC/Disassembler/SystemZ/insns.txt =================================================================== --- test/MC/Disassembler/SystemZ/insns.txt +++ test/MC/Disassembler/SystemZ/insns.txt @@ -3199,6 +3199,27 @@ # CHECK: ear %r15, %a15 0xb2 0x4f 0x00 0xff +# CHECK: ectg 0, 0, %r0 +0xc8 0x01 0x00 0x00 0x00 0x00 + +# CHECK: ectg 0, 4095, %r2 +0xc8 0x21 0x00 0x00 0x0f 0xff + +# CHECK: ectg 0, 0(%r1), %r2 +0xc8 0x21 0x00 0x00 0x10 0x00 + +# CHECK: ectg 0, 0(%r15), %r2 +0xc8 0x21 0x00 0x00 0xf0 0x00 + +# CHECK: ectg 0(%r1), 4095(%r15), %r2 +0xc8 0x21 0x10 0x00 0xff 0xff + +# CHECK: ectg 0(%r1), 0(%r15), %r2 +0xc8 0x21 0x10 0x00 0xf0 0x00 + +# CHECK: ectg 4095(%r1), 0(%r15), %r2 +0xc8 0x21 0x1f 0xff 0xf0 0x00 + # CHECK: etnd %r0 0xb2 0xec 0x00 0x00 @@ -6502,6 +6523,27 @@ # CHECK: mvc 0(256,%r15), 0 0xd2 0xff 0xf0 0x00 0x00 0x00 +# CHECK: mvck 0, 0, %r0 +0xd9 0x00 0x00 0x00 0x00 0x00 + +# CHECK: mvck 0, 4095, %r2 +0xd9 0x02 0x00 0x00 0x0f 0xff + +# CHECK: mvck 0, 0(%r1), %r2 +0xd9 0x02 0x00 0x00 0x10 0x00 + +# CHECK: mvck 0, 0(%r15), %r2 +0xd9 0x02 0x00 0x00 0xf0 0x00 + +# CHECK: mvck 0(%r1), 4095(%r15), %r2 +0xd9 0x02 0x10 0x00 0xff 0xff + +# CHECK: mvck 0(%r1), 0(%r15), %r2 +0xd9 0x02 0x10 0x00 0xf0 0x00 + +# CHECK: mvck 4095(%r15,%r1), 0(%r15), %r2 +0xd9 0xf2 0x1f 0xff 0xf0 0x00 + # CHECK: mvghi 0, 0 0xe5 0x48 0x00 0x00 0x00 0x00 @@ -7309,6 +7351,9 @@ # CHECK: pfd 15, 0 0xe3 0xf0 0x00 0x00 0x00 0x36 +# CHECK: pr +0x01 0x01 + # CHECK: popcnt %r0, %r0 0xb9 0xe1 0x00 0x00 @@ -9022,6 +9067,24 @@ # CHECK: stmy %r0, %r0, 524287(%r15) 0xeb 0x00 0xff 0xff 0x7f 0x90 +# CHECK: strag 0, 0 +0xe5 0x02 0x00 0x00 0x00 0x00 + +# CHECK: strag 0, 4095 +0xe5 0x02 0x00 0x00 0x0f 0xff + +# CHECK: strag 0, 0(%r1) +0xe5 0x02 0x00 0x00 0x10 0x00 + +# CHECK: strag 0, 0(%r15) +0xe5 0x02 0x00 0x00 0xf0 0x00 + +# CHECK: strag 0(%r1), 4095(%r15) +0xe5 0x02 0x10 0x00 0xff 0xff + +# CHECK: strag 4095(%r1), 0(%r15) +0xe5 0x02 0x1f 0xff 0xf0 0x00 + # CHECK: strvg %r0, -524288 0xe3 0x00 0x00 0x00 0x80 0x2f Index: test/MC/SystemZ/directive-insn.s =================================================================== --- /dev/null +++ test/MC/SystemZ/directive-insn.s @@ -0,0 +1,102 @@ +# RUN: llvm-mc -triple s390x-linux-gnu -filetype=obj %s | \ +# RUN: llvm-objdump -mcpu=zEC12 -disassemble - | FileCheck %s + +# Test the .insn directive which provides a way of encoding an instruction +# directly. It takes a format, encoding, and operands based on the format. + +#CHECK: 01 01 pr + .insn e,0x0101 + +#CHECK: a7 18 12 34 lhi %r1, 4660 + .insn ri,0xa7080000,%r1,0x1234 + +# GAS considers this instruction's immediate operand to be PC relative. +#CHECK: ec 12 00 06 00 76 crj %r1, %r2, 0, 0x12 + .insn rie,0xec0000000076,%r1,%r2,12 +#CHECK: ec 12 00 03 00 64 cgrj %r1, %r2, 0, 0x12 + .insn rie,0xec0000000064,%r1,%r2,label.rie +#CHECK: label.rie: +label.rie: + +# GAS considers this instruction's immediate operand to be PC relative. +#CHECK: c6 1d 00 00 00 06 crl %r1, 0x1e + .insn ril,0xc60d00000000,%r1,12 +#CHECK: c6 18 00 00 00 03 cgrl %r1, 0x1e + .insn ril,0xc60800000000,%r1,label.ril +#CHECK: label.ril: +label.ril: + +#CHECK: c2 2b 80 00 00 00 alfi %r2, 2147483648 + .insn rilu,0xc20b00000000,%r2,0x80000000 + +#CHECK: ec 1c f0 a0 34 fc cgible %r1, 52, 160(%r15) + .insn ris,0xec00000000fc,%r1,0x34,0xc,160(%r15) + +# Test using an integer in place of a register. +#CHECK: 18 23 lr %r2, %r3 + .insn rr,0x1800,2,3 + +#CHECK: b9 14 00 45 lgfr %r4, %r5 + .insn rre,0xb9140000,%r4,%r5 + +# Test FP and GR registers in a single directive. +#CHECK: b3 c1 00 fe ldgr %f15, %r14 + .insn rre,0xb3c10000,%f15,%r14 + +# Test using an integer in place of a register. +#CHECK: b3 44 34 12 ledbra %f1, 3, %f2, 4 + .insn rrf,0xb3440000,%f1,2,%f3,4 + +#CHECK: ec 34 f0 b4 a0 e4 cgrbhe %r3, %r4, 180(%r15) + .insn rrs,0xec00000000e4,%r3,%r4,0xa,180(%r15) + +#CHECK: ba 01 f0 a0 cs %r0, %r1, 160(%r15) + .insn rs,0xba000000,%r0,%r1,160(%r15) + +# GAS considers this instruction's immediate operand to be PC relative. +#CHECK: 84 13 00 04 brxh %r1, %r3, 0x4a + .insn rsi,0x84000000,%r1,%r3,8 +#CHECK: 84 13 00 02 brxh %r1, %r3, 0x4a + .insn rsi,0x84000000,%r1,%r3,label.rsi +#CHECK: label.rsi: +label.rsi: + +# RSE formats are short displacement versions of the RSY formats. +#CHECK: eb 12 f0 a0 00 f8 laa %r1, %r2, 160(%r15) + .insn rse,0xeb00000000f8,%r1,%r2,160(%r15) + +#CHECK: eb 12 f3 45 12 30 csg %r1, %r2, 74565(%r15) + .insn rsy,0xeb0000000030,%r1,%r2,74565(%r15) + +#CHECK: 59 13 f0 a0 c %r1, 160(%r3,%r15) + .insn rx,0x59000000,%r1,160(%r3,%r15) + +#CHECK: ed 13 f0 a0 00 19 cdb %f1, 160(%r3,%r15) + .insn rxe,0xed0000000019,%f1,160(%r3,%r15) + +#CHECK: ed 23 f0 a0 10 1e madb %f1, %f2, 160(%r3,%r15) + .insn rxf,0xed000000001e,%f1,%f2,160(%r3,%r15) + +#CHECK: ed 12 f1 23 90 65 ldy %f1, -458461(%r2,%r15) + .insn rxy,0xed0000000065,%f1,-458461(%r2,%r15) + +#CHECK: b2 fc f0 a0 tabort 160(%r15) + .insn s,0xb2fc0000,160(%r15) + +#CHECK: 91 34 f0 a0 tm 160(%r15), 52 + .insn si,0x91000000,160(%r15),52 + +#CHECK: eb f0 fc de ab 51 tmy -344866(%r15), 240 + .insn siy,0xeb0000000051,-344866(%r15),240 + +#CHECK: e5 60 f0 a0 12 34 tbegin 160(%r15), 4660 + .insn sil,0xe56000000000,160(%r15),0x1234 + +#CHECK: d9 13 f1 23 e4 56 mvck 291(%r1,%r15), 1110(%r14), %r3 + .insn ss,0xd90000000000,291(%r1,%r15),1110(%r14),%r3 + +#CHECK: e5 02 10 a0 21 23 strag 160(%r1), 291(%r2) + .insn sse,0xe50200000000,160(%r1),291(%r2) + +#CHECK: c8 31 f0 a0 e2 34 ectg 160(%r15), 564(%r14), %r3 + .insn ssf,0xc80100000000,160(%r15),564(%r14),%r3 Index: test/MC/SystemZ/insn-bad.s =================================================================== --- test/MC/SystemZ/insn-bad.s +++ test/MC/SystemZ/insn-bad.s @@ -370,6 +370,34 @@ brctg %r0, 1 brctg %r0, 0x10000 +#CHECK: error: offset out of range +#CHECK: brxh %r0, %r2, -0x100002 +#CHECK: error: offset out of range +#CHECK: brxh %r0, %r2, -1 +#CHECK: error: offset out of range +#CHECK: brxh %r0, %r2, 1 +#CHECK: error: offset out of range +#CHECK: brxh %r0, %r2, 0x10000 + + brxh %r0, %r2, -0x100002 + brxh %r0, %r2, -1 + brxh %r0, %r2, 1 + brxh %r0, %r2, 0x10000 + +#CHECK: error: offset out of range +#CHECK: brxle %r0, %r2, -0x100002 +#CHECK: error: offset out of range +#CHECK: brxle %r0, %r2, -1 +#CHECK: error: offset out of range +#CHECK: brxle %r0, %r2, 1 +#CHECK: error: offset out of range +#CHECK: brxle %r0, %r2, 0x10000 + + brxle %r0, %r2, -0x100002 + brxle %r0, %r2, -1 + brxle %r0, %r2, 1 + brxle %r0, %r2, 0x10000 + #CHECK: error: invalid operand #CHECK: c %r0, -1 #CHECK: error: invalid operand @@ -1419,6 +1447,23 @@ ex %r0, -1 ex %r0, 4096 +#CHECK: error: invalid use of indexed addressing +#CHECK: ectg 160(%r1,%r15),160(%r15), %r2 +#CHECK: error: invalid operand +#CHECK: ectg -1(%r1),160(%r15), %r2 +#CHECK: error: invalid operand +#CHECK: ectg 4096(%r1),160(%r15), %r2 +#CHECK: error: invalid operand +#CHECK: ectg 0(%r1),-1(%r15), %r2 +#CHECK: error: invalid operand +#CHECK: ectg 0(%r1),4096(%r15), %r2 + + ectg 160(%r1,%r15),160(%r15), %r2 + ectg -1(%r1),160(%r15), %r2 + ectg 4096(%r1),160(%r15), %r2 + ectg 0(%r1),-1(%r15), %r2 + ectg 0(%r1),4096(%r15), %r2 + #CHECK: error: invalid operand #CHECK: fidbr %f0, -1, %f0 #CHECK: error: invalid operand @@ -2371,6 +2416,38 @@ mvc 0(1,%r2), 0(%r1,%r2) mvc 0(-), 0 +#CHECK: error: invalid use of length addressing +#CHECK: mvck 0(%r1,%r1), 0(2,%r1), %r3 +#CHECK: error: %r0 used in an address +#CHECK: mvck 0(%r0,%r1), 0(%r1), %r3 +#CHECK: error: invalid operand +#CHECK: mvck -1(%r1,%r1), 0(%r1), %r3 +#CHECK: error: invalid operand +#CHECK: mvck 4096(%r1,%r1), 0(%r1), %r3 +#CHECK: error: invalid operand +#CHECK: mvck 0(%r1,%r1), -1(%r1), %r3 +#CHECK: error: invalid operand +#CHECK: mvck 0(%r1,%r1), 4096(%r1), %r3 +#CHECK: error: %r0 used in an address +#CHECK: mvck 0(%r1,%r0), 0(%r1), %r3 +#CHECK: error: %r0 used in an address +#CHECK: mvck 0(%r1,%r1), 0(%r0), %r3 +#CHECK: error: invalid use of indexed addressing +#CHECK: mvck 0(%r1,%r2), 0(%r1,%r2), %r3 +#CHECK: error: unknown token in expression +#CHECK: mvck 0(-), 0, %r3 + + mvck 0(%r1,%r1), 0(2,%r1), %r3 + mvck 0(%r0,%r1), 0(%r1), %r3 + mvck -1(%r1,%r1), 0(%r1), %r3 + mvck 4096(%r1,%r1), 0(%r1), %r3 + mvck 0(%r1,%r1), -1(%r1), %r3 + mvck 0(%r1,%r1), 4096(%r1), %r3 + mvck 0(%r1,%r0), 0(%r1), %r3 + mvck 0(%r1,%r1), 0(%r0), %r3 + mvck 0(%r1,%r2), 0(%r1,%r2), %r3 + mvck 0(-), 0, %r3 + #CHECK: error: invalid operand #CHECK: mvghi -1, 0 #CHECK: error: invalid operand @@ -2840,6 +2917,10 @@ popcnt %r0, %r0 #CHECK: error: invalid operand +#CHECK: pr %r0 + pr %r0 + +#CHECK: error: invalid operand #CHECK: risbg %r0,%r0,0,0,-1 #CHECK: error: invalid operand #CHECK: risbg %r0,%r0,0,0,64 @@ -3403,6 +3484,23 @@ stmy %r0, %r0, 524288 stmy %r0, %r0, 0(%r1,%r2) +#CHECK: error: invalid use of indexed addressing +#CHECK: strag 160(%r1,%r15),160(%r15) +#CHECK: error: invalid operand +#CHECK: strag -1(%r1),160(%r15) +#CHECK: error: invalid operand +#CHECK: strag 4096(%r1),160(%r15) +#CHECK: error: invalid operand +#CHECK: strag 0(%r1),-1(%r15) +#CHECK: error: invalid operand +#CHECK: strag 0(%r1),4096(%r15) + + strag 160(%r1,%r15),160(%r15) + strag -1(%r1),160(%r15) + strag 4096(%r1),160(%r15) + strag 0(%r1),-1(%r15) + strag 0(%r1),4096(%r15) + #CHECK: error: offset out of range #CHECK: strl %r0, -0x1000000002 #CHECK: error: offset out of range Index: test/MC/SystemZ/insn-good.s =================================================================== --- test/MC/SystemZ/insn-good.s +++ test/MC/SystemZ/insn-good.s @@ -1281,6 +1281,92 @@ #CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL brctg %r15, 0 +#CHECK: brxh %r0, %r2, .[[LAB:L.*]]-65536 # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL + brxh %r0,%r2, -0x10000 +#CHECK: brxh %r0, %r2, .[[LAB:L.*]]-2 # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL + brxh %r0, %r2, -2 +#CHECK: brxh %r0, %r2, .[[LAB:L.*]] # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL + brxh %r0,%r2, 0 +#CHECK: brxh %r0, %r2, .[[LAB:L.*]]+65534 # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL + brxh %r0,%r2, 0xfffe + +#CHECK: brxh %r0, %r2, foo # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: brxh %r14, %r2, foo # encoding: [0x84,0xe2,A,A] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: brxh %r15, %r2, foo # encoding: [0x84,0xf2,A,A] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + brxh %r0,%r2,foo + brxh %r14,%r2,foo + brxh %r15,%r2,foo + +#CHECK: brxh %r0, %r2, bar+100 # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL +#CHECK: brxh %r14, %r2, bar+100 # encoding: [0x84,0xe2,A,A] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL +#CHECK: brxh %r15, %r2, bar+100 # encoding: [0x84,0xf2,A,A] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + brxh %r0,%r2,bar+100 + brxh %r14,%r2,bar+100 + brxh %r15,%r2,bar+100 + +#CHECK: brxh %r0, %r2, bar@PLT # encoding: [0x84,0x02,A,A] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL +#CHECK: brxh %r14, %r2, bar@PLT # encoding: [0x84,0xe2,A,A] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL +#CHECK: brxh %r15, %r2, bar@PLT # encoding: [0x84,0xf2,A,A] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + brxh %r0,%r2,bar@PLT + brxh %r14,%r2,bar@PLT + brxh %r15,%r2,bar@PLT + +#CHECK: brxle %r0, %r2, .[[LAB:L.*]]-65536 # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-65536)+2, kind: FK_390_PC16DBL + brxle %r0,%r2, -0x10000 +#CHECK: brxle %r0, %r2, .[[LAB:L.*]]-2 # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]-2)+2, kind: FK_390_PC16DBL + brxle %r0, %r2, -2 +#CHECK: brxle %r0, %r2, .[[LAB:L.*]] # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: .[[LAB]]+2, kind: FK_390_PC16DBL + brxle %r0,%r2, 0 +#CHECK: brxle %r0, %r2, .[[LAB:L.*]]+65534 # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (.[[LAB]]+65534)+2, kind: FK_390_PC16DBL + brxle %r0,%r2, 0xfffe + +#CHECK: brxle %r0, %r2, foo # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: brxle %r14, %r2, foo # encoding: [0x85,0xe2,A,A] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL +#CHECK: brxle %r15, %r2, foo # encoding: [0x85,0xf2,A,A] +#CHECK: fixup A - offset: 2, value: foo+2, kind: FK_390_PC16DBL + brxle %r0,%r2,foo + brxle %r14,%r2,foo + brxle %r15,%r2,foo + +#CHECK: brxle %r0, %r2, bar+100 # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL +#CHECK: brxle %r14, %r2, bar+100 # encoding: [0x85,0xe2,A,A] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL +#CHECK: brxle %r15, %r2, bar+100 # encoding: [0x85,0xf2,A,A] +#CHECK: fixup A - offset: 2, value: (bar+100)+2, kind: FK_390_PC16DBL + brxle %r0,%r2,bar+100 + brxle %r14,%r2,bar+100 + brxle %r15,%r2,bar+100 + +#CHECK: brxle %r0, %r2, bar@PLT # encoding: [0x85,0x02,A,A] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL +#CHECK: brxle %r14, %r2, bar@PLT # encoding: [0x85,0xe2,A,A] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL +#CHECK: brxle %r15, %r2, bar@PLT # encoding: [0x85,0xf2,A,A] +#CHECK: fixup A - offset: 2, value: bar@PLT+2, kind: FK_390_PC16DBL + brxle %r0,%r2,bar@PLT + brxle %r14,%r2,bar@PLT + brxle %r15,%r2,bar@PLT + #CHECK: c %r0, 0 # encoding: [0x59,0x00,0x00,0x00] #CHECK: c %r0, 4095 # encoding: [0x59,0x00,0x0f,0xff] #CHECK: c %r0, 0(%r1) # encoding: [0x59,0x00,0x10,0x00] @@ -5326,6 +5412,20 @@ ear %r7, %a8 ear %r15, %a15 +#CHECK: ectg 0, 0, %r0 # encoding: [0xc8,0x01,0x00,0x00,0x00,0x00] +#CHECK: ectg 0(%r1), 0(%r15), %r2 # encoding: [0xc8,0x21,0x10,0x00,0xf0,0x00] +#CHECK: ectg 1(%r1), 0(%r15), %r2 # encoding: [0xc8,0x21,0x10,0x01,0xf0,0x00] +#CHECK: ectg 4095(%r1), 0(%r15), %r2 # encoding: [0xc8,0x21,0x1f,0xff,0xf0,0x00] +#CHECK: ectg 0(%r1), 1(%r15), %r2 # encoding: [0xc8,0x21,0x10,0x00,0xf0,0x01] +#CHECK: ectg 0(%r1), 4095(%r15), %r2 # encoding: [0xc8,0x21,0x10,0x00,0xff,0xff] + + ectg 0,0,%r0 + ectg 0(%r1),0(%r15),%r2 + ectg 1(%r1),0(%r15),%r2 + ectg 4095(%r1),0(%r15),%r2 + ectg 0(%r1),1(%r15),%r2 + ectg 0(%r1),4095(%r15),%r2 + #CHECK: ex %r0, 0 # encoding: [0x44,0x00,0x00,0x00] #CHECK: ex %r0, 4095 # encoding: [0x44,0x00,0x0f,0xff] #CHECK: ex %r0, 0(%r1) # encoding: [0x44,0x00,0x10,0x00] @@ -7652,6 +7752,32 @@ mvc 0(256,%r1), 0 mvc 0(256,%r15), 0 +#CHECK: mvck 0(%r1), 0, %r3 # encoding: [0xd9,0x03,0x10,0x00,0x00,0x00] +#CHECK: mvck 0(%r1), 0(%r1), %r3 # encoding: [0xd9,0x03,0x10,0x00,0x10,0x00] +#CHECK: mvck 0(%r1), 0(%r15), %r3 # encoding: [0xd9,0x03,0x10,0x00,0xf0,0x00] +#CHECK: mvck 0(%r1), 4095, %r3 # encoding: [0xd9,0x03,0x10,0x00,0x0f,0xff] +#CHECK: mvck 0(%r1), 4095(%r1), %r3 # encoding: [0xd9,0x03,0x10,0x00,0x1f,0xff] +#CHECK: mvck 0(%r1), 4095(%r15), %r3 # encoding: [0xd9,0x03,0x10,0x00,0xff,0xff] +#CHECK: mvck 0(%r2,%r1), 0, %r3 # encoding: [0xd9,0x23,0x10,0x00,0x00,0x00] +#CHECK: mvck 0(%r2,%r15), 0, %r3 # encoding: [0xd9,0x23,0xf0,0x00,0x00,0x00] +#CHECK: mvck 4095(%r2,%r1), 0, %r3 # encoding: [0xd9,0x23,0x1f,0xff,0x00,0x00] +#CHECK: mvck 4095(%r2,%r15), 0, %r3 # encoding: [0xd9,0x23,0xff,0xff,0x00,0x00] +#CHECK: mvck 0(%r2,%r1), 0, %r3 # encoding: [0xd9,0x23,0x10,0x00,0x00,0x00] +#CHECK: mvck 0(%r2,%r15), 0, %r3 # encoding: [0xd9,0x23,0xf0,0x00,0x00,0x00] + + mvck 0(%r1), 0, %r3 + mvck 0(%r1), 0(%r1), %r3 + mvck 0(%r1), 0(%r15), %r3 + mvck 0(%r1), 4095, %r3 + mvck 0(%r1), 4095(%r1), %r3 + mvck 0(%r1), 4095(%r15), %r3 + mvck 0(%r2,%r1), 0, %r3 + mvck 0(%r2,%r15), 0, %r3 + mvck 4095(%r2,%r1), 0, %r3 + mvck 4095(%r2,%r15), 0, %r3 + mvck 0(%r2,%r1), 0, %r3 + mvck 0(%r2,%r15), 0, %r3 + #CHECK: mvghi 0, 0 # encoding: [0xe5,0x48,0x00,0x00,0x00,0x00] #CHECK: mvghi 4095, 0 # encoding: [0xe5,0x48,0x0f,0xff,0x00,0x00] #CHECK: mvghi 0, -32768 # encoding: [0xe5,0x48,0x00,0x00,0x80,0x00] @@ -8273,6 +8399,9 @@ pfdrl 7, frob@PLT pfdrl 8, frob@PLT +#CHECK: pr # encoding: [0x01,0x01] + pr + #CHECK: risbg %r0, %r0, 0, 0, 0 # encoding: [0xec,0x00,0x00,0x00,0x00,0x55] #CHECK: risbg %r0, %r0, 0, 0, 63 # encoding: [0xec,0x00,0x00,0x00,0x3f,0x55] #CHECK: risbg %r0, %r0, 0, 255, 0 # encoding: [0xec,0x00,0x00,0xff,0x00,0x55] @@ -9409,6 +9538,28 @@ stmy %r0,%r0,524287(%r1) stmy %r0,%r0,524287(%r15) +#CHECK: strag 0, 0 # encoding: [0xe5,0x02,0x00,0x00,0x00,0x00] +#CHECK: strag 0(%r1), 0(%r2) # encoding: [0xe5,0x02,0x10,0x00,0x20,0x00] +#CHECK: strag 160(%r1), 320(%r15) # encoding: [0xe5,0x02,0x10,0xa0,0xf1,0x40] +#CHECK: strag 0(%r1), 4095 # encoding: [0xe5,0x02,0x10,0x00,0x0f,0xff] +#CHECK: strag 0(%r1), 4095(%r2) # encoding: [0xe5,0x02,0x10,0x00,0x2f,0xff] +#CHECK: strag 0(%r1), 4095(%r15) # encoding: [0xe5,0x02,0x10,0x00,0xff,0xff] +#CHECK: strag 0(%r1), 0 # encoding: [0xe5,0x02,0x10,0x00,0x00,0x00] +#CHECK: strag 0(%r15), 0 # encoding: [0xe5,0x02,0xf0,0x00,0x00,0x00] +#CHECK: strag 4095(%r1), 0 # encoding: [0xe5,0x02,0x1f,0xff,0x00,0x00] +#CHECK: strag 4095(%r15), 0 # encoding: [0xe5,0x02,0xff,0xff,0x00,0x00] + + strag 0, 0 + strag 0(%r1), 0(%r2) + strag 160(%r1), 320(%r15) + strag 0(%r1), 4095 + strag 0(%r1), 4095(%r2) + strag 0(%r1), 4095(%r15) + strag 0(%r1), 0 + strag 0(%r15), 0 + strag 4095(%r1), 0 + strag 4095(%r15), 0 + #CHECK: strl %r0, .[[LAB:L.*]]-4294967296 # encoding: [0xc4,0x0f,A,A,A,A] #CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL strl %r0, -0x100000000