[AArch64][SVE] Asm: Support for FCPY immediate instructions.

Predicated copy of floating-point immediate value to SVE vector,
along with MOV-aliases.

Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar

Reviewed By: javed.absar

Differential Revision: https://reviews.llvm.org/D47518

llvm-svn: 333869
This commit is contained in:
Sander de Smalen 2018-06-04 05:58:06 +00:00
parent 512d57f1a5
commit 367a53b059
6 changed files with 3308 additions and 2 deletions

View File

@ -41,8 +41,9 @@ let Predicates = [HasSVE] in {
defm DUPM_ZI : sve_int_dup_mask_imm<"dupm">;
// Splat immediate (predicated)
defm CPY_ZPmI : sve_int_dup_imm_pred_merge<"cpy">;
defm CPY_ZPzI : sve_int_dup_imm_pred_zero<"cpy">;
defm CPY_ZPmI : sve_int_dup_imm_pred_merge<"cpy">;
defm CPY_ZPzI : sve_int_dup_imm_pred_zero<"cpy">;
defm FCPY_ZPmI : sve_int_dup_fpimm_pred<"fcpy">;
// continuous load with reg+immediate
defm LD1B_IMM : sve_mem_cld_si<0b0000, "ld1b", Z_b, ZPR8>;

View File

@ -621,6 +621,39 @@ class sve_int_bin_cons_log<bits<2> opc, string asm>
// SVE Integer Wide Immediate - Predicated Group
//===----------------------------------------------------------------------===//
class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
string asm, ZPRRegOp zprty>
: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
asm, "\t$Zd, $Pg/m, $imm8",
"",
[]>, Sched<[]> {
bits<4> Pg;
bits<5> Zd;
bits<8> imm8;
let Inst{31-24} = 0b00000101;
let Inst{23-22} = sz;
let Inst{21-20} = 0b01;
let Inst{19-16} = Pg;
let Inst{15-13} = 0b110;
let Inst{12-5} = imm8;
let Inst{4-0} = Zd;
let Constraints = "$Zd = $_Zd";
}
multiclass sve_int_dup_fpimm_pred<string asm> {
def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
(!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
}
class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
ZPRRegOp zprty, string pred_qual, dag iops>
: I<(outs zprty:$Zd), iops,
@ -656,6 +689,13 @@ multiclass sve_int_dup_imm_pred_merge<string asm> {
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, cpy_imm8_opt_lsl_i32:$imm), 1>;
def : InstAlias<"mov $Zd, $Pg/m, $imm",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, cpy_imm8_opt_lsl_i64:$imm), 1>;
def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
(!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
}
multiclass sve_int_dup_imm_pred_zero<string asm> {

View File

@ -0,0 +1,83 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Invalid predicate suffix
fcpy z0.h, p0/z, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: fcpy z0.h, p0/z, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.s, p0/z, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: fcpy z0.s, p0/z, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.d, p0/z, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: fcpy z0.d, p0/z, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid immediates
fcpy z0.h, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.h, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.s, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.s, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.d, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.d, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.h, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.h, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.s, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.s, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.d, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.d, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.h, p0/m, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.h, p0/m, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.s, p0/m, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.s, p0/m, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.d, p0/m, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.d, p0/m, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.h, p0/m, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.h, p0/m, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.s, p0/m, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.s, p0/m, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fcpy z0.d, p0/m, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fcpy z0.d, p0/m, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,23 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Invalid predicate suffix
fmov z0.h, p0/z, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: fmov z0.h, p0/z, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.s, p0/z, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: fmov z0.s, p0/z, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.d, p0/z, #0.0
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
// CHECK-NEXT: fmov z0.d, p0/z, #0.0
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid immediates
@ -62,3 +80,63 @@ fmov z0.d, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.d, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.h, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.h, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.s, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.s, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.d, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.d, p0/m, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.h, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.h, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.s, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.s, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.d, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.d, p0/m, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.h, p0/m, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.h, p0/m, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.s, p0/m, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.s, p0/m, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.d, p0/m, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.d, p0/m, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.h, p0/m, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.h, p0/m, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.s, p0/m, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.s, p0/m, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
fmov z0.d, p0/m, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fmov z0.d, p0/m, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

File diff suppressed because it is too large Load Diff