Skip to content

Commit

Permalink
[AArch64][SVE] Asm: Support for FDUP_ZI (copy fp immediate) instruction.
Browse files Browse the repository at this point in the history
Unpredicated copy of floating-point immediate value into SVE vector,
along with MOV-aliases.

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

Reviewed By: fhahn

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

llvm-svn: 333744
  • Loading branch information
sdesmalen-arm committed Jun 1, 2018
1 parent a041d84 commit f95ea04
Show file tree
Hide file tree
Showing 6 changed files with 1,773 additions and 0 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Expand Up @@ -37,6 +37,7 @@ let Predicates = [HasSVE] in {

// Splat immediate (unpredicated)
defm DUP_ZI : sve_int_dup_imm<"dup">;
defm FDUP_ZI : sve_int_dup_fpimm<"fdup">;
defm DUPM_ZI : sve_int_dup_mask_imm<"dupm">;

// continuous load with reg+immediate
Expand Down
38 changes: 38 additions & 0 deletions llvm/lib/Target/AArch64/SVEInstrFormats.td
Expand Up @@ -527,6 +527,44 @@ multiclass sve_int_dup_imm<string asm> {
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
def : InstAlias<"mov $Zd, $imm",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;

def : InstAlias<"fmov $Zd, #0.0",
(!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
def : InstAlias<"fmov $Zd, #0.0",
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
def : InstAlias<"fmov $Zd, #0.0",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
}

class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
string asm, ZPRRegOp zprty>
: I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
asm, "\t$Zd, $imm8",
"",
[]>, Sched<[]> {
bits<5> Zd;
bits<8> imm8;
let Inst{31-24} = 0b00100101;
let Inst{23-22} = sz8_64;
let Inst{21-14} = 0b11100111;
let Inst{13} = 0b0;
let Inst{12-5} = imm8;
let Inst{4-0} = Zd;

let isReMaterializable = 1;
}

multiclass sve_int_dup_fpimm<string asm> {
def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;

def : InstAlias<"fmov $Zd, $imm8",
(!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
def : InstAlias<"fmov $Zd, $imm8",
(!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
def : InstAlias<"fmov $Zd, $imm8",
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
}

class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
Expand Down
64 changes: 64 additions & 0 deletions llvm/test/MC/AArch64/SVE/fdup-diagnostics.s
@@ -0,0 +1,64 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s

// --------------------------------------------------------------------------//
// Invalid immediates

fdup z0.h, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.h, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.s, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.s, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.d, #-0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.d, #-0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.h, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.h, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.s, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.s, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.d, #-64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.d, #-64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.h, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.h, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.s, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.s, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.d, #0.05859375 // r = -4, n = 15
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.d, #0.05859375 // r = -4, n = 15
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.h, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.h, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.s, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.s, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

fdup z0.d, #64.00000000 // r = 5, n = 32
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: expected compatible register or floating-point constant
// CHECK-NEXT: fdup z0.d, #64.00000000 // r = 5, n = 32
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

0 comments on commit f95ea04

Please sign in to comment.