Skip to content

Commit

Permalink
[ARM] Add ARMv8.2-A FP16 scalar instructions
Browse files Browse the repository at this point in the history
ARMv8.2-A adds 16-bit floating point versions of all existing VFP
floating-point instructions. This is an optional extension, so all of
these instructions require the FeatureFullFP16 subtarget feature.

The assembly for these instructions uses S registers (AArch32 does not
have H registers), but the instructions have ".f16" type specifiers
rather than ".f32" or ".f64". The top 16 bits of each source register
are ignored, and the top 16 bits of the destination register are set to
zero.

These instructions are mostly the same as the 32- and 64-bit versions,
but they use coprocessor 9 rather than 10 and 11.

Two new instructions, VMOVX and VINS, have been added to allow packing
and extracting two 16-bit floats stored in the top and bottom halves of
an S register.

New fixup kinds have been added for the PC-relative load and store
instructions, but no ELF relocations have been added as they have a
range of 512 bytes.

Differential Revision: http://reviews.llvm.org/D15038



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255762 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
ostannard committed Dec 16, 2015
1 parent 5862199 commit 8fb8da1
Show file tree
Hide file tree
Showing 18 changed files with 1,976 additions and 6 deletions.
134 changes: 134 additions & 0 deletions lib/Target/ARM/ARMInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,32 @@ class ASI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
let D = VFPNeonDomain;
}

class AHI5<bits<4> opcod1, bits<2> opcod2, dag oops, dag iops,
InstrItinClass itin,
string opc, string asm, list<dag> pattern>
: VFPI<oops, iops, AddrMode5, 4, IndexModeNone,
VFPLdStFrm, itin, opc, asm, "", pattern> {
list<Predicate> Predicates = [HasFullFP16];

// Instruction operands.
bits<5> Sd;
bits<13> addr;

// Encode instruction operands.
let Inst{23} = addr{8}; // U (add = (U == '1'))
let Inst{22} = Sd{0};
let Inst{19-16} = addr{12-9}; // Rn
let Inst{15-12} = Sd{4-1};
let Inst{7-0} = addr{7-0}; // imm8

let Inst{27-24} = opcod1;
let Inst{21-20} = opcod2;
let Inst{11-8} = 0b1001; // Half precision

// Loads & stores operate on both NEON and VFP pipelines.
let D = VFPNeonDomain;
}

// VFP Load / store multiple pseudo instructions.
class PseudoVFPLdStM<dag oops, dag iops, InstrItinClass itin, string cstr,
list<dag> pattern>
Expand Down Expand Up @@ -1817,6 +1843,114 @@ class ASbIn<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
let Inst{22} = Sd{0};
}

// Half precision, unary, predicated
class AHuI<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
bit opcod5, dag oops, dag iops, InstrItinClass itin, string opc,
string asm, list<dag> pattern>
: VFPAI<oops, iops, VFPUnaryFrm, itin, opc, asm, pattern> {
list<Predicate> Predicates = [HasFullFP16];

// Instruction operands.
bits<5> Sd;
bits<5> Sm;

// Encode instruction operands.
let Inst{3-0} = Sm{4-1};
let Inst{5} = Sm{0};
let Inst{15-12} = Sd{4-1};
let Inst{22} = Sd{0};

let Inst{27-23} = opcod1;
let Inst{21-20} = opcod2;
let Inst{19-16} = opcod3;
let Inst{11-8} = 0b1001; // Half precision
let Inst{7-6} = opcod4;
let Inst{4} = opcod5;
}

// Half precision, unary, non-predicated
class AHuInp<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4,
bit opcod5, dag oops, dag iops, InstrItinClass itin,
string asm, list<dag> pattern>
: VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
VFPUnaryFrm, itin, asm, "", pattern> {
list<Predicate> Predicates = [HasFullFP16];

// Instruction operands.
bits<5> Sd;
bits<5> Sm;

let Inst{31-28} = 0b1111;

// Encode instruction operands.
let Inst{3-0} = Sm{4-1};
let Inst{5} = Sm{0};
let Inst{15-12} = Sd{4-1};
let Inst{22} = Sd{0};

let Inst{27-23} = opcod1;
let Inst{21-20} = opcod2;
let Inst{19-16} = opcod3;
let Inst{11-8} = 0b1001; // Half precision
let Inst{7-6} = opcod4;
let Inst{4} = opcod5;
}

// Half precision, binary
class AHbI<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, dag iops,
InstrItinClass itin, string opc, string asm, list<dag> pattern>
: VFPAI<oops, iops, VFPBinaryFrm, itin, opc, asm, pattern> {
list<Predicate> Predicates = [HasFullFP16];

// Instruction operands.
bits<5> Sd;
bits<5> Sn;
bits<5> Sm;

// Encode instruction operands.
let Inst{3-0} = Sm{4-1};
let Inst{5} = Sm{0};
let Inst{19-16} = Sn{4-1};
let Inst{7} = Sn{0};
let Inst{15-12} = Sd{4-1};
let Inst{22} = Sd{0};

let Inst{27-23} = opcod1;
let Inst{21-20} = opcod2;
let Inst{11-8} = 0b1001; // Half precision
let Inst{6} = op6;
let Inst{4} = op4;
}

// Half precision, binary, not predicated
class AHbInp<bits<5> opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops,
InstrItinClass itin, string asm, list<dag> pattern>
: VFPXI<oops, iops, AddrModeNone, 4, IndexModeNone,
VFPBinaryFrm, itin, asm, "", pattern> {
list<Predicate> Predicates = [HasFullFP16];

// Instruction operands.
bits<5> Sd;
bits<5> Sn;
bits<5> Sm;

let Inst{31-28} = 0b1111;

// Encode instruction operands.
let Inst{3-0} = Sm{4-1};
let Inst{5} = Sm{0};
let Inst{19-16} = Sn{4-1};
let Inst{7} = Sn{0};
let Inst{15-12} = Sd{4-1};
let Inst{22} = Sd{0};

let Inst{27-23} = opcod1;
let Inst{21-20} = opcod2;
let Inst{11-8} = 0b1001; // Half precision
let Inst{6} = opcod3;
let Inst{4} = 0;
}

// VFP conversion instructions
class AVConv1I<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, bits<4> opcod4,
dag oops, dag iops, InstrItinClass itin, string opc, string asm,
Expand Down
15 changes: 15 additions & 0 deletions lib/Target/ARM/ARMInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,21 @@ def addrmode5_pre : AddrMode5 {
let PrintMethod = "printAddrMode5Operand<true>";
}

// addrmode5fp16 := reg +/- imm8*2
//
def AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; }
class AddrMode5FP16 : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrMode5FP16", []> {
let EncoderMethod = "getAddrMode5FP16OpValue";
let DecoderMethod = "DecodeAddrMode5FP16Operand";
let ParserMatchClass = AddrMode5FP16AsmOperand;
let MIOperandInfo = (ops GPR:$base, i32imm);
}

def addrmode5fp16 : AddrMode5FP16 {
let PrintMethod = "printAddrMode5FP16Operand<false>";
}

// addrmode6 := reg with optional alignment
//
def AddrMode6AsmOperand : AsmOperandClass { let Name = "AlignedMemory"; }
Expand Down
Loading

0 comments on commit 8fb8da1

Please sign in to comment.