[AArch64][SVE] Asm: Print indexed element 0 as FPR.
Print the first indexed element as a FP register, for example: mov z0.d, z1.d[0] Is now printed as: mov z0.d, d1 Next to printing, this patch also adds aliases to parse 'mov z0.d, d1'. Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D47571 llvm-svn: 333872
This commit is contained in:
parent
c33d668ab7
commit
fd54a781f6
|
@ -859,6 +859,22 @@ def ZPR32 : ZPRRegOp<"s", ZPRAsmOp32, ZPR>;
|
|||
def ZPR64 : ZPRRegOp<"d", ZPRAsmOp64, ZPR>;
|
||||
def ZPR128 : ZPRRegOp<"q", ZPRAsmOp128, ZPR>;
|
||||
|
||||
class FPRasZPR<int Width> : AsmOperandClass{
|
||||
let Name = "FPR" # Width # "asZPR";
|
||||
let PredicateMethod = "isFPRasZPR<AArch64::FPR" # Width # "RegClassID>";
|
||||
let RenderMethod = "addFPRasZPRRegOperands<" # Width # ">";
|
||||
}
|
||||
|
||||
class FPRasZPROperand<int Width> : RegisterOperand<ZPR> {
|
||||
let ParserMatchClass = FPRasZPR<Width>;
|
||||
let PrintMethod = "printZPRasFPR<" # Width # ">";
|
||||
}
|
||||
|
||||
def FPR8asZPR : FPRasZPROperand<8>;
|
||||
def FPR16asZPR : FPRasZPROperand<16>;
|
||||
def FPR32asZPR : FPRasZPROperand<32>;
|
||||
def FPR64asZPR : FPRasZPROperand<64>;
|
||||
def FPR128asZPR : FPRasZPROperand<128>;
|
||||
|
||||
let Namespace = "AArch64" in {
|
||||
def zsub0 : SubRegIndex<128, -1>;
|
||||
|
|
|
@ -934,6 +934,11 @@ public:
|
|||
AArch64MCRegisterClasses[Class].contains(getReg());
|
||||
}
|
||||
|
||||
template <unsigned Class> bool isFPRasZPR() const {
|
||||
return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
|
||||
AArch64MCRegisterClasses[Class].contains(getReg());
|
||||
}
|
||||
|
||||
template <int ElementWidth, unsigned Class>
|
||||
DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const {
|
||||
if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector)
|
||||
|
@ -1269,6 +1274,21 @@ public:
|
|||
Inst.addOperand(MCOperand::createReg(Reg));
|
||||
}
|
||||
|
||||
template <int Width>
|
||||
void addFPRasZPRRegOperands(MCInst &Inst, unsigned N) const {
|
||||
unsigned Base;
|
||||
switch (Width) {
|
||||
case 8: Base = AArch64::B0; break;
|
||||
case 16: Base = AArch64::H0; break;
|
||||
case 32: Base = AArch64::S0; break;
|
||||
case 64: Base = AArch64::D0; break;
|
||||
case 128: Base = AArch64::Q0; break;
|
||||
default:
|
||||
llvm_unreachable("Unsupported width");
|
||||
}
|
||||
Inst.addOperand(MCOperand::createReg(AArch64::Z0 + getReg() - Base));
|
||||
}
|
||||
|
||||
void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
assert(
|
||||
|
|
|
@ -1499,3 +1499,21 @@ void AArch64InstPrinter::printSVELogicalImm(const MCInst *MI, unsigned OpNum,
|
|||
else
|
||||
O << '#' << formatHex((uint64_t)PrintVal);
|
||||
}
|
||||
|
||||
template <int Width>
|
||||
void AArch64InstPrinter::printZPRasFPR(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
unsigned Base;
|
||||
switch (Width) {
|
||||
case 8: Base = AArch64::B0; break;
|
||||
case 16: Base = AArch64::H0; break;
|
||||
case 32: Base = AArch64::S0; break;
|
||||
case 64: Base = AArch64::D0; break;
|
||||
case 128: Base = AArch64::Q0; break;
|
||||
default:
|
||||
llvm_unreachable("Unsupported width");
|
||||
}
|
||||
unsigned Reg = MI->getOperand(OpNum).getReg();
|
||||
O << getRegisterName(Reg - AArch64::Z0 + Base);
|
||||
}
|
||||
|
|
|
@ -180,6 +180,9 @@ protected:
|
|||
template <char = 0>
|
||||
void printSVERegOp(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
template <int Width>
|
||||
void printZPRasFPR(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
};
|
||||
|
||||
class AArch64AppleInstPrinter : public AArch64InstPrinter {
|
||||
|
|
|
@ -334,6 +334,16 @@ multiclass sve_int_perm_dup_i<string asm> {
|
|||
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
|
||||
def : InstAlias<"mov $Zd, $Zn$idx",
|
||||
(!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
|
||||
def : InstAlias<"mov $Zd, $Bn",
|
||||
(!cast<Instruction>(NAME # _B) ZPR8:$Zd, FPR8asZPR:$Bn, 0), 2>;
|
||||
def : InstAlias<"mov $Zd, $Hn",
|
||||
(!cast<Instruction>(NAME # _H) ZPR16:$Zd, FPR16asZPR:$Hn, 0), 2>;
|
||||
def : InstAlias<"mov $Zd, $Sn",
|
||||
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, FPR32asZPR:$Sn, 0), 2>;
|
||||
def : InstAlias<"mov $Zd, $Dn",
|
||||
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, FPR64asZPR:$Dn, 0), 2>;
|
||||
def : InstAlias<"mov $Zd, $Qn",
|
||||
(!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -141,6 +141,31 @@ dup z0.d, #128, lsl #8
|
|||
// --------------------------------------------------------------------------//
|
||||
// Immediate not compatible with encode/decode function.
|
||||
|
||||
dup z0.b, b0
|
||||
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
// CHECK-NEXT: dup z0.b, b0
|
||||
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
|
||||
|
||||
dup z0.h, h0
|
||||
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
// CHECK-NEXT: dup z0.h, h0
|
||||
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
|
||||
|
||||
dup z0.s, s0
|
||||
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
// CHECK-NEXT: dup z0.s, s0
|
||||
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
|
||||
|
||||
dup z0.d, d0
|
||||
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
// CHECK-NEXT: dup z0.d, d0
|
||||
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
|
||||
|
||||
dup z0.q, q0
|
||||
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
|
||||
// CHECK-NEXT: dup z0.q, q0
|
||||
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
|
||||
|
||||
dup z24.b, z17.b[-1]
|
||||
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 63].
|
||||
// CHECK-NEXT: dup z24.b, z17.b[-1]
|
||||
|
|
|
@ -182,31 +182,31 @@ dup z21.d, #32512
|
|||
// CHECK-UNKNOWN: f5 ef f8 25 <unknown>
|
||||
|
||||
dup z0.b, z0.b[0]
|
||||
// CHECK-INST: mov z0.b, z0.b[0]
|
||||
// CHECK-INST: mov z0.b, b0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x21,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 21 05 <unknown>
|
||||
|
||||
dup z0.h, z0.h[0]
|
||||
// CHECK-INST: mov z0.h, z0.h[0]
|
||||
// CHECK-INST: mov z0.h, h0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x22,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 22 05 <unknown>
|
||||
|
||||
dup z0.s, z0.s[0]
|
||||
// CHECK-INST: mov z0.s, z0.s[0]
|
||||
// CHECK-INST: mov z0.s, s0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x24,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 24 05 <unknown>
|
||||
|
||||
dup z0.d, z0.d[0]
|
||||
// CHECK-INST: mov z0.d, z0.d[0]
|
||||
// CHECK-INST: mov z0.d, d0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x28,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 28 05 <unknown>
|
||||
|
||||
dup z0.q, z0.q[0]
|
||||
// CHECK-INST: mov z0.q, z0.q[0]
|
||||
// CHECK-INST: mov z0.q, q0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x30,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 30 05 <unknown>
|
||||
|
|
|
@ -406,31 +406,61 @@ mov z21.d, p15/m, #-128, lsl #8
|
|||
// Tests for indexed variant
|
||||
|
||||
mov z0.b, z0.b[0]
|
||||
// CHECK-INST: mov z0.b, z0.b[0]
|
||||
// CHECK-INST: mov z0.b, b0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x21,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 21 05 <unknown>
|
||||
|
||||
mov z0.h, z0.h[0]
|
||||
// CHECK-INST: mov z0.h, z0.h[0]
|
||||
// CHECK-INST: mov z0.h, h0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x22,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 22 05 <unknown>
|
||||
|
||||
mov z0.s, z0.s[0]
|
||||
// CHECK-INST: mov z0.s, z0.s[0]
|
||||
// CHECK-INST: mov z0.s, s0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x24,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 24 05 <unknown>
|
||||
|
||||
mov z0.d, z0.d[0]
|
||||
// CHECK-INST: mov z0.d, z0.d[0]
|
||||
// CHECK-INST: mov z0.d, d0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x28,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 28 05 <unknown>
|
||||
|
||||
mov z0.q, z0.q[0]
|
||||
// CHECK-INST: mov z0.q, z0.q[0]
|
||||
// CHECK-INST: mov z0.q, q0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x30,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 30 05 <unknown>
|
||||
|
||||
mov z0.b, b0
|
||||
// CHECK-INST: mov z0.b, b0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x21,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 21 05 <unknown>
|
||||
|
||||
mov z0.h, h0
|
||||
// CHECK-INST: mov z0.h, h0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x22,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 22 05 <unknown>
|
||||
|
||||
mov z0.s, s0
|
||||
// CHECK-INST: mov z0.s, s0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x24,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 24 05 <unknown>
|
||||
|
||||
mov z0.d, d0
|
||||
// CHECK-INST: mov z0.d, d0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x28,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 28 05 <unknown>
|
||||
|
||||
mov z0.q, q0
|
||||
// CHECK-INST: mov z0.q, q0
|
||||
// CHECK-ENCODING: [0x00,0x20,0x30,0x05]
|
||||
// CHECK-ERROR: instruction requires: sve
|
||||
// CHECK-UNKNOWN: 00 20 30 05 <unknown>
|
||||
|
|
Loading…
Reference in New Issue