BDMem,
BDXMem,
BDLMem,
+ BDRMem,
BDVMem
};
unsigned MemKind : 4;
unsigned RegKind : 4;
const MCExpr *Disp;
- const MCExpr *Length;
+ union {
+ const MCExpr *Imm;
+ unsigned Reg;
+ } Length;
};
// Imm is an immediate operand, and Sym is an optional TLS symbol
}
static std::unique_ptr<SystemZOperand>
createMem(MemoryKind MemKind, RegisterKind RegKind, unsigned Base,
- const MCExpr *Disp, unsigned Index, const MCExpr *Length,
- SMLoc StartLoc, SMLoc EndLoc) {
+ const MCExpr *Disp, unsigned Index, const MCExpr *LengthImm,
+ unsigned LengthReg, SMLoc StartLoc, SMLoc EndLoc) {
auto Op = make_unique<SystemZOperand>(KindMem, StartLoc, EndLoc);
Op->Mem.MemKind = MemKind;
Op->Mem.RegKind = RegKind;
Op->Mem.Base = Base;
Op->Mem.Index = Index;
Op->Mem.Disp = Disp;
- Op->Mem.Length = Length;
+ if (MemKind == BDLMem)
+ Op->Mem.Length.Imm = LengthImm;
+ if (MemKind == BDRMem)
+ Op->Mem.Length.Reg = LengthReg;
return Op;
}
static std::unique_ptr<SystemZOperand>
return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287);
}
bool isMemDisp12Len8(RegisterKind RegKind) const {
- return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length, 1, 0x100);
- }
- void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
- assert(N == 3 && "Invalid number of operands");
- assert(isMem(BDVMem) && "Invalid operand type");
- Inst.addOperand(MCOperand::createReg(Mem.Base));
- addExpr(Inst, Mem.Disp);
- Inst.addOperand(MCOperand::createReg(Mem.Index));
+ return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x100);
}
// Override MCParsedAsmOperand.
assert(isMem(BDLMem) && "Invalid operand type");
Inst.addOperand(MCOperand::createReg(Mem.Base));
addExpr(Inst, Mem.Disp);
- addExpr(Inst, Mem.Length);
+ addExpr(Inst, Mem.Length.Imm);
+ }
+ void addBDRAddrOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 3 && "Invalid number of operands");
+ assert(isMem(BDRMem) && "Invalid operand type");
+ Inst.addOperand(MCOperand::createReg(Mem.Base));
+ addExpr(Inst, Mem.Disp);
+ Inst.addOperand(MCOperand::createReg(Mem.Length.Reg));
+ }
+ void addBDVAddrOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 3 && "Invalid number of operands");
+ assert(isMem(BDVMem) && "Invalid operand type");
+ Inst.addOperand(MCOperand::createReg(Mem.Base));
+ addExpr(Inst, Mem.Disp);
+ Inst.addOperand(MCOperand::createReg(Mem.Index));
}
void addImmTLSOperands(MCInst &Inst, unsigned N) const {
assert(N == 2 && "Invalid number of operands");
bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, ADDR64Reg); }
bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, ADDR64Reg); }
bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(ADDR64Reg); }
+ bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, ADDR64Reg); }
bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, ADDR64Reg); }
bool isU1Imm() const { return isImm(0, 1); }
bool isU2Imm() const { return isImm(0, 3); }
OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
- bool parseAddress(unsigned &Base, const MCExpr *&Disp,
- unsigned &Index, bool &IsVector, const MCExpr *&Length,
- const unsigned *Regs, RegisterKind RegKind);
+ bool parseAddress(bool &HaveReg1, Register &Reg1,
+ bool &HaveReg2, Register &Reg2,
+ const MCExpr *&Disp, const MCExpr *&Length);
+ bool parseAddressRegister(Register &Reg);
bool ParseDirectiveInsn(SMLoc L);
OperandMatchResultTy parseBDLAddr64(OperandVector &Operands) {
return parseAddress(Operands, BDLMem, SystemZMC::GR64Regs, ADDR64Reg);
}
+ OperandMatchResultTy parseBDRAddr64(OperandVector &Operands) {
+ return parseAddress(Operands, BDRMem, SystemZMC::GR64Regs, ADDR64Reg);
+ }
OperandMatchResultTy parseBDVAddr64(OperandVector &Operands) {
return parseAddress(Operands, BDVMem, SystemZMC::GR64Regs, ADDR64Reg);
}
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).
-bool SystemZAsmParser::parseAddress(unsigned &Base, const MCExpr *&Disp,
- unsigned &Index, bool &IsVector,
- const MCExpr *&Length, const unsigned *Regs,
- RegisterKind RegKind) {
+// Parse a memory operand into Reg1, Reg2, Disp, and Length.
+bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1,
+ bool &HaveReg2, Register &Reg2,
+ const MCExpr *&Disp,
+ const MCExpr *&Length) {
// Parse the displacement, which must always be present.
if (getParser().parseExpression(Disp))
return true;
// Parse the optional base and index.
- Index = 0;
- Base = 0;
- IsVector = false;
+ HaveReg1 = false;
+ HaveReg2 = false;
Length = nullptr;
if (getLexer().is(AsmToken::LParen)) {
Parser.Lex();
if (getLexer().is(AsmToken::Percent)) {
- // Parse the first register and decide whether it's a base or an index.
- Register Reg;
- if (parseRegister(Reg))
+ // Parse the first register.
+ HaveReg1 = true;
+ if (parseRegister(Reg1))
return true;
- if (Reg.Group == RegV) {
- // A vector index register. The base register is optional.
- IsVector = true;
- Index = SystemZMC::VR128Regs[Reg.Num];
- } else if (Reg.Group == RegGR) {
- if (Reg.Num == 0)
- return Error(Reg.StartLoc, "%r0 used in an address");
- // If the are two registers, the first one is the index and the
- // second is the base.
- if (getLexer().is(AsmToken::Comma))
- Index = Regs[Reg.Num];
- else
- Base = Regs[Reg.Num];
- } else
- return Error(Reg.StartLoc, "invalid address register");
} else {
// Parse the length.
if (getParser().parseExpression(Length))
return true;
}
- // Check whether there's a second register. It's the base if so.
+ // Check whether there's a second register.
if (getLexer().is(AsmToken::Comma)) {
Parser.Lex();
- Register Reg;
- if (parseRegister(Reg, RegGR, Regs, RegKind))
+ HaveReg2 = true;
+ if (parseRegister(Reg2))
return true;
- Base = Reg.Num;
}
// Consume the closing bracket.
return false;
}
+// Verify that Reg is a valid address register (base or index).
+bool
+SystemZAsmParser::parseAddressRegister(Register &Reg) {
+ if (Reg.Group == RegV) {
+ Error(Reg.StartLoc, "invalid use of vector addressing");
+ return true;
+ } else if (Reg.Group != RegGR) {
+ Error(Reg.StartLoc, "invalid address register");
+ return true;
+ } else if (Reg.Num == 0) {
+ Error(Reg.StartLoc, "%r0 used in an address");
+ return true;
+ }
+ return false;
+}
+
// Parse a memory operand and add it to Operands. The other arguments
// are as above.
SystemZAsmParser::OperandMatchResultTy
SystemZAsmParser::parseAddress(OperandVector &Operands, MemoryKind MemKind,
const unsigned *Regs, RegisterKind RegKind) {
SMLoc StartLoc = Parser.getTok().getLoc();
- unsigned Base, Index;
- bool IsVector;
+ unsigned Base = 0, Index = 0, LengthReg = 0;
+ Register Reg1, Reg2;
+ bool HaveReg1, HaveReg2;
const MCExpr *Disp;
const MCExpr *Length;
- if (parseAddress(Base, Disp, Index, IsVector, Length, Regs, RegKind))
+ if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Disp, Length))
return MatchOperand_ParseFail;
- if (IsVector && MemKind != BDVMem) {
- Error(StartLoc, "invalid use of vector addressing");
- return MatchOperand_ParseFail;
- }
-
- if (!IsVector && MemKind == BDVMem) {
- Error(StartLoc, "vector index required in address");
- return MatchOperand_ParseFail;
- }
-
- if (Index && MemKind != BDXMem && MemKind != BDVMem) {
- Error(StartLoc, "invalid use of indexed addressing");
- return MatchOperand_ParseFail;
- }
-
- if (Length && MemKind != BDLMem) {
- Error(StartLoc, "invalid use of length addressing");
- return MatchOperand_ParseFail;
- }
-
- if (!Length && MemKind == BDLMem) {
- Error(StartLoc, "missing length in address");
- return MatchOperand_ParseFail;
+ switch (MemKind) {
+ case BDMem:
+ // If we have Reg1, it must be an address register.
+ if (HaveReg1) {
+ if (parseAddressRegister(Reg1))
+ return MatchOperand_ParseFail;
+ Base = Regs[Reg1.Num];
+ }
+ // There must be no Reg2 or length.
+ if (Length) {
+ Error(StartLoc, "invalid use of length addressing");
+ return MatchOperand_ParseFail;
+ }
+ if (HaveReg2) {
+ Error(StartLoc, "invalid use of indexed addressing");
+ return MatchOperand_ParseFail;
+ }
+ break;
+ case BDXMem:
+ // If we have Reg1, it must be an address register.
+ if (HaveReg1) {
+ if (parseAddressRegister(Reg1))
+ return MatchOperand_ParseFail;
+ // If the are two registers, the first one is the index and the
+ // second is the base.
+ if (HaveReg2)
+ Index = Regs[Reg1.Num];
+ else
+ Base = Regs[Reg1.Num];
+ }
+ // If we have Reg2, it must be an address register.
+ if (HaveReg2) {
+ if (parseAddressRegister(Reg2))
+ return MatchOperand_ParseFail;
+ Base = Regs[Reg2.Num];
+ }
+ // There must be no length.
+ if (Length) {
+ Error(StartLoc, "invalid use of length addressing");
+ return MatchOperand_ParseFail;
+ }
+ break;
+ case BDLMem:
+ // If we have Reg2, it must be an address register.
+ if (HaveReg2) {
+ if (parseAddressRegister(Reg2))
+ return MatchOperand_ParseFail;
+ Base = Regs[Reg2.Num];
+ }
+ // We cannot support base+index addressing.
+ if (HaveReg1 && HaveReg2) {
+ Error(StartLoc, "invalid use of indexed addressing");
+ return MatchOperand_ParseFail;
+ }
+ // We must have a length.
+ if (!Length) {
+ Error(StartLoc, "missing length in address");
+ return MatchOperand_ParseFail;
+ }
+ break;
+ case BDRMem:
+ // We must have Reg1, and it must be a GPR.
+ if (!HaveReg1 || Reg1.Group != RegGR) {
+ Error(StartLoc, "invalid operand for instruction");
+ return MatchOperand_ParseFail;
+ }
+ LengthReg = SystemZMC::GR64Regs[Reg1.Num];
+ // If we have Reg2, it must be an address register.
+ if (HaveReg2) {
+ if (parseAddressRegister(Reg2))
+ return MatchOperand_ParseFail;
+ Base = Regs[Reg2.Num];
+ }
+ // There must be no length.
+ if (Length) {
+ Error(StartLoc, "invalid use of length addressing");
+ return MatchOperand_ParseFail;
+ }
+ break;
+ case BDVMem:
+ // We must have Reg1, and it must be a vector register.
+ if (!HaveReg1 || Reg1.Group != RegV) {
+ Error(StartLoc, "vector index required in address");
+ return MatchOperand_ParseFail;
+ }
+ Index = SystemZMC::VR128Regs[Reg1.Num];
+ // If we have Reg2, it must be an address register.
+ if (HaveReg2) {
+ if (parseAddressRegister(Reg2))
+ return MatchOperand_ParseFail;
+ Base = Regs[Reg2.Num];
+ }
+ // There must be no length.
+ if (Length) {
+ Error(StartLoc, "invalid use of length addressing");
+ return MatchOperand_ParseFail;
+ }
+ break;
}
SMLoc EndLoc =
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
Operands.push_back(SystemZOperand::createMem(MemKind, RegKind, Base, Disp,
- Index, Length, StartLoc,
- EndLoc));
+ Index, Length, LengthReg,
+ StartLoc, EndLoc));
return MatchOperand_Success;
}
// real address operands should have used a context-dependent parse routine,
// so we treat any plain expression as an immediate.
SMLoc StartLoc = Parser.getTok().getLoc();
- unsigned Base, Index;
- bool IsVector;
- const MCExpr *Expr, *Length;
- if (parseAddress(Base, Expr, Index, IsVector, Length, SystemZMC::GR64Regs,
- ADDR64Reg))
- return true;
+ Register Reg1, Reg2;
+ bool HaveReg1, HaveReg2;
+ const MCExpr *Expr;
+ const MCExpr *Length;
+ if (parseAddress(HaveReg1, Reg1, HaveReg2, Reg2, Expr, Length))
+ return MatchOperand_ParseFail;
+ // If the register combination is not valid for any instruction, reject it.
+ // Otherwise, fall back to reporting an unrecognized instruction.
+ if (HaveReg1 && Reg1.Group != RegGR && Reg1.Group != RegV
+ && parseAddressRegister(Reg1))
+ return MatchOperand_ParseFail;
+ if (HaveReg2 && parseAddressRegister(Reg2))
+ return MatchOperand_ParseFail;
SMLoc EndLoc =
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- if (Base || Index || Length)
+ if (HaveReg1 || HaveReg2 || Length)
Operands.push_back(SystemZOperand::createInvalid(StartLoc, EndLoc));
else
Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
return MCDisassembler::Success;
}
+static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field,
+ const unsigned *Regs) {
+ uint64_t Length = Field >> 16;
+ uint64_t Base = (Field >> 12) & 0xf;
+ uint64_t Disp = Field & 0xfff;
+ assert(Length < 16 && "Invalid BDRAddr12");
+ Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
+ Inst.addOperand(MCOperand::createImm(Disp));
+ Inst.addOperand(MCOperand::createReg(Regs[Length]));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
const unsigned *Regs) {
uint64_t Index = Field >> 16;
return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
}
+static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst &Inst,
+ uint64_t Field,
+ uint64_t Address,
+ const void *Decoder) {
+ return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
+}
+
static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
uint64_t Address,
const void *Decoder) {
O << ')';
}
+void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ unsigned Base = MI->getOperand(OpNum).getReg();
+ uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
+ unsigned Length = MI->getOperand(OpNum + 2).getReg();
+ O << Disp << "(%" << getRegisterName(Length);
+ if (Base)
+ O << ",%" << getRegisterName(Base);
+ O << ')';
+}
+
void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
printAddress(MI->getOperand(OpNum).getReg(),
void printBDAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printBDXAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printBDLAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printBDRAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printBDVAddrOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printU1ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printU2ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
}
uint64_t SystemZMCCodeEmitter::
+getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
+ uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+ uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
+ assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
+ return (Len << 16) | (Base << 12) | Disp;
+}
+
+uint64_t SystemZMCCodeEmitter::
getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
field bits<48> Inst;
field bits<48> SoftFail = 0;
- bits<20> XBD1;
+ bits<20> RBD1;
bits<16> BD2;
bits<4> R3;
let Inst{47-40} = op;
- let Inst{39-36} = XBD1{19-16};
+ let Inst{39-36} = RBD1{19-16};
let Inst{35-32} = R3;
- let Inst{31-16} = XBD1{15-0};
+ let Inst{31-16} = RBD1{15-0};
let Inst{15-0} = BD2;
}
let mayLoad = 1, mayStore = 1 in
def MVCK : InstSSd<0xD9, (outs),
- (ins bdxaddr12only:$XBD1, bdaddr12only:$BD2,
+ (ins bdraddr12only:$RBD1, bdaddr12only:$BD2,
GR64:$R3),
- "mvck\t$XBD1, $BD2, $R3", []>;
+ "mvck\t$RBD1, $BD2, $R3", []>;
}
let mayStore = 1 in
imm32zx16:$I2),
".insn sil,$enc,$BD1,$I2", []>;
def InsnSS : DirectiveInsnSS<(outs),
- (ins imm64zx48:$enc, bdxaddr12only:$XBD1,
+ (ins imm64zx48:$enc, bdraddr12only:$RBD1,
bdaddr12only:$BD2, AnyReg:$R3),
- ".insn ss,$enc,$XBD1,$BD2,$R3", []>;
+ ".insn ss,$enc,$RBD1,$BD2,$R3", []>;
def InsnSSE : DirectiveInsnSSE<(outs),
(ins imm64zx48:$enc,
bdaddr12only:$BD1,bdaddr12only:$BD2),
!cast<Immediate>("disp"##dispsize##"imm"##bitsize),
!cast<Immediate>("imm"##bitsize))>;
+// A BDMode paired with a register length operand.
+class BDRMode<string type, string bitsize, string dispsize, string suffix>
+ : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDRAddr",
+ (ops !cast<RegisterOperand>("ADDR"##bitsize),
+ !cast<Immediate>("disp"##dispsize##"imm"##bitsize),
+ !cast<RegisterOperand>("GR"##bitsize))>;
+
// An addressing mode with a base, displacement and a vector index.
class BDVMode<string bitsize, string dispsize>
: AddressOperand<bitsize, dispsize, "", "BDVAddr",
def BDXAddr64Disp12 : AddressAsmOperand<"BDXAddr", "64", "12">;
def BDXAddr64Disp20 : AddressAsmOperand<"BDXAddr", "64", "20">;
def BDLAddr64Disp12Len8 : AddressAsmOperand<"BDLAddr", "64", "12", "Len8">;
+def BDRAddr64Disp12 : AddressAsmOperand<"BDRAddr", "64", "12">;
def BDVAddr64Disp12 : AddressAsmOperand<"BDVAddr", "64", "12">;
// DAG patterns and operands for addressing modes. Each mode has
def laaddr12pair : BDXMode<"LAAddr", "64", "12", "Pair">;
def laaddr20pair : BDXMode<"LAAddr", "64", "20", "Pair">;
def bdladdr12onlylen8 : BDLMode<"BDLAddr", "64", "12", "Only", "8">;
+def bdraddr12only : BDRMode<"BDRAddr", "64", "12", "Only">;
def bdvaddr12only : BDVMode< "64", "12">;
//===----------------------------------------------------------------------===//
# CHECK: mvc 0(256,%r15), 0
0xd2 0xff 0xf0 0x00 0x00 0x00
-# CHECK: mvck 0, 0, %r0
+# CHECK: mvck 0(%r0), 0, %r0
0xd9 0x00 0x00 0x00 0x00 0x00
-# CHECK: mvck 0, 4095, %r2
+# CHECK: mvck 0(%r0), 4095, %r2
0xd9 0x02 0x00 0x00 0x0f 0xff
-# CHECK: mvck 0, 0(%r1), %r2
+# CHECK: mvck 0(%r0), 0(%r1), %r2
0xd9 0x02 0x00 0x00 0x10 0x00
-# CHECK: mvck 0, 0(%r15), %r2
+# CHECK: mvck 0(%r0), 0(%r15), %r2
0xd9 0x02 0x00 0x00 0xf0 0x00
-# CHECK: mvck 0(%r1), 4095(%r15), %r2
+# CHECK: mvck 0(%r0,%r1), 4095(%r15), %r2
0xd9 0x02 0x10 0x00 0xff 0xff
-# CHECK: mvck 0(%r1), 0(%r15), %r2
+# CHECK: mvck 0(%r0,%r1), 0(%r15), %r2
0xd9 0x02 0x10 0x00 0xf0 0x00
# CHECK: mvck 4095(%r15,%r1), 0(%r15), %r2
#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 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
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(%r0), 0, %r3 # encoding: [0xd9,0x03,0x00,0x00,0x00,0x00]
+#CHECK: mvck 0(%r1), 0, %r3 # encoding: [0xd9,0x13,0x00,0x00,0x00,0x00]
+#CHECK: mvck 0(%r1), 0(%r1), %r3 # encoding: [0xd9,0x13,0x00,0x00,0x10,0x00]
+#CHECK: mvck 0(%r1), 0(%r15), %r3 # encoding: [0xd9,0x13,0x00,0x00,0xf0,0x00]
+#CHECK: mvck 0(%r1), 4095, %r3 # encoding: [0xd9,0x13,0x00,0x00,0x0f,0xff]
+#CHECK: mvck 0(%r1), 4095(%r1), %r3 # encoding: [0xd9,0x13,0x00,0x00,0x1f,0xff]
+#CHECK: mvck 0(%r1), 4095(%r15), %r3 # encoding: [0xd9,0x13,0x00,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 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(%r0), 0, %r3
mvck 0(%r1), 0, %r3
mvck 0(%r1), 0(%r1), %r3
mvck 0(%r1), 0(%r15), %r3
#CHECK: foo 100(200,%r1), 300
#CHECK: error: invalid address register
#CHECK: foo 100(%a0), 200
-#CHECK: error: %r0 used in an address
+#CHECK: error: invalid instruction
#CHECK: foo 100(%r0), 200
#CHECK: error: %r0 used in an address
#CHECK: foo 100(%v1,%r0), 200
#CHECK: foo 100(%v0,%r1), 200
#CHECK: error: invalid instruction
#CHECK: foo 100(%v31), 200
-#CHECK: error: invalid operand
+#CHECK: error: invalid address register
#CHECK: foo 100(%r1,%a0), 200
#CHECK: error: %r0 used in an address
#CHECK: foo 100(%r1,%r0), 200