Skip to content

Commit a8b04e1

Browse files
committedMay 5, 2015
[SystemZ] Add z13 vector facility and MC support
This patch adds support for the z13 processor type and its vector facility, and adds MC support for all new instructions provided by that facilily. Apart from defining the new instructions, the main changes are: - Adding VR128, VR64 and VR32 register classes. - Making FP64 a subclass of VR64 and FP32 a subclass of VR32. - Adding a D(V,B) addressing mode for scatter/gather operations - Adding 1-, 2-, and 3-bit immediate operands for some 4-bit fields. Until now all immediate operands have been the same width as the underlying field (hence the assert->return change in decode[SU]ImmOperand). In addition, sys::getHostCPUName is extended to detect running natively on a z13 machine. Based on a patch by Richard Sandiford. llvm-svn: 236520
1 parent b8499f0 commit a8b04e1

22 files changed

+13182
-117
lines changed
 

‎llvm/lib/Support/Host.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -682,13 +682,37 @@ StringRef sys::getHostCPUName() {
682682
StringRef Str(buffer, CPUInfoSize);
683683
SmallVector<StringRef, 32> Lines;
684684
Str.split(Lines, "\n");
685+
686+
// Look for the CPU features.
687+
SmallVector<StringRef, 32> CPUFeatures;
688+
for (unsigned I = 0, E = Lines.size(); I != E; ++I)
689+
if (Lines[I].startswith("features")) {
690+
size_t Pos = Lines[I].find(":");
691+
if (Pos != StringRef::npos) {
692+
Lines[I].drop_front(Pos + 1).split(CPUFeatures, " ");
693+
break;
694+
}
695+
}
696+
697+
// We need to check for the presence of vector support independently of
698+
// the machine type, since we may only use the vector register set when
699+
// supported by the kernel (and hypervisor).
700+
bool HaveVectorSupport = false;
701+
for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
702+
if (CPUFeatures[I] == "vx")
703+
HaveVectorSupport = true;
704+
}
705+
706+
// Now check the processor machine type.
685707
for (unsigned I = 0, E = Lines.size(); I != E; ++I) {
686708
if (Lines[I].startswith("processor ")) {
687709
size_t Pos = Lines[I].find("machine = ");
688710
if (Pos != StringRef::npos) {
689711
Pos += sizeof("machine = ") - 1;
690712
unsigned int Id;
691713
if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) {
714+
if (Id >= 2964 && HaveVectorSupport)
715+
return "z13";
692716
if (Id >= 2827)
693717
return "zEC12";
694718
if (Id >= 2817)

‎llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp

+93-31
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,17 @@ enum RegisterKind {
3939
ADDR64Reg,
4040
FP32Reg,
4141
FP64Reg,
42-
FP128Reg
42+
FP128Reg,
43+
VR32Reg,
44+
VR64Reg,
45+
VR128Reg
4346
};
4447

4548
enum MemoryKind {
4649
BDMem,
4750
BDXMem,
48-
BDLMem
51+
BDLMem,
52+
BDVMem
4953
};
5054

5155
class SystemZOperand : public MCParsedAsmOperand {
@@ -89,10 +93,10 @@ class SystemZOperand : public MCParsedAsmOperand {
8993
// the base register has (ADDR32Reg or ADDR64Reg). Length is the operand
9094
// length for D(L,B)-style operands, otherwise it is null.
9195
struct MemOp {
92-
unsigned Base : 8;
93-
unsigned Index : 8;
94-
unsigned MemKind : 8;
95-
unsigned RegKind : 8;
96+
unsigned Base : 12;
97+
unsigned Index : 12;
98+
unsigned MemKind : 4;
99+
unsigned RegKind : 4;
96100
const MCExpr *Disp;
97101
const MCExpr *Length;
98102
};
@@ -246,6 +250,13 @@ class SystemZOperand : public MCParsedAsmOperand {
246250
bool isMemDisp12Len8(RegisterKind RegKind) const {
247251
return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length, 1, 0x100);
248252
}
253+
void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
254+
assert(N == 3 && "Invalid number of operands");
255+
assert(isMem(BDVMem) && "Invalid operand type");
256+
Inst.addOperand(MCOperand::CreateReg(Mem.Base));
257+
addExpr(Inst, Mem.Disp);
258+
Inst.addOperand(MCOperand::CreateReg(Mem.Index));
259+
}
249260

250261
// Override MCParsedAsmOperand.
251262
SMLoc getStartLoc() const override { return StartLoc; }
@@ -307,17 +318,26 @@ class SystemZOperand : public MCParsedAsmOperand {
307318
bool isFP32() const { return isReg(FP32Reg); }
308319
bool isFP64() const { return isReg(FP64Reg); }
309320
bool isFP128() const { return isReg(FP128Reg); }
321+
bool isVR32() const { return isReg(VR32Reg); }
322+
bool isVR64() const { return isReg(VR64Reg); }
323+
bool isVF128() const { return false; }
324+
bool isVR128() const { return isReg(VR128Reg); }
310325
bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); }
311326
bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); }
312327
bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, ADDR64Reg); }
313328
bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, ADDR64Reg); }
314329
bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, ADDR64Reg); }
315330
bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, ADDR64Reg); }
316331
bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); }
332+
bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, ADDR64Reg); }
333+
bool isU1Imm() const { return isImm(0, 1); }
334+
bool isU2Imm() const { return isImm(0, 3); }
335+
bool isU3Imm() const { return isImm(0, 7); }
317336
bool isU4Imm() const { return isImm(0, 15); }
318337
bool isU6Imm() const { return isImm(0, 63); }
319338
bool isU8Imm() const { return isImm(0, 255); }
320339
bool isS8Imm() const { return isImm(-128, 127); }
340+
bool isU12Imm() const { return isImm(0, 4095); }
321341
bool isU16Imm() const { return isImm(0, 65535); }
322342
bool isS16Imm() const { return isImm(-32768, 32767); }
323343
bool isU32Imm() const { return isImm(0, (1LL << 32) - 1); }
@@ -334,6 +354,7 @@ class SystemZAsmParser : public MCTargetAsmParser {
334354
enum RegisterGroup {
335355
RegGR,
336356
RegFP,
357+
RegV,
337358
RegAccess
338359
};
339360
struct Register {
@@ -352,7 +373,7 @@ class SystemZAsmParser : public MCTargetAsmParser {
352373
RegisterKind Kind);
353374

354375
bool parseAddress(unsigned &Base, const MCExpr *&Disp,
355-
unsigned &Index, const MCExpr *&Length,
376+
unsigned &Index, bool &IsVector, const MCExpr *&Length,
356377
const unsigned *Regs, RegisterKind RegKind);
357378

358379
OperandMatchResultTy parseAddress(OperandVector &Operands,
@@ -419,6 +440,18 @@ class SystemZAsmParser : public MCTargetAsmParser {
419440
OperandMatchResultTy parseFP128(OperandVector &Operands) {
420441
return parseRegister(Operands, RegFP, SystemZMC::FP128Regs, FP128Reg);
421442
}
443+
OperandMatchResultTy parseVR32(OperandVector &Operands) {
444+
return parseRegister(Operands, RegV, SystemZMC::VR32Regs, VR32Reg);
445+
}
446+
OperandMatchResultTy parseVR64(OperandVector &Operands) {
447+
return parseRegister(Operands, RegV, SystemZMC::VR64Regs, VR64Reg);
448+
}
449+
OperandMatchResultTy parseVF128(OperandVector &Operands) {
450+
llvm_unreachable("Shouldn't be used as an operand");
451+
}
452+
OperandMatchResultTy parseVR128(OperandVector &Operands) {
453+
return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg);
454+
}
422455
OperandMatchResultTy parseBDAddr32(OperandVector &Operands) {
423456
return parseAddress(Operands, BDMem, SystemZMC::GR32Regs, ADDR32Reg);
424457
}
@@ -431,6 +464,9 @@ class SystemZAsmParser : public MCTargetAsmParser {
431464
OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
432465
return parseAddress(Operands, BDLMem, SystemZMC::GR64Regs, ADDR64Reg);
433466
}
467+
OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
468+
return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg);
469+
}
434470
OperandMatchResultTy parseAccessReg(OperandVector &Operands);
435471
OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
436472
return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
@@ -484,6 +520,8 @@ bool SystemZAsmParser::parseRegister(Register &Reg) {
484520
Reg.Group = RegGR;
485521
else if (Prefix == 'f' && Reg.Num < 16)
486522
Reg.Group = RegFP;
523+
else if (Prefix == 'v' && Reg.Num < 32)
524+
Reg.Group = RegV;
487525
else if (Prefix == 'a' && Reg.Num < 16)
488526
Reg.Group = RegAccess;
489527
else
@@ -534,8 +572,8 @@ SystemZAsmParser::parseRegister(OperandVector &Operands, RegisterGroup Group,
534572
// Regs maps asm register numbers to LLVM register numbers and RegKind
535573
// says what kind of address register we're using (ADDR32Reg or ADDR64Reg).
536574
bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
537-
unsigned &Index, const MCExpr *&Length,
538-
const unsigned *Regs,
575+
unsigned &Index, bool &IsVector,
576+
const MCExpr *&Length, const unsigned *Regs,
539577
RegisterKind RegKind) {
540578
// Parse the displacement, which must always be present.
541579
if (getParser().parseExpression(Disp))
@@ -544,19 +582,31 @@ bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
544582
// Parse the optional base and index.
545583
Index = 0;
546584
Base = 0;
585+
IsVector = false;
547586
Length = nullptr;
548587
if (getLexer().is(AsmToken::LParen)) {
549588
Parser.Lex();
550589

551590
if (getLexer().is(AsmToken::Percent)) {
552591
// Parse the first register and decide whether it's a base or an index.
553592
Register Reg;
554-
if (parseRegister(Reg, RegGR, Regs, RegKind))
593+
if (parseRegister(Reg))
555594
return true;
556-
if (getLexer().is(AsmToken::Comma))
557-
Index = Reg.Num;
558-
else
559-
Base = Reg.Num;
595+
if (Reg.Group == RegV) {
596+
// A vector index register. The base register is optional.
597+
IsVector = true;
598+
Index = SystemZMC::VR128Regs[Reg.Num];
599+
} else if (Reg.Group == RegGR) {
600+
if (Reg.Num == 0)
601+
return Error(Reg.StartLoc, "%r0 used in an address");
602+
// If the are two registers, the first one is the index and the
603+
// second is the base.
604+
if (getLexer().is(AsmToken::Comma))
605+
Index = Regs[Reg.Num];
606+
else
607+
Base = Regs[Reg.Num];
608+
} else
609+
return Error(Reg.StartLoc, "invalid address register");
560610
} else {
561611
// Parse the length.
562612
if (getParser().parseExpression(Length))
@@ -587,28 +637,36 @@ SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind,
587637
const unsigned *Regs, RegisterKind RegKind) {
588638
SMLoc StartLoc = Parser.getTok().getLoc();
589639
unsigned Base, Index;
640+
bool IsVector;
590641
const MCExpr *Disp;
591642
const MCExpr *Length;
592-
if (parseAddress(Base, Disp, Index, Length, Regs, RegKind))
643+
if (parseAddress(Base, Disp, Index, IsVector, Length, Regs, RegKind))
593644
return MatchOperand_ParseFail;
594645

595-
if (Index && MemKind != BDXMem)
596-
{
597-
Error(StartLoc, "invalid use of indexed addressing");
598-
return MatchOperand_ParseFail;
599-
}
646+
if (IsVector && MemKind != BDVMem) {
647+
Error(StartLoc, "invalid use of vector addressing");
648+
return MatchOperand_ParseFail;
649+
}
600650

601-
if (Length && MemKind != BDLMem)
602-
{
603-
Error(StartLoc, "invalid use of length addressing");
604-
return MatchOperand_ParseFail;
605-
}
651+
if (!IsVector && MemKind == BDVMem) {
652+
Error(StartLoc, "vector index required in address");
653+
return MatchOperand_ParseFail;
654+
}
606655

607-
if (!Length && MemKind == BDLMem)
608-
{
609-
Error(StartLoc, "missing length in address");
610-
return MatchOperand_ParseFail;
611-
}
656+
if (Index && MemKind != BDXMem && MemKind != BDVMem) {
657+
Error(StartLoc, "invalid use of indexed addressing");
658+
return MatchOperand_ParseFail;
659+
}
660+
661+
if (Length && MemKind != BDLMem) {
662+
Error(StartLoc, "invalid use of length addressing");
663+
return MatchOperand_ParseFail;
664+
}
665+
666+
if (!Length && MemKind == BDLMem) {
667+
Error(StartLoc, "missing length in address");
668+
return MatchOperand_ParseFail;
669+
}
612670

613671
SMLoc EndLoc =
614672
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
@@ -631,6 +689,8 @@ bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
631689
RegNo = SystemZMC::GR64Regs[Reg.Num];
632690
else if (Reg.Group == RegFP)
633691
RegNo = SystemZMC::FP64Regs[Reg.Num];
692+
else if (Reg.Group == RegV)
693+
RegNo = SystemZMC::VR128Regs[Reg.Num];
634694
else
635695
// FIXME: Access registers aren't modelled as LLVM registers yet.
636696
return Error(Reg.StartLoc, "invalid operand for instruction");
@@ -703,8 +763,10 @@ bool SystemZAsmParser::parseOperand(OperandVector &Operands,
703763
// so we treat any plain expression as an immediate.
704764
SMLoc StartLoc = Parser.getTok().getLoc();
705765
unsigned Base, Index;
766+
bool IsVector;
706767
const MCExpr *Expr, *Length;
707-
if (parseAddress(Base, Expr, Index, Length, SystemZMC::GR64Regs, ADDR64Reg))
768+
if (parseAddress(Base, Expr, Index, IsVector, Length, SystemZMC::GR64Regs,
769+
ADDR64Reg))
708770
return true;
709771

710772
SMLoc EndLoc =

0 commit comments

Comments
 (0)
Please sign in to comment.