summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2016-11-08 20:15:26 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2016-11-08 20:15:26 +0000
commitba2fbb8f1e4f22aa938ac5210b63a702f274d5de (patch)
treedb624dc2fea7184509258edbcf944c2dade09ef7
parent18fd3e63e3ece05645e1a5b090bbcb83b11cd947 (diff)
downloadllvm-ba2fbb8f1e4f22aa938ac5210b63a702f274d5de.tar.gz
[SystemZ] Model access registers as LLVM registers
Add the 16 access registers as LLVM registers. This allows removing a lot of special cases in the assembler and disassembler where we were handling access registers; this can all just use the generic register code now. Also add a bunch of instructions to operate on access registers, for assembler/disassembler use only. No change in code generation intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@286283 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp55
-rw-r--r--lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp12
-rw-r--r--lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp7
-rw-r--r--lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h1
-rw-r--r--lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp8
-rw-r--r--lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h1
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.cpp8
-rw-r--r--lib/Target/SystemZ/SystemZISelLowering.h4
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.cpp12
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.td31
-rw-r--r--lib/Target/SystemZ/SystemZOperands.td11
-rw-r--r--lib/Target/SystemZ/SystemZOperators.td5
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.cpp5
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.td20
-rw-r--r--lib/Target/SystemZ/SystemZScheduleZ13.td16
-rw-r--r--lib/Target/SystemZ/SystemZScheduleZ196.td16
-rw-r--r--lib/Target/SystemZ/SystemZScheduleZEC12.td16
-rw-r--r--test/MC/Disassembler/SystemZ/insns.txt219
-rw-r--r--test/MC/SystemZ/insn-bad.s54
-rw-r--r--test/MC/SystemZ/insn-good.s161
-rw-r--r--test/MC/SystemZ/regs-bad.s8
-rw-r--r--test/MC/SystemZ/regs-good.s50
22 files changed, 610 insertions, 110 deletions
diff --git a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 3caff5352117..3f373de4d890 100644
--- a/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -43,7 +43,8 @@ enum RegisterKind {
FP128Reg,
VR32Reg,
VR64Reg,
- VR128Reg
+ VR128Reg,
+ AR32Reg,
};
enum MemoryKind {
@@ -61,7 +62,6 @@ private:
KindInvalid,
KindToken,
KindReg,
- KindAccessReg,
KindImm,
KindImmTLS,
KindMem
@@ -116,7 +116,6 @@ private:
union {
TokenOp Token;
RegOp Reg;
- unsigned AccessReg;
const MCExpr *Imm;
ImmTLSOp ImmTLS;
MemOp Mem;
@@ -155,12 +154,6 @@ public:
return Op;
}
static std::unique_ptr<SystemZOperand>
- createAccessReg(unsigned Num, SMLoc StartLoc, SMLoc EndLoc) {
- auto Op = make_unique<SystemZOperand>(KindAccessReg, StartLoc, EndLoc);
- Op->AccessReg = Num;
- return Op;
- }
- static std::unique_ptr<SystemZOperand>
createImm(const MCExpr *Expr, SMLoc StartLoc, SMLoc EndLoc) {
auto Op = make_unique<SystemZOperand>(KindImm, StartLoc, EndLoc);
Op->Imm = Expr;
@@ -212,12 +205,6 @@ public:
return Reg.Num;
}
- // Access register operands. Access registers aren't exposed to LLVM
- // as registers.
- bool isAccessReg() const {
- return Kind == KindAccessReg;
- }
-
// Immediate operands.
bool isImm() const override {
return Kind == KindImm;
@@ -270,11 +257,6 @@ public:
assert(N == 1 && "Invalid number of operands");
Inst.addOperand(MCOperand::createReg(getReg()));
}
- void addAccessRegOperands(MCInst &Inst, unsigned N) const {
- assert(N == 1 && "Invalid number of operands");
- assert(Kind == KindAccessReg && "Invalid operand type");
- Inst.addOperand(MCOperand::createImm(AccessReg));
- }
void addImmOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands");
addExpr(Inst, getImm());
@@ -337,6 +319,7 @@ public:
bool isVR64() const { return isReg(VR64Reg); }
bool isVF128() const { return false; }
bool isVR128() const { return isReg(VR128Reg); }
+ bool isAR32() const { return isReg(AR32Reg); }
bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, ADDR32Reg); }
bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, ADDR32Reg); }
@@ -372,7 +355,7 @@ private:
RegGR,
RegFP,
RegV,
- RegAccess
+ RegAR
};
struct Register {
RegisterGroup Group;
@@ -477,6 +460,9 @@ public:
OperandMatchResultTy parseVR128(OperandVector &Operands) {
return parseRegister(Operands, RegV, SystemZMC::VR128Regs, VR128Reg);
}
+ OperandMatchResultTy parseAR32(OperandVector &Operands) {
+ return parseRegister(Operands, RegAR, SystemZMC::AR32Regs, AR32Reg);
+ }
OperandMatchResultTy parseAnyReg(OperandVector &Operands) {
return parseAnyRegister(Operands);
}
@@ -498,7 +484,6 @@ public:
OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg);
}
- OperandMatchResultTy parseAccessReg(OperandVector &Operands);
OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
}
@@ -631,7 +616,7 @@ bool SystemZAsmParser::parseRegister(Register &Reg) {
else if (Prefix == 'v' && Reg.Num < 32)
Reg.Group = RegV;
else if (Prefix == 'a' && Reg.Num < 16)
- Reg.Group = RegAccess;
+ Reg.Group = RegAR;
else
return Error(Reg.StartLoc, "invalid register");
@@ -721,6 +706,10 @@ SystemZAsmParser::parseAnyRegister(OperandVector &Operands) {
Kind = VR128Reg;
RegNo = SystemZMC::VR128Regs[Reg.Num];
}
+ else if (Reg.Group == RegAR) {
+ Kind = AR32Reg;
+ RegNo = SystemZMC::AR32Regs[Reg.Num];
+ }
else {
return MatchOperand_ParseFail;
}
@@ -1034,9 +1023,8 @@ bool SystemZAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
RegNo = SystemZMC::FP64Regs[Reg.Num];
else if (Reg.Group == RegV)
RegNo = SystemZMC::VR128Regs[Reg.Num];
- else
- // FIXME: Access registers aren't modelled as LLVM registers yet.
- return Error(Reg.StartLoc, "invalid operand for instruction");
+ else if (Reg.Group == RegAR)
+ RegNo = SystemZMC::AR32Regs[Reg.Num];
StartLoc = Reg.StartLoc;
EndLoc = Reg.EndLoc;
return false;
@@ -1184,21 +1172,6 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
}
OperandMatchResultTy
-SystemZAsmParser::parseAccessReg(OperandVector &Operands) {
- if (Parser.getTok().isNot(AsmToken::Percent))
- return MatchOperand_NoMatch;
-
- Register Reg;
- if (parseRegister(Reg, RegAccess, nullptr))
- return MatchOperand_ParseFail;
-
- Operands.push_back(SystemZOperand::createAccessReg(Reg.Num,
- Reg.StartLoc,
- Reg.EndLoc));
- return MatchOperand_Success;
-}
-
-OperandMatchResultTy
SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
int64_t MaxVal, bool AllowTLS) {
MCContext &Ctx = getContext();
diff --git a/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp b/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp
index 71b81cd26d75..a1b8422e9e83 100644
--- a/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp
+++ b/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp
@@ -150,6 +150,12 @@ static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
}
+static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
+}
+
template<unsigned N>
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
if (!isUInt<N>(Imm))
@@ -166,12 +172,6 @@ static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
return MCDisassembler::Success;
}
-static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
- uint64_t Address,
- const void *Decoder) {
- return decodeUImmOperand<4>(Inst, Imm);
-}
-
static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
uint64_t Address, const void *Decoder) {
return decodeUImmOperand<1>(Inst, Imm);
diff --git a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp
index 60ea7472159e..1207c7b327e8 100644
--- a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp
+++ b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp
@@ -139,13 +139,6 @@ void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,
printUImmOperand<48>(MI, OpNum, O);
}
-void SystemZInstPrinter::printAccessRegOperand(const MCInst *MI, int OpNum,
- raw_ostream &O) {
- uint64_t Value = MI->getOperand(OpNum).getImm();
- assert(Value < 16 && "Invalid access register number");
- O << "%a" << (unsigned int)Value;
-}
-
void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
const MCOperand &MO = MI->getOperand(OpNum);
diff --git a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h
index 6c699093a081..6336f5ee0efa 100644
--- a/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h
+++ b/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h
@@ -65,7 +65,6 @@ private:
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);
// Print the mnemonic for a condition-code mask ("ne", "lh", etc.)
// This forms part of the instruction name rather than the operand list.
diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp b/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
index 063be46add25..dfea7e33fa15 100644
--- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
+++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.cpp
@@ -109,6 +109,13 @@ const unsigned SystemZMC::VR128Regs[32] = {
SystemZ::V28, SystemZ::V29, SystemZ::V30, SystemZ::V31
};
+const unsigned SystemZMC::AR32Regs[16] = {
+ SystemZ::A0, SystemZ::A1, SystemZ::A2, SystemZ::A3,
+ SystemZ::A4, SystemZ::A5, SystemZ::A6, SystemZ::A7,
+ SystemZ::A8, SystemZ::A9, SystemZ::A10, SystemZ::A11,
+ SystemZ::A12, SystemZ::A13, SystemZ::A14, SystemZ::A15
+};
+
unsigned SystemZMC::getFirstReg(unsigned Reg) {
static unsigned Map[SystemZ::NUM_TARGET_REGS];
static bool Initialized = false;
@@ -119,6 +126,7 @@ unsigned SystemZMC::getFirstReg(unsigned Reg) {
Map[GR64Regs[I]] = I;
Map[GR128Regs[I]] = I;
Map[FP128Regs[I]] = I;
+ Map[AR32Regs[I]] = I;
}
for (unsigned I = 0; I < 32; ++I) {
Map[VR32Regs[I]] = I;
diff --git a/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h b/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h
index 498f5199cfb8..d9926c7e4986 100644
--- a/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h
+++ b/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h
@@ -54,6 +54,7 @@ extern const unsigned FP128Regs[16];
extern const unsigned VR32Regs[32];
extern const unsigned VR64Regs[32];
extern const unsigned VR128Regs[32];
+extern const unsigned AR32Regs[16];
// Return the 0-based number of the first architectural register that
// contains the given LLVM register. E.g. R1D -> 1.
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp
index 3108a5b2564b..2ddee39754c0 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -2564,16 +2564,15 @@ SDValue SystemZTargetLowering::lowerTLSGetOffset(GlobalAddressSDNode *Node,
SDValue SystemZTargetLowering::lowerThreadPointer(const SDLoc &DL,
SelectionDAG &DAG) const {
+ SDValue Chain = DAG.getEntryNode();
EVT PtrVT = getPointerTy(DAG.getDataLayout());
// The high part of the thread pointer is in access register 0.
- SDValue TPHi = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32,
- DAG.getConstant(0, DL, MVT::i32));
+ SDValue TPHi = DAG.getCopyFromReg(Chain, DL, SystemZ::A0, MVT::i32);
TPHi = DAG.getNode(ISD::ANY_EXTEND, DL, PtrVT, TPHi);
// The low part of the thread pointer is in access register 1.
- SDValue TPLo = DAG.getNode(SystemZISD::EXTRACT_ACCESS, DL, MVT::i32,
- DAG.getConstant(1, DL, MVT::i32));
+ SDValue TPLo = DAG.getCopyFromReg(Chain, DL, SystemZ::A1, MVT::i32);
TPLo = DAG.getNode(ISD::ZERO_EXTEND, DL, PtrVT, TPLo);
// Merge them into a single 64-bit address.
@@ -4612,7 +4611,6 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
OPCODE(BR_CCMASK);
OPCODE(SELECT_CCMASK);
OPCODE(ADJDYNALLOC);
- OPCODE(EXTRACT_ACCESS);
OPCODE(POPCNT);
OPCODE(UMUL_LOHI64);
OPCODE(SDIVREM32);
diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h
index 735f4b512899..84c259757832 100644
--- a/lib/Target/SystemZ/SystemZISelLowering.h
+++ b/lib/Target/SystemZ/SystemZISelLowering.h
@@ -83,10 +83,6 @@ enum NodeType : unsigned {
// base of the dynamically-allocatable area.
ADJDYNALLOC,
- // Extracts the value of a 32-bit access register. Operand 0 is
- // the number of the register.
- EXTRACT_ACCESS,
-
// Count number of bits set in operand 0 per byte.
POPCNT,
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp
index ba7059aae1e4..d781ec742e09 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -172,7 +172,7 @@ void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const {
MachineInstr *Ear1MI = MF.CloneMachineInstr(MI);
MBB->insert(MI, Ear1MI);
Ear1MI->setDesc(get(SystemZ::EAR));
- MachineInstrBuilder(MF, Ear1MI).addImm(0);
+ MachineInstrBuilder(MF, Ear1MI).addReg(SystemZ::A0);
// sllg <reg>, <reg>, 32
MachineInstr *SllgMI = MF.CloneMachineInstr(MI);
@@ -184,7 +184,7 @@ void SystemZInstrInfo::expandLoadStackGuard(MachineInstr *MI) const {
MachineInstr *Ear2MI = MF.CloneMachineInstr(MI);
MBB->insert(MI, Ear2MI);
Ear2MI->setDesc(get(SystemZ::EAR));
- MachineInstrBuilder(MF, Ear2MI).addImm(1);
+ MachineInstrBuilder(MF, Ear2MI).addReg(SystemZ::A1);
// lg <reg>, 40(<reg>)
MI->setDesc(get(SystemZ::LG));
@@ -695,6 +695,14 @@ void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Opcode = SystemZ::VLR64;
else if (SystemZ::VR128BitRegClass.contains(DestReg, SrcReg))
Opcode = SystemZ::VLR;
+ else if (SystemZ::AR32BitRegClass.contains(DestReg, SrcReg))
+ Opcode = SystemZ::CPYA;
+ else if (SystemZ::AR32BitRegClass.contains(DestReg) &&
+ SystemZ::GR32BitRegClass.contains(SrcReg))
+ Opcode = SystemZ::SAR;
+ else if (SystemZ::GR32BitRegClass.contains(DestReg) &&
+ SystemZ::AR32BitRegClass.contains(SrcReg))
+ Opcode = SystemZ::EAR;
else
llvm_unreachable("Impossible reg-to-reg copy");
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td
index 15b6b71087ad..42b5eb89a2f7 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.td
+++ b/lib/Target/SystemZ/SystemZInstrInfo.td
@@ -1438,6 +1438,30 @@ let Defs = [CC] in {
}
//===----------------------------------------------------------------------===//
+// Access registers
+//===----------------------------------------------------------------------===//
+
+// Read a 32-bit access register into a GR32. As with all GR32 operations,
+// the upper 32 bits of the enclosing GR64 remain unchanged, which is useful
+// when a 64-bit address is stored in a pair of access registers.
+def EAR : UnaryRRE<"ear", 0xB24F, null_frag, GR32, AR32>;
+
+// Set access register.
+def SAR : UnaryRRE<"sar", 0xB24E, null_frag, AR32, GR32>;
+
+// Copy access register.
+def CPYA : UnaryRRE<"cpya", 0xB24D, null_frag, AR32, AR32>;
+
+// Load address extended.
+defm LAE : LoadAddressRXPair<"lae", 0x51, 0xE375, null_frag>;
+
+// Load access multiple.
+defm LAM : LoadMultipleRSPair<"lam", 0x9A, 0xEB9A, AR32>;
+
+// Load access multiple.
+defm STAM : StoreMultipleRSPair<"stam", 0x9B, 0xEB9B, AR32>;
+
+//===----------------------------------------------------------------------===//
// Transactional execution
//===----------------------------------------------------------------------===//
@@ -1487,13 +1511,6 @@ let Predicates = [FeatureProcessorAssist] in {
let Uses = [CC] in
def IPM : InherentRRE<"ipm", 0xB222, GR32, z_ipm>;
-// Read a 32-bit access register into a GR32. As with all GR32 operations,
-// the upper 32 bits of the enclosing GR64 remain unchanged, which is useful
-// when a 64-bit address is stored in a pair of access registers.
-def EAR : InstRRE<0xB24F, (outs GR32:$R1), (ins access_reg:$R2),
- "ear\t$R1, $R2",
- [(set GR32:$R1, (z_extract_access access_reg:$R2))]>;
-
// Find leftmost one, AKA count leading zeros. The instruction actually
// returns a pair of GR64s, the first giving the number of leading zeros
// and the second giving a copy of the source with the leftmost one bit
diff --git a/lib/Target/SystemZ/SystemZOperands.td b/lib/Target/SystemZ/SystemZOperands.td
index 442fbd6065a9..3b747496a1b1 100644
--- a/lib/Target/SystemZ/SystemZOperands.td
+++ b/lib/Target/SystemZ/SystemZOperands.td
@@ -570,17 +570,6 @@ def bdvaddr12only : BDVMode< "64", "12">;
// Miscellaneous
//===----------------------------------------------------------------------===//
-// Access registers. At present we just use them for accessing the thread
-// pointer, so we don't expose them as register to LLVM.
-def AccessReg : AsmOperandClass {
- let Name = "AccessReg";
- let ParserMethod = "parseAccessReg";
-}
-def access_reg : Immediate<i32, [{ return N->getZExtValue() < 16; }],
- NOOP_SDNodeXForm, "AccessReg"> {
- let ParserMatchClass = AccessReg;
-}
-
// A 4-bit condition-code mask.
def cond4 : PatLeaf<(i32 imm), [{ return (N->getZExtValue() < 16); }]>,
Operand<i32> {
diff --git a/lib/Target/SystemZ/SystemZOperators.td b/lib/Target/SystemZ/SystemZOperators.td
index 948c64a704b4..843ad34e7d49 100644
--- a/lib/Target/SystemZ/SystemZOperators.td
+++ b/lib/Target/SystemZ/SystemZOperators.td
@@ -35,9 +35,6 @@ def SDT_ZWrapOffset : SDTypeProfile<1, 2,
SDTCisSameAs<0, 2>,
SDTCisPtrTy<0>]>;
def SDT_ZAdjDynAlloc : SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>;
-def SDT_ZExtractAccess : SDTypeProfile<1, 1,
- [SDTCisVT<0, i32>,
- SDTCisVT<1, i32>]>;
def SDT_ZGR128Binary32 : SDTypeProfile<1, 2,
[SDTCisVT<0, untyped>,
SDTCisVT<1, untyped>,
@@ -186,8 +183,6 @@ def z_br_ccmask : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask,
def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask,
[SDNPInGlue]>;
def z_adjdynalloc : SDNode<"SystemZISD::ADJDYNALLOC", SDT_ZAdjDynAlloc>;
-def z_extract_access : SDNode<"SystemZISD::EXTRACT_ACCESS",
- SDT_ZExtractAccess>;
def z_popcnt : SDNode<"SystemZISD::POPCNT", SDTIntUnaryOp>;
def z_umul_lohi64 : SDNode<"SystemZISD::UMUL_LOHI64", SDT_ZGR128Binary64>;
def z_sdivrem32 : SDNode<"SystemZISD::SDIVREM32", SDT_ZGR128Binary32>;
diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index b5e5fd4bfc4f..6ef8000d6f43 100644
--- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -59,6 +59,11 @@ SystemZRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(SystemZ::R15L);
Reserved.set(SystemZ::R15H);
Reserved.set(SystemZ::R14Q);
+
+ // A0 and A1 hold the thread pointer.
+ Reserved.set(SystemZ::A0);
+ Reserved.set(SystemZ::A1);
+
return Reserved;
}
diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.td b/lib/Target/SystemZ/SystemZRegisterInfo.td
index 5f0197f8e051..47d2f75cc11a 100644
--- a/lib/Target/SystemZ/SystemZRegisterInfo.td
+++ b/lib/Target/SystemZ/SystemZRegisterInfo.td
@@ -36,15 +36,16 @@ def subreg_hr32 : ComposedSubRegIndex<subreg_h64, subreg_r32>;
// associated operand called NAME. SIZE is the size and alignment
// of the registers and REGLIST is the list of individual registers.
multiclass SystemZRegClass<string name, list<ValueType> types, int size,
- dag regList> {
+ dag regList, bit allocatable = 1> {
def AsmOperand : AsmOperandClass {
let Name = name;
let ParserMethod = "parse"##name;
let RenderMethod = "addRegOperands";
}
- def Bit : RegisterClass<"SystemZ", types, size, regList> {
- let Size = size;
- }
+ let isAllocatable = allocatable in
+ def Bit : RegisterClass<"SystemZ", types, size, regList> {
+ let Size = size;
+ }
def "" : RegisterOperand<!cast<RegisterClass>(name##"Bit")> {
let ParserMatchClass = !cast<AsmOperandClass>(name##"AsmOperand");
}
@@ -292,3 +293,14 @@ def v128any : TypedReg<untyped, VR128>;
def CC : SystemZReg<"cc">;
let isAllocatable = 0 in
def CCRegs : RegisterClass<"SystemZ", [i32], 32, (add CC)>;
+
+// Access registers.
+class ACR32<bits<16> num, string n> : SystemZReg<n> {
+ let HWEncoding = num;
+}
+foreach I = 0-15 in {
+ def A#I : ACR32<I, "a"#I>, DwarfRegNum<[!add(I, 48)]>;
+}
+defm AR32 : SystemZRegClass<"AR32", [i32], 32,
+ (add (sequence "A%u", 0, 15)), 0>;
+
diff --git a/lib/Target/SystemZ/SystemZScheduleZ13.td b/lib/Target/SystemZ/SystemZScheduleZ13.td
index f010f6d0d586..6857af54e2fd 100644
--- a/lib/Target/SystemZ/SystemZScheduleZ13.td
+++ b/lib/Target/SystemZ/SystemZScheduleZ13.td
@@ -520,6 +520,19 @@ def : InstRW<[FXb, LSU, Lat5], (instregex "LAX(G)?$")>;
def : InstRW<[FXa, FXb, LSU, Lat6, GroupAlone], (instregex "CS(G|Y)?$")>;
//===----------------------------------------------------------------------===//
+// Access registers
+//===----------------------------------------------------------------------===//
+
+// Extract/set/copy access register
+def : InstRW<[LSU], (instregex "(EAR|SAR|CPYA)$")>;
+
+// Load address extended
+def : InstRW<[LSU, FXa], (instregex "LAE(Y)?$")>;
+
+// Load/store access multiple (not modeled precisely)
+def : InstRW<[LSU, Lat30, GroupAlone], (instregex "(L|ST)AM(Y)?$")>;
+
+//===----------------------------------------------------------------------===//
// Transactional execution
//===----------------------------------------------------------------------===//
@@ -552,9 +565,6 @@ def : InstRW<[FXb], (instregex "PPA$")>;
// Insert Program Mask
def : InstRW<[FXa, Lat3, EndGroup], (instregex "IPM$")>;
-// Extract access register
-def : InstRW<[LSU], (instregex "EAR$")>;
-
// Find leftmost one
def : InstRW<[FXa, Lat6, GroupAlone], (instregex "FLOGR$")>;
diff --git a/lib/Target/SystemZ/SystemZScheduleZ196.td b/lib/Target/SystemZ/SystemZScheduleZ196.td
index f4c0e6cb71f6..d964865c36c8 100644
--- a/lib/Target/SystemZ/SystemZScheduleZ196.td
+++ b/lib/Target/SystemZ/SystemZScheduleZ196.td
@@ -497,15 +497,25 @@ def : InstRW<[FXU, LSU, Lat5], (instregex "LAX(G)?$")>;
def : InstRW<[FXU, LSU, FXU, Lat6, GroupAlone], (instregex "CS(G|Y)?$")>;
//===----------------------------------------------------------------------===//
+// Access registers
+//===----------------------------------------------------------------------===//
+
+// Extract/set/copy access register
+def : InstRW<[LSU], (instregex "(EAR|SAR|CPYA)$")>;
+
+// Load address extended
+def : InstRW<[LSU, FXU], (instregex "LAE(Y)?$")>;
+
+// Load/store access multiple (not modeled precisely)
+def : InstRW<[LSU, Lat30, GroupAlone], (instregex "(L|ST)AM(Y)?$")>;
+
+//===----------------------------------------------------------------------===//
// Miscellaneous Instructions.
//===----------------------------------------------------------------------===//
// Insert Program Mask
def : InstRW<[FXU, Lat3, EndGroup], (instregex "IPM$")>;
-// Extract access register
-def : InstRW<[LSU], (instregex "EAR$")>;
-
// Find leftmost one
def : InstRW<[FXU, Lat7, GroupAlone], (instregex "FLOGR$")>;
diff --git a/lib/Target/SystemZ/SystemZScheduleZEC12.td b/lib/Target/SystemZ/SystemZScheduleZEC12.td
index 4f406be34f6c..0f005f4e7206 100644
--- a/lib/Target/SystemZ/SystemZScheduleZEC12.td
+++ b/lib/Target/SystemZ/SystemZScheduleZEC12.td
@@ -499,6 +499,19 @@ def : InstRW<[FXU, LSU, Lat5], (instregex "LAX(G)?$")>;
def : InstRW<[FXU, FXU, LSU, Lat6, GroupAlone], (instregex "CS(G|Y)?$")>;
//===----------------------------------------------------------------------===//
+// Access registers
+//===----------------------------------------------------------------------===//
+
+// Extract/set/copy access register
+def : InstRW<[LSU], (instregex "(EAR|SAR|CPYA)$")>;
+
+// Load address extended
+def : InstRW<[LSU, FXU], (instregex "LAE(Y)?$")>;
+
+// Load/store access multiple (not modeled precisely)
+def : InstRW<[LSU, Lat30, GroupAlone], (instregex "(L|ST)AM(Y)?$")>;
+
+//===----------------------------------------------------------------------===//
// Transactional execution
//===----------------------------------------------------------------------===//
@@ -531,9 +544,6 @@ def : InstRW<[FXU], (instregex "PPA$")>;
// Insert Program Mask
def : InstRW<[FXU, Lat3, EndGroup], (instregex "IPM$")>;
-// Extract access register
-def : InstRW<[LSU], (instregex "EAR$")>;
-
// Find leftmost one
def : InstRW<[FXU, Lat7, GroupAlone], (instregex "FLOGR$")>;
diff --git a/test/MC/Disassembler/SystemZ/insns.txt b/test/MC/Disassembler/SystemZ/insns.txt
index 9a1cfe69dec1..546e2f45687a 100644
--- a/test/MC/Disassembler/SystemZ/insns.txt
+++ b/test/MC/Disassembler/SystemZ/insns.txt
@@ -2719,6 +2719,21 @@
# CHECK: cpsdr %f15, %f15, %f15
0xb3 0x72 0xf0 0xff
+# CHECK: cpya %a0, %a0
+0xb2 0x4d 0x00 0x00
+
+# CHECK: cpya %a0, %a15
+0xb2 0x4d 0x00 0x0f
+
+# CHECK: cpya %a15, %a0
+0xb2 0x4d 0x00 0xf0
+
+# CHECK: cpya %a7, %a8
+0xb2 0x4d 0x00 0x78
+
+# CHECK: cpya %a15, %a15
+0xb2 0x4d 0x00 0xff
+
# CHECK: cr %r0, %r0
0x19 0x00
@@ -3817,6 +3832,126 @@
# CHECK: laalg %r15, %r0, 0
0xeb 0xf0 0x00 0x00 0x00 0xea
+# CHECK: lae %r0, 0
+0x51 0x00 0x00 0x00
+
+# CHECK: lae %r0, 4095
+0x51 0x00 0x0f 0xff
+
+# CHECK: lae %r0, 0(%r1)
+0x51 0x00 0x10 0x00
+
+# CHECK: lae %r0, 0(%r15)
+0x51 0x00 0xf0 0x00
+
+# CHECK: lae %r0, 4095(%r1,%r15)
+0x51 0x01 0xff 0xff
+
+# CHECK: lae %r0, 4095(%r15,%r1)
+0x51 0x0f 0x1f 0xff
+
+# CHECK: lae %r15, 0
+0x51 0xf0 0x00 0x00
+
+# CHECK: laey %r0, -524288
+0xe3 0x00 0x00 0x00 0x80 0x75
+
+# CHECK: laey %r0, -1
+0xe3 0x00 0x0f 0xff 0xff 0x75
+
+# CHECK: laey %r0, 0
+0xe3 0x00 0x00 0x00 0x00 0x75
+
+# CHECK: laey %r0, 1
+0xe3 0x00 0x00 0x01 0x00 0x75
+
+# CHECK: laey %r0, 524287
+0xe3 0x00 0x0f 0xff 0x7f 0x75
+
+# CHECK: laey %r0, 0(%r1)
+0xe3 0x00 0x10 0x00 0x00 0x75
+
+# CHECK: laey %r0, 0(%r15)
+0xe3 0x00 0xf0 0x00 0x00 0x75
+
+# CHECK: laey %r0, 524287(%r1,%r15)
+0xe3 0x01 0xff 0xff 0x7f 0x75
+
+# CHECK: laey %r0, 524287(%r15,%r1)
+0xe3 0x0f 0x1f 0xff 0x7f 0x75
+
+# CHECK: laey %r15, 0
+0xe3 0xf0 0x00 0x00 0x00 0x75
+
+# CHECK: lam %a0, %a0, 0
+0x9a 0x00 0x00 0x00
+
+# CHECK: lam %a0, %a15, 0
+0x9a 0x0f 0x00 0x00
+
+# CHECK: lam %a14, %a15, 0
+0x9a 0xef 0x00 0x00
+
+# CHECK: lam %a15, %a15, 0
+0x9a 0xff 0x00 0x00
+
+# CHECK: lam %a0, %a0, 4095
+0x9a 0x00 0x0f 0xff
+
+# CHECK: lam %a0, %a0, 1
+0x9a 0x00 0x00 0x01
+
+# CHECK: lam %a0, %a0, 0(%r1)
+0x9a 0x00 0x10 0x00
+
+# CHECK: lam %a0, %a0, 0(%r15)
+0x9a 0x00 0xf0 0x00
+
+# CHECK: lam %a0, %a0, 4095(%r1)
+0x9a 0x00 0x1f 0xff
+
+# CHECK: lam %a0, %a0, 4095(%r15)
+0x9a 0x00 0xff 0xff
+
+# CHECK: lamy %a0, %a0, 0
+0xeb 0x00 0x00 0x00 0x00 0x9a
+
+# CHECK: lamy %a0, %a15, 0
+0xeb 0x0f 0x00 0x00 0x00 0x9a
+
+# CHECK: lamy %a14, %a15, 0
+0xeb 0xef 0x00 0x00 0x00 0x9a
+
+# CHECK: lamy %a15, %a15, 0
+0xeb 0xff 0x00 0x00 0x00 0x9a
+
+# CHECK: lamy %a0, %a0, -524288
+0xeb 0x00 0x00 0x00 0x80 0x9a
+
+# CHECK: lamy %a0, %a0, -1
+0xeb 0x00 0x0f 0xff 0xff 0x9a
+
+# CHECK: lamy %a0, %a0, 0
+0xeb 0x00 0x00 0x00 0x00 0x9a
+
+# CHECK: lamy %a0, %a0, 1
+0xeb 0x00 0x00 0x01 0x00 0x9a
+
+# CHECK: lamy %a0, %a0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0x9a
+
+# CHECK: lamy %a0, %a0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0x9a
+
+# CHECK: lamy %a0, %a0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0x9a
+
+# CHECK: lamy %a0, %a0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0x9a
+
+# CHECK: lamy %a0, %a0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0x9a
+
# CHECK: lan %r0, %r0, -524288
0xeb 0x00 0x00 0x00 0x80 0xf4
@@ -7696,6 +7831,21 @@
# CHECK: rll %r0, %r0, 524287(%r15)
0xeb 0x00 0xff 0xff 0x7f 0x1d
+# CHECK: sar %a0, %r0
+0xb2 0x4e 0x00 0x00
+
+# CHECK: sar %a0, %r15
+0xb2 0x4e 0x00 0x0f
+
+# CHECK: sar %a15, %r0
+0xb2 0x4e 0x00 0xf0
+
+# CHECK: sar %a7, %r8
+0xb2 0x4e 0x00 0x78
+
+# CHECK: sar %a15, %r15
+0xb2 0x4e 0x00 0xff
+
# CHECK: sdbr %f0, %f0
0xb3 0x1b 0x00 0x00
@@ -8620,6 +8770,75 @@
# CHECK: srst %r7, %r8
0xb2 0x5e 0x00 0x78
+# CHECK: stam %a0, %a0, 0
+0x9b 0x00 0x00 0x00
+
+# CHECK: stam %a0, %a15, 0
+0x9b 0x0f 0x00 0x00
+
+# CHECK: stam %a14, %a15, 0
+0x9b 0xef 0x00 0x00
+
+# CHECK: stam %a15, %a15, 0
+0x9b 0xff 0x00 0x00
+
+# CHECK: stam %a0, %a0, 4095
+0x9b 0x00 0x0f 0xff
+
+# CHECK: stam %a0, %a0, 1
+0x9b 0x00 0x00 0x01
+
+# CHECK: stam %a0, %a0, 0(%r1)
+0x9b 0x00 0x10 0x00
+
+# CHECK: stam %a0, %a0, 0(%r15)
+0x9b 0x00 0xf0 0x00
+
+# CHECK: stam %a0, %a0, 4095(%r1)
+0x9b 0x00 0x1f 0xff
+
+# CHECK: stam %a0, %a0, 4095(%r15)
+0x9b 0x00 0xff 0xff
+
+# CHECK: stamy %a0, %a0, 0
+0xeb 0x00 0x00 0x00 0x00 0x9b
+
+# CHECK: stamy %a0, %a15, 0
+0xeb 0x0f 0x00 0x00 0x00 0x9b
+
+# CHECK: stamy %a14, %a15, 0
+0xeb 0xef 0x00 0x00 0x00 0x9b
+
+# CHECK: stamy %a15, %a15, 0
+0xeb 0xff 0x00 0x00 0x00 0x9b
+
+# CHECK: stamy %a0, %a0, -524288
+0xeb 0x00 0x00 0x00 0x80 0x9b
+
+# CHECK: stamy %a0, %a0, -1
+0xeb 0x00 0x0f 0xff 0xff 0x9b
+
+# CHECK: stamy %a0, %a0, 0
+0xeb 0x00 0x00 0x00 0x00 0x9b
+
+# CHECK: stamy %a0, %a0, 1
+0xeb 0x00 0x00 0x01 0x00 0x9b
+
+# CHECK: stamy %a0, %a0, 524287
+0xeb 0x00 0x0f 0xff 0x7f 0x9b
+
+# CHECK: stamy %a0, %a0, 0(%r1)
+0xeb 0x00 0x10 0x00 0x00 0x9b
+
+# CHECK: stamy %a0, %a0, 0(%r15)
+0xeb 0x00 0xf0 0x00 0x00 0x9b
+
+# CHECK: stamy %a0, %a0, 524287(%r1)
+0xeb 0x00 0x1f 0xff 0x7f 0x9b
+
+# CHECK: stamy %a0, %a0, 524287(%r15)
+0xeb 0x00 0xff 0xff 0x7f 0x9b
+
# CHECK: stc %r0, 0
0x42 0x00 0x00 0x00
diff --git a/test/MC/SystemZ/insn-bad.s b/test/MC/SystemZ/insn-bad.s
index 7e76f43253d1..81f6cfed0070 100644
--- a/test/MC/SystemZ/insn-bad.s
+++ b/test/MC/SystemZ/insn-bad.s
@@ -1660,6 +1660,14 @@
la %r0, -1
la %r0, 4096
+#CHECK: error: invalid operand
+#CHECK: lae %r0, -1
+#CHECK: error: invalid operand
+#CHECK: lae %r0, 4096
+
+ lae %r0, -1
+ lae %r0, 4096
+
#CHECK: error: instruction requires: interlocked-access1
#CHECK: laa %r1, %r2, 100(%r3)
laa %r1, %r2, 100(%r3)
@@ -1676,6 +1684,33 @@
#CHECK: laalg %r1, %r2, 100(%r3)
laalg %r1, %r2, 100(%r3)
+#CHECK: error: invalid operand
+#CHECK: laey %r0, -524289
+#CHECK: error: invalid operand
+#CHECK: laey %r0, 524288
+
+ laey %r0, -524289
+ laey %r0, 524288
+
+#CHECK: error: invalid operand
+#CHECK: lam %a0, %a0, 4096
+#CHECK: error: invalid use of indexed addressing
+#CHECK: lam %a0, %a0, 0(%r1,%r2)
+
+ lam %a0, %a0, 4096
+ lam %a0, %a0, 0(%r1,%r2)
+
+#CHECK: error: invalid operand
+#CHECK: lamy %a0, %a0, -524289
+#CHECK: error: invalid operand
+#CHECK: lamy %a0, %a0, 524288
+#CHECK: error: invalid use of indexed addressing
+#CHECK: lamy %a0, %a0, 0(%r1,%r2)
+
+ lamy %a0, %a0, -524289
+ lamy %a0, %a0, 524288
+ lamy %a0, %a0, 0(%r1,%r2)
+
#CHECK: error: instruction requires: interlocked-access1
#CHECK: lan %r1, %r2, 100(%r3)
lan %r1, %r2, 100(%r3)
@@ -3350,6 +3385,25 @@
st %r0, 4096
#CHECK: error: invalid operand
+#CHECK: stam %a0, %a0, 4096
+#CHECK: error: invalid use of indexed addressing
+#CHECK: stam %a0, %a0, 0(%r1,%r2)
+
+ stam %a0, %a0, 4096
+ stam %a0, %a0, 0(%r1,%r2)
+
+#CHECK: error: invalid operand
+#CHECK: stamy %a0, %a0, -524289
+#CHECK: error: invalid operand
+#CHECK: stamy %a0, %a0, 524288
+#CHECK: error: invalid use of indexed addressing
+#CHECK: stamy %a0, %a0, 0(%r1,%r2)
+
+ stamy %a0, %a0, -524289
+ stamy %a0, %a0, 524288
+ stamy %a0, %a0, 0(%r1,%r2)
+
+#CHECK: error: invalid operand
#CHECK: stc %r0, -1
#CHECK: error: invalid operand
#CHECK: stc %r0, 4096
diff --git a/test/MC/SystemZ/insn-good.s b/test/MC/SystemZ/insn-good.s
index a550f30ef9e2..da2decb07e42 100644
--- a/test/MC/SystemZ/insn-good.s
+++ b/test/MC/SystemZ/insn-good.s
@@ -4840,6 +4840,17 @@
cpsdr %f1, %f2, %f3
cpsdr %f15, %f15, %f15
+#CHECK: cpya %a0, %a0 # encoding: [0xb2,0x4d,0x00,0x00]
+#CHECK: cpya %a0, %a15 # encoding: [0xb2,0x4d,0x00,0x0f]
+#CHECK: cpya %a15, %a0 # encoding: [0xb2,0x4d,0x00,0xf0]
+#CHECK: cpya %a7, %a8 # encoding: [0xb2,0x4d,0x00,0x78]
+#CHECK: cpya %a15, %a15 # encoding: [0xb2,0x4d,0x00,0xff]
+
+ cpya %a0, %a0
+ cpya %a0, %a15
+ cpya %a15, %a0
+ cpya %a7, %a8
+ cpya %a15, %a15
#CHECK: cr %r0, %r0 # encoding: [0x19,0x00]
#CHECK: cr %r0, %r15 # encoding: [0x19,0x0f]
@@ -5847,6 +5858,94 @@
la %r0, 4095(%r15,%r1)
la %r15, 0
+#CHECK: lae %r0, 0 # encoding: [0x51,0x00,0x00,0x00]
+#CHECK: lae %r0, 4095 # encoding: [0x51,0x00,0x0f,0xff]
+#CHECK: lae %r0, 0(%r1) # encoding: [0x51,0x00,0x10,0x00]
+#CHECK: lae %r0, 0(%r15) # encoding: [0x51,0x00,0xf0,0x00]
+#CHECK: lae %r0, 4095(%r1,%r15) # encoding: [0x51,0x01,0xff,0xff]
+#CHECK: lae %r0, 4095(%r15,%r1) # encoding: [0x51,0x0f,0x1f,0xff]
+#CHECK: lae %r15, 0 # encoding: [0x51,0xf0,0x00,0x00]
+
+ lae %r0, 0
+ lae %r0, 4095
+ lae %r0, 0(%r1)
+ lae %r0, 0(%r15)
+ lae %r0, 4095(%r1,%r15)
+ lae %r0, 4095(%r15,%r1)
+ lae %r15, 0
+
+#CHECK: laey %r0, -524288 # encoding: [0xe3,0x00,0x00,0x00,0x80,0x75]
+#CHECK: laey %r0, -1 # encoding: [0xe3,0x00,0x0f,0xff,0xff,0x75]
+#CHECK: laey %r0, 0 # encoding: [0xe3,0x00,0x00,0x00,0x00,0x75]
+#CHECK: laey %r0, 1 # encoding: [0xe3,0x00,0x00,0x01,0x00,0x75]
+#CHECK: laey %r0, 524287 # encoding: [0xe3,0x00,0x0f,0xff,0x7f,0x75]
+#CHECK: laey %r0, 0(%r1) # encoding: [0xe3,0x00,0x10,0x00,0x00,0x75]
+#CHECK: laey %r0, 0(%r15) # encoding: [0xe3,0x00,0xf0,0x00,0x00,0x75]
+#CHECK: laey %r0, 524287(%r1,%r15) # encoding: [0xe3,0x01,0xff,0xff,0x7f,0x75]
+#CHECK: laey %r0, 524287(%r15,%r1) # encoding: [0xe3,0x0f,0x1f,0xff,0x7f,0x75]
+#CHECK: laey %r15, 0 # encoding: [0xe3,0xf0,0x00,0x00,0x00,0x75]
+
+ laey %r0, -524288
+ laey %r0, -1
+ laey %r0, 0
+ laey %r0, 1
+ laey %r0, 524287
+ laey %r0, 0(%r1)
+ laey %r0, 0(%r15)
+ laey %r0, 524287(%r1,%r15)
+ laey %r0, 524287(%r15,%r1)
+ laey %r15, 0
+
+#CHECK: lam %a0, %a0, 0 # encoding: [0x9a,0x00,0x00,0x00]
+#CHECK: lam %a0, %a15, 0 # encoding: [0x9a,0x0f,0x00,0x00]
+#CHECK: lam %a14, %a15, 0 # encoding: [0x9a,0xef,0x00,0x00]
+#CHECK: lam %a15, %a15, 0 # encoding: [0x9a,0xff,0x00,0x00]
+#CHECK: lam %a0, %a0, 4095 # encoding: [0x9a,0x00,0x0f,0xff]
+#CHECK: lam %a0, %a0, 1 # encoding: [0x9a,0x00,0x00,0x01]
+#CHECK: lam %a0, %a0, 0(%r1) # encoding: [0x9a,0x00,0x10,0x00]
+#CHECK: lam %a0, %a0, 0(%r15) # encoding: [0x9a,0x00,0xf0,0x00]
+#CHECK: lam %a0, %a0, 4095(%r1) # encoding: [0x9a,0x00,0x1f,0xff]
+#CHECK: lam %a0, %a0, 4095(%r15) # encoding: [0x9a,0x00,0xff,0xff]
+
+ lam %a0,%a0,0
+ lam %a0,%a15,0
+ lam %a14,%a15,0
+ lam %a15,%a15,0
+ lam %a0,%a0,4095
+ lam %a0,%a0,1
+ lam %a0,%a0,0(%r1)
+ lam %a0,%a0,0(%r15)
+ lam %a0,%a0,4095(%r1)
+ lam %a0,%a0,4095(%r15)
+
+#CHECK: lamy %a0, %a0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0x9a]
+#CHECK: lamy %a0, %a15, 0 # encoding: [0xeb,0x0f,0x00,0x00,0x00,0x9a]
+#CHECK: lamy %a14, %a15, 0 # encoding: [0xeb,0xef,0x00,0x00,0x00,0x9a]
+#CHECK: lamy %a15, %a15, 0 # encoding: [0xeb,0xff,0x00,0x00,0x00,0x9a]
+#CHECK: lamy %a0, %a0, -524288 # encoding: [0xeb,0x00,0x00,0x00,0x80,0x9a]
+#CHECK: lamy %a0, %a0, -1 # encoding: [0xeb,0x00,0x0f,0xff,0xff,0x9a]
+#CHECK: lamy %a0, %a0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0x9a]
+#CHECK: lamy %a0, %a0, 1 # encoding: [0xeb,0x00,0x00,0x01,0x00,0x9a]
+#CHECK: lamy %a0, %a0, 524287 # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0x9a]
+#CHECK: lamy %a0, %a0, 0(%r1) # encoding: [0xeb,0x00,0x10,0x00,0x00,0x9a]
+#CHECK: lamy %a0, %a0, 0(%r15) # encoding: [0xeb,0x00,0xf0,0x00,0x00,0x9a]
+#CHECK: lamy %a0, %a0, 524287(%r1) # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0x9a]
+#CHECK: lamy %a0, %a0, 524287(%r15) # encoding: [0xeb,0x00,0xff,0xff,0x7f,0x9a]
+
+ lamy %a0,%a0,0
+ lamy %a0,%a15,0
+ lamy %a14,%a15,0
+ lamy %a15,%a15,0
+ lamy %a0,%a0,-524288
+ lamy %a0,%a0,-1
+ lamy %a0,%a0,0
+ lamy %a0,%a0,1
+ lamy %a0,%a0,524287
+ lamy %a0,%a0,0(%r1)
+ lamy %a0,%a0,0(%r15)
+ lamy %a0,%a0,524287(%r1)
+ lamy %a0,%a0,524287(%r15)
+
#CHECK: larl %r0, .[[LAB:L.*]]-4294967296 # encoding: [0xc0,0x00,A,A,A,A]
#CHECK: fixup A - offset: 2, value: (.[[LAB]]-4294967296)+2, kind: FK_390_PC32DBL
larl %r0, -0x100000000
@@ -8664,6 +8763,18 @@
s %r0, 4095(%r15,%r1)
s %r15, 0
+#CHECK: sar %a0, %r0 # encoding: [0xb2,0x4e,0x00,0x00]
+#CHECK: sar %a0, %r15 # encoding: [0xb2,0x4e,0x00,0x0f]
+#CHECK: sar %a15, %r0 # encoding: [0xb2,0x4e,0x00,0xf0]
+#CHECK: sar %a7, %r8 # encoding: [0xb2,0x4e,0x00,0x78]
+#CHECK: sar %a15, %r15 # encoding: [0xb2,0x4e,0x00,0xff]
+
+ sar %a0, %r0
+ sar %a0, %r15
+ sar %a15, %r0
+ sar %a7, %r8
+ sar %a15, %r15
+
#CHECK: sdb %f0, 0 # encoding: [0xed,0x00,0x00,0x00,0x00,0x1b]
#CHECK: sdb %f0, 4095 # encoding: [0xed,0x00,0x0f,0xff,0x00,0x1b]
#CHECK: sdb %f0, 0(%r1) # encoding: [0xed,0x00,0x10,0x00,0x00,0x1b]
@@ -9258,6 +9369,56 @@
st %r0, 4095(%r15,%r1)
st %r15, 0
+#CHECK: stam %a0, %a0, 0 # encoding: [0x9b,0x00,0x00,0x00]
+#CHECK: stam %a0, %a15, 0 # encoding: [0x9b,0x0f,0x00,0x00]
+#CHECK: stam %a14, %a15, 0 # encoding: [0x9b,0xef,0x00,0x00]
+#CHECK: stam %a15, %a15, 0 # encoding: [0x9b,0xff,0x00,0x00]
+#CHECK: stam %a0, %a0, 4095 # encoding: [0x9b,0x00,0x0f,0xff]
+#CHECK: stam %a0, %a0, 1 # encoding: [0x9b,0x00,0x00,0x01]
+#CHECK: stam %a0, %a0, 0(%r1) # encoding: [0x9b,0x00,0x10,0x00]
+#CHECK: stam %a0, %a0, 0(%r15) # encoding: [0x9b,0x00,0xf0,0x00]
+#CHECK: stam %a0, %a0, 4095(%r1) # encoding: [0x9b,0x00,0x1f,0xff]
+#CHECK: stam %a0, %a0, 4095(%r15) # encoding: [0x9b,0x00,0xff,0xff]
+
+ stam %a0,%a0,0
+ stam %a0,%a15,0
+ stam %a14,%a15,0
+ stam %a15,%a15,0
+ stam %a0,%a0,4095
+ stam %a0,%a0,1
+ stam %a0,%a0,0(%r1)
+ stam %a0,%a0,0(%r15)
+ stam %a0,%a0,4095(%r1)
+ stam %a0,%a0,4095(%r15)
+
+#CHECK: stamy %a0, %a0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0x9b]
+#CHECK: stamy %a0, %a15, 0 # encoding: [0xeb,0x0f,0x00,0x00,0x00,0x9b]
+#CHECK: stamy %a14, %a15, 0 # encoding: [0xeb,0xef,0x00,0x00,0x00,0x9b]
+#CHECK: stamy %a15, %a15, 0 # encoding: [0xeb,0xff,0x00,0x00,0x00,0x9b]
+#CHECK: stamy %a0, %a0, -524288 # encoding: [0xeb,0x00,0x00,0x00,0x80,0x9b]
+#CHECK: stamy %a0, %a0, -1 # encoding: [0xeb,0x00,0x0f,0xff,0xff,0x9b]
+#CHECK: stamy %a0, %a0, 0 # encoding: [0xeb,0x00,0x00,0x00,0x00,0x9b]
+#CHECK: stamy %a0, %a0, 1 # encoding: [0xeb,0x00,0x00,0x01,0x00,0x9b]
+#CHECK: stamy %a0, %a0, 524287 # encoding: [0xeb,0x00,0x0f,0xff,0x7f,0x9b]
+#CHECK: stamy %a0, %a0, 0(%r1) # encoding: [0xeb,0x00,0x10,0x00,0x00,0x9b]
+#CHECK: stamy %a0, %a0, 0(%r15) # encoding: [0xeb,0x00,0xf0,0x00,0x00,0x9b]
+#CHECK: stamy %a0, %a0, 524287(%r1) # encoding: [0xeb,0x00,0x1f,0xff,0x7f,0x9b]
+#CHECK: stamy %a0, %a0, 524287(%r15) # encoding: [0xeb,0x00,0xff,0xff,0x7f,0x9b]
+
+ stamy %a0,%a0,0
+ stamy %a0,%a15,0
+ stamy %a14,%a15,0
+ stamy %a15,%a15,0
+ stamy %a0,%a0,-524288
+ stamy %a0,%a0,-1
+ stamy %a0,%a0,0
+ stamy %a0,%a0,1
+ stamy %a0,%a0,524287
+ stamy %a0,%a0,0(%r1)
+ stamy %a0,%a0,0(%r15)
+ stamy %a0,%a0,524287(%r1)
+ stamy %a0,%a0,524287(%r15)
+
#CHECK: stc %r0, 0 # encoding: [0x42,0x00,0x00,0x00]
#CHECK: stc %r0, 4095 # encoding: [0x42,0x00,0x0f,0xff]
#CHECK: stc %r0, 0(%r1) # encoding: [0x42,0x00,0x10,0x00]
diff --git a/test/MC/SystemZ/regs-bad.s b/test/MC/SystemZ/regs-bad.s
index 65720578ff8f..37c83dd4b8ff 100644
--- a/test/MC/SystemZ/regs-bad.s
+++ b/test/MC/SystemZ/regs-bad.s
@@ -239,14 +239,6 @@
.cfi_offset %reef,0
.cfi_offset %arid,0
-# Test invalid CFI registers. Will need to be updated once access
-# registers are modelled as LLVM registers.
-#
-#CHECK: error: invalid operand for instruction
-#CHECK: .cfi_offset %a0,0
-
- .cfi_offset %a0,0
-
.cfi_endproc
#CHECK: error: %r0 used in an address
diff --git a/test/MC/SystemZ/regs-good.s b/test/MC/SystemZ/regs-good.s
index 7513d0c6b2a3..4047579bcbb3 100644
--- a/test/MC/SystemZ/regs-good.s
+++ b/test/MC/SystemZ/regs-good.s
@@ -100,6 +100,24 @@
lxr %f8,%f9
lxr %f12,%f13
+#CHECK: cpya %a0, %a1 # encoding: [0xb2,0x4d,0x00,0x01]
+#CHECK: cpya %a2, %a3 # encoding: [0xb2,0x4d,0x00,0x23]
+#CHECK: cpya %a4, %a5 # encoding: [0xb2,0x4d,0x00,0x45]
+#CHECK: cpya %a6, %a7 # encoding: [0xb2,0x4d,0x00,0x67]
+#CHECK: cpya %a8, %a9 # encoding: [0xb2,0x4d,0x00,0x89]
+#CHECK: cpya %a10, %a11 # encoding: [0xb2,0x4d,0x00,0xab]
+#CHECK: cpya %a12, %a13 # encoding: [0xb2,0x4d,0x00,0xcd]
+#CHECK: cpya %a14, %a15 # encoding: [0xb2,0x4d,0x00,0xef]
+
+ cpya %a0,%a1
+ cpya %a2,%a3
+ cpya %a4,%a5
+ cpya %a6,%a7
+ cpya %a8,%a9
+ cpya %a10,%a11
+ cpya %a12,%a13
+ cpya %a14,%a15
+
#CHECK: .cfi_offset %r0, 0
#CHECK: .cfi_offset %r1, 8
#CHECK: .cfi_offset %r2, 16
@@ -132,6 +150,22 @@
#CHECK: .cfi_offset %f13, 232
#CHECK: .cfi_offset %f14, 240
#CHECK: .cfi_offset %f15, 248
+#CHECK: .cfi_offset %a0, 256
+#CHECK: .cfi_offset %a1, 260
+#CHECK: .cfi_offset %a2, 264
+#CHECK: .cfi_offset %a3, 268
+#CHECK: .cfi_offset %a4, 272
+#CHECK: .cfi_offset %a5, 276
+#CHECK: .cfi_offset %a6, 280
+#CHECK: .cfi_offset %a7, 284
+#CHECK: .cfi_offset %a8, 288
+#CHECK: .cfi_offset %r9, 292
+#CHECK: .cfi_offset %a10, 296
+#CHECK: .cfi_offset %a11, 300
+#CHECK: .cfi_offset %a12, 304
+#CHECK: .cfi_offset %a13, 308
+#CHECK: .cfi_offset %a14, 312
+#CHECK: .cfi_offset %a15, 316
.cfi_startproc
.cfi_offset %r0,0
@@ -166,4 +200,20 @@
.cfi_offset %f13,232
.cfi_offset %f14,240
.cfi_offset %f15,248
+ .cfi_offset %a0,256
+ .cfi_offset %a1,260
+ .cfi_offset %a2,264
+ .cfi_offset %a3,268
+ .cfi_offset %a4,272
+ .cfi_offset %a5,276
+ .cfi_offset %a6,280
+ .cfi_offset %a7,284
+ .cfi_offset %a8,288
+ .cfi_offset %r9,292
+ .cfi_offset %a10,296
+ .cfi_offset %a11,300
+ .cfi_offset %a12,304
+ .cfi_offset %a13,308
+ .cfi_offset %a14,312
+ .cfi_offset %a15,316
.cfi_endproc