Index: lib/Target/AArch64/AArch64RegisterInfo.td =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.td +++ lib/Target/AArch64/AArch64RegisterInfo.td @@ -1062,17 +1062,17 @@ def ZPR#RegWidth#ExtSXTW16 : ZPRExtendRegisterOperand<0b1, 0b0, "SXTW", RegWidth, 16>; def ZPR#RegWidth#ExtSXTW32 : ZPRExtendRegisterOperand<0b1, 0b0, "SXTW", RegWidth, 32>; def ZPR#RegWidth#ExtSXTW64 : ZPRExtendRegisterOperand<0b1, 0b0, "SXTW", RegWidth, 64>; -} -// LSL(8|16|32|64) -def ZPR64AsmOpndExtLSL8 : ZPRExtendAsmOperand<"LSL", 64, 8>; -def ZPR64AsmOpndExtLSL16 : ZPRExtendAsmOperand<"LSL", 64, 16>; -def ZPR64AsmOpndExtLSL32 : ZPRExtendAsmOperand<"LSL", 64, 32>; -def ZPR64AsmOpndExtLSL64 : ZPRExtendAsmOperand<"LSL", 64, 64>; -def ZPR64ExtLSL8 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", 64, 8>; -def ZPR64ExtLSL16 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", 64, 16>; -def ZPR64ExtLSL32 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", 64, 32>; -def ZPR64ExtLSL64 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", 64, 64>; + // LSL(8|16|32|64) + def ZPR#RegWidth#AsmOpndExtLSL8 : ZPRExtendAsmOperand<"LSL", RegWidth, 8>; + def ZPR#RegWidth#AsmOpndExtLSL16 : ZPRExtendAsmOperand<"LSL", RegWidth, 16>; + def ZPR#RegWidth#AsmOpndExtLSL32 : ZPRExtendAsmOperand<"LSL", RegWidth, 32>; + def ZPR#RegWidth#AsmOpndExtLSL64 : ZPRExtendAsmOperand<"LSL", RegWidth, 64>; + def ZPR#RegWidth#ExtLSL8 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", RegWidth, 8>; + def ZPR#RegWidth#ExtLSL16 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", RegWidth, 16>; + def ZPR#RegWidth#ExtLSL32 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", RegWidth, 32>; + def ZPR#RegWidth#ExtLSL64 : ZPRExtendRegisterOperand<0b0, 0b1, "LSL", RegWidth, 64>; +} class GPR64ShiftExtendAsmOperand : AsmOperandClass { let Name = AsmOperandName # Scale; Index: lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64SVEInstrInfo.td +++ lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -496,6 +496,11 @@ defm PRFW_D_PZI : sve_mem_64b_prfm_vi<0b10, "prfw", uimm5s4>; defm PRFD_D_PZI : sve_mem_64b_prfm_vi<0b11, "prfd", uimm5s8>; + defm ADR_SXTW_ZZZ_D : sve_int_bin_cons_misc_0_a_sxtw<0b00, "adr">; + defm ADR_UXTW_ZZZ_D : sve_int_bin_cons_misc_0_a_uxtw<0b01, "adr">; + defm ADR_LSL_ZZZ_S : sve_int_bin_cons_misc_0_a_32_lsl<0b10, "adr">; + defm ADR_LSL_ZZZ_D : sve_int_bin_cons_misc_0_a_64_lsl<0b11, "adr">; + defm ZIP1_ZZZ : sve_int_perm_bin_perm_zz<0b000, "zip1">; defm ZIP2_ZZZ : sve_int_perm_bin_perm_zz<0b001, "zip2">; Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -2373,14 +2373,17 @@ SMLoc S = getLoc(); const MCExpr *Expr; - parseOptionalToken(AsmToken::Hash); - if (getParser().parseExpression(Expr)) - return MatchOperand_ParseFail; + const AsmToken &Tok = getParser().getTok(); + if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) { + if (getParser().parseExpression(Expr)) + return MatchOperand_ParseFail; - SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); - Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); + SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1); + Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext())); - return MatchOperand_Success; + return MatchOperand_Success; + } + return MatchOperand_NoMatch; } /// tryParseFPImm - A floating point immediate expression operand. @@ -4096,6 +4099,14 @@ case Match_InvalidZPR64UXTW64: case Match_InvalidZPR64SXTW64: return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'"); + case Match_InvalidZPR32LSL8: + return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s'"); + case Match_InvalidZPR32LSL16: + return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #1'"); + case Match_InvalidZPR32LSL32: + return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #2'"); + case Match_InvalidZPR32LSL64: + return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #3'"); case Match_InvalidZPR64LSL8: return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d'"); case Match_InvalidZPR64LSL16: @@ -4621,6 +4632,10 @@ case Match_InvalidZPR64SXTW32: case Match_InvalidZPR64UXTW64: case Match_InvalidZPR64SXTW64: + case Match_InvalidZPR32LSL8: + case Match_InvalidZPR32LSL16: + case Match_InvalidZPR32LSL32: + case Match_InvalidZPR32LSL64: case Match_InvalidZPR64LSL8: case Match_InvalidZPR64LSL16: case Match_InvalidZPR64LSL32: Index: lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- lib/Target/AArch64/SVEInstrFormats.td +++ lib/Target/AArch64/SVEInstrFormats.td @@ -2824,3 +2824,55 @@ def : InstAlias(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>; } + + +//===----------------------------------------------------------------------===// +// SVE Compute Vector Address Group +//===----------------------------------------------------------------------===// + +class sve_int_bin_cons_misc_0_a opc, bits<2> msz, string asm, + ZPRRegOp zprty, RegisterOperand zprext> +: I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm), + asm, "\t$Zd, [$Zn, $Zm]", + "", + []>, Sched<[]> { + bits<5> Zd; + bits<5> Zn; + bits<5> Zm; + let Inst{31-24} = 0b00000100; + let Inst{23-22} = opc; + let Inst{21} = 0b1; + let Inst{20-16} = Zm; + let Inst{15-12} = 0b1010; + let Inst{11-10} = msz; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; +} + +multiclass sve_int_bin_cons_misc_0_a_uxtw opc, string asm> { + def _0 : sve_int_bin_cons_misc_0_a; + def _1 : sve_int_bin_cons_misc_0_a; + def _2 : sve_int_bin_cons_misc_0_a; + def _3 : sve_int_bin_cons_misc_0_a; +} + +multiclass sve_int_bin_cons_misc_0_a_sxtw opc, string asm> { + def _0 : sve_int_bin_cons_misc_0_a; + def _1 : sve_int_bin_cons_misc_0_a; + def _2 : sve_int_bin_cons_misc_0_a; + def _3 : sve_int_bin_cons_misc_0_a; +} + +multiclass sve_int_bin_cons_misc_0_a_32_lsl opc, string asm> { + def _0 : sve_int_bin_cons_misc_0_a; + def _1 : sve_int_bin_cons_misc_0_a; + def _2 : sve_int_bin_cons_misc_0_a; + def _3 : sve_int_bin_cons_misc_0_a; +} + +multiclass sve_int_bin_cons_misc_0_a_64_lsl opc, string asm> { + def _0 : sve_int_bin_cons_misc_0_a; + def _1 : sve_int_bin_cons_misc_0_a; + def _2 : sve_int_bin_cons_misc_0_a; + def _3 : sve_int_bin_cons_misc_0_a; +} Index: test/MC/AArch64/SVE/adr-diagnostics.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/adr-diagnostics.s @@ -0,0 +1,59 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid addressing modes. + +adr z0.s, [z0.s, z0.d] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: adr z0.s, [z0.s, z0.d] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.s, [z0.s, z0.s, lsl] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected #imm after shift specifier +// CHECK-NEXT: adr z0.s, [z0.s, z0.s, lsl] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.s, [z0.s, z0.s, lsl #4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid shift/extend specified, expected 'z[0..31].s' +// CHECK-NEXT: adr z0.s, [z0.s, z0.s, lsl #4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.s, [z0.s, z0.s, uxtw] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid shift/extend specified, expected 'z[0..31].s' +// CHECK-NEXT: adr z0.s, [z0.s, z0.s, uxtw] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.s, [z0.s, z0.s, sxtw] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid shift/extend specified, expected 'z[0..31].s' +// CHECK-NEXT: adr z0.s, [z0.s, z0.s, sxtw] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.d, [z0.d, z0.s] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: adr z0.d, [z0.d, z0.s] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.d, [z0.d, z0.s, uxtw] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: adr z0.d, [z0.d, z0.s, uxtw] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.d, [z0.d, z0.s, sxtw] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: adr z0.d, [z0.d, z0.s, sxtw] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.d, [z0.d, z0.d, lsl #4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3' +// CHECK-NEXT: adr z0.d, [z0.d, z0.d, lsl #4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.d, [z0.d, z0.d, uxtw #4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3' +// CHECK-NEXT: adr z0.d, [z0.d, z0.d, uxtw #4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +adr z0.d, [z0.d, z0.d, sxtw #4] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3' +// CHECK-NEXT: adr z0.d, [z0.d, z0.d, sxtw #4] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: test/MC/AArch64/SVE/adr.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/adr.s @@ -0,0 +1,128 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +adr z0.s, [z0.s, z0.s] +// CHECK-INST: adr z0.s, [z0.s, z0.s] +// CHECK-ENCODING: [0x00,0xa0,0xa0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 a0 04 + +adr z0.s, [z0.s, z0.s, lsl #0] +// CHECK-INST: adr z0.s, [z0.s, z0.s] +// CHECK-ENCODING: [0x00,0xa0,0xa0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 a0 04 + +adr z0.s, [z0.s, z0.s, lsl #1] +// CHECK-INST: adr z0.s, [z0.s, z0.s, lsl #1] +// CHECK-ENCODING: [0x00,0xa4,0xa0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a4 a0 04 + +adr z0.s, [z0.s, z0.s, lsl #2] +// CHECK-INST: adr z0.s, [z0.s, z0.s, lsl #2] +// CHECK-ENCODING: [0x00,0xa8,0xa0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a8 a0 04 + +adr z0.s, [z0.s, z0.s, lsl #3] +// CHECK-INST: adr z0.s, [z0.s, z0.s, lsl #3] +// CHECK-ENCODING: [0x00,0xac,0xa0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 ac a0 04 + +adr z0.d, [z0.d, z0.d] +// CHECK-INST: adr z0.d, [z0.d, z0.d] +// CHECK-ENCODING: [0x00,0xa0,0xe0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 e0 04 + +adr z0.d, [z0.d, z0.d, lsl #0] +// CHECK-INST: adr z0.d, [z0.d, z0.d] +// CHECK-ENCODING: [0x00,0xa0,0xe0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 e0 04 + +adr z0.d, [z0.d, z0.d, lsl #1] +// CHECK-INST: adr z0.d, [z0.d, z0.d, lsl #1] +// CHECK-ENCODING: [0x00,0xa4,0xe0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a4 e0 04 + +adr z0.d, [z0.d, z0.d, lsl #2] +// CHECK-INST: adr z0.d, [z0.d, z0.d, lsl #2] +// CHECK-ENCODING: [0x00,0xa8,0xe0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a8 e0 04 + +adr z0.d, [z0.d, z0.d, lsl #3] +// CHECK-INST: adr z0.d, [z0.d, z0.d, lsl #3] +// CHECK-ENCODING: [0x00,0xac,0xe0,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 ac e0 04 + +adr z0.d, [z0.d, z0.d, uxtw] +// CHECK-INST: adr z0.d, [z0.d, z0.d, uxtw] +// CHECK-ENCODING: [0x00,0xa0,0x60,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 60 04 + +adr z0.d, [z0.d, z0.d, uxtw #0] +// CHECK-INST: adr z0.d, [z0.d, z0.d, uxtw] +// CHECK-ENCODING: [0x00,0xa0,0x60,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 60 04 + +adr z0.d, [z0.d, z0.d, uxtw #1] +// CHECK-INST: adr z0.d, [z0.d, z0.d, uxtw #1] +// CHECK-ENCODING: [0x00,0xa4,0x60,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a4 60 04 + +adr z0.d, [z0.d, z0.d, uxtw #2] +// CHECK-INST: adr z0.d, [z0.d, z0.d, uxtw #2] +// CHECK-ENCODING: [0x00,0xa8,0x60,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a8 60 04 + +adr z0.d, [z0.d, z0.d, uxtw #3] +// CHECK-INST: adr z0.d, [z0.d, z0.d, uxtw #3] +// CHECK-ENCODING: [0x00,0xac,0x60,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 ac 60 04 + +adr z0.d, [z0.d, z0.d, sxtw] +// CHECK-INST: adr z0.d, [z0.d, z0.d, sxtw] +// CHECK-ENCODING: [0x00,0xa0,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 20 04 + +adr z0.d, [z0.d, z0.d, sxtw #0] +// CHECK-INST: adr z0.d, [z0.d, z0.d, sxtw] +// CHECK-ENCODING: [0x00,0xa0,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a0 20 04 + +adr z0.d, [z0.d, z0.d, sxtw #1] +// CHECK-INST: adr z0.d, [z0.d, z0.d, sxtw #1] +// CHECK-ENCODING: [0x00,0xa4,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a4 20 04 + +adr z0.d, [z0.d, z0.d, sxtw #2] +// CHECK-INST: adr z0.d, [z0.d, z0.d, sxtw #2] +// CHECK-ENCODING: [0x00,0xa8,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 a8 20 04 + +adr z0.d, [z0.d, z0.d, sxtw #3] +// CHECK-INST: adr z0.d, [z0.d, z0.d, sxtw #3] +// CHECK-ENCODING: [0x00,0xac,0x20,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 ac 20 04