llvm-6502/lib/Target/AArch64/AArch64RegisterInfo.td
Jiangning Liu 477fc628b3 Initial support for Neon scalar instructions.
Patch by Ana Pazos.

1.Added support for v1ix and v1fx types.
2.Added Scalar Pairwise Reduce instructions.
3.Added initial implementation of Scalar Arithmetic instructions.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191263 91177308-0d34-0410-b5e6-96231b3b80d8
2013-09-24 02:47:27 +00:00

180 lines
6.1 KiB
TableGen

//===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains declarations that describe the AArch64 register file
//
//===----------------------------------------------------------------------===//
let Namespace = "AArch64" in {
def sub_128 : SubRegIndex<128>;
def sub_64 : SubRegIndex<64>;
def sub_32 : SubRegIndex<32>;
def sub_16 : SubRegIndex<16>;
def sub_8 : SubRegIndex<8>;
}
// Registers are identified with 5-bit ID numbers.
class AArch64Reg<bits<16> enc, string n> : Register<n> {
let HWEncoding = enc;
let Namespace = "AArch64";
}
class AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [],
list<SubRegIndex> inds = []>
: AArch64Reg<enc, n> {
let SubRegs = subregs;
let SubRegIndices = inds;
}
//===----------------------------------------------------------------------===//
// Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp
//===----------------------------------------------------------------------===//
foreach Index = 0-30 in {
def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>;
}
def WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
def WZR : AArch64Reg<31, "wzr">;
// Could be combined with previous loop, but this way leaves w and x registers
// consecutive as LLVM register numbers, which makes for easier debugging.
foreach Index = 0-30 in {
def X#Index : AArch64RegWithSubs<Index, "x"#Index,
[!cast<Register>("W"#Index)], [sub_32]>,
DwarfRegNum<[Index]>;
}
def XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>;
def XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>;
// Most instructions treat register 31 as zero for reads and a black-hole for
// writes.
// Note that the order of registers is important for the Disassembler here:
// tablegen uses it to form MCRegisterClass::getRegister, which we assume can
// take an encoding value.
def GPR32 : RegisterClass<"AArch64", [i32], 32,
(add (sequence "W%u", 0, 30), WZR)> {
}
def GPR64 : RegisterClass<"AArch64", [i64], 64,
(add (sequence "X%u", 0, 30), XZR)> {
}
def GPR32nowzr : RegisterClass<"AArch64", [i32], 32,
(sequence "W%u", 0, 30)> {
}
def GPR64noxzr : RegisterClass<"AArch64", [i64], 64,
(sequence "X%u", 0, 30)> {
}
// For tail calls, we can't use callee-saved registers or the structure-return
// register, as they are supposed to be live across function calls and may be
// clobbered by the epilogue.
def tcGPR64 : RegisterClass<"AArch64", [i64], 64,
(add (sequence "X%u", 0, 7),
(sequence "X%u", 9, 18))> {
}
// Certain addressing-useful instructions accept sp directly. Again the order of
// registers is important to the Disassembler.
def GPR32wsp : RegisterClass<"AArch64", [i32], 32,
(add (sequence "W%u", 0, 30), WSP)> {
}
def GPR64xsp : RegisterClass<"AArch64", [i64], 64,
(add (sequence "X%u", 0, 30), XSP)> {
}
// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and
// non-SP variants). We can't use a bare register in those patterns because
// TableGen doesn't like it, so we need a class containing just stack registers
def Rxsp : RegisterClass<"AArch64", [i64], 64,
(add XSP)> {
}
def Rwsp : RegisterClass<"AArch64", [i32], 32,
(add WSP)> {
}
//===----------------------------------------------------------------------===//
// Scalar registers in the vector unit:
// b0-b31, h0-h31, s0-s31, d0-d31, q0-q31
//===----------------------------------------------------------------------===//
foreach Index = 0-31 in {
def B # Index : AArch64Reg< Index, "b" # Index>,
DwarfRegNum<[!add(Index, 64)]>;
def H # Index : AArch64RegWithSubs<Index, "h" # Index,
[!cast<Register>("B" # Index)], [sub_8]>,
DwarfRegNum<[!add(Index, 64)]>;
def S # Index : AArch64RegWithSubs<Index, "s" # Index,
[!cast<Register>("H" # Index)], [sub_16]>,
DwarfRegNum<[!add(Index, 64)]>;
def D # Index : AArch64RegWithSubs<Index, "d" # Index,
[!cast<Register>("S" # Index)], [sub_32]>,
DwarfRegNum<[!add(Index, 64)]>;
def Q # Index : AArch64RegWithSubs<Index, "q" # Index,
[!cast<Register>("D" # Index)], [sub_64]>,
DwarfRegNum<[!add(Index, 64)]>;
}
def FPR8 : RegisterClass<"AArch64", [i8, v1i8], 8,
(sequence "B%u", 0, 31)> {
}
def FPR16 : RegisterClass<"AArch64", [f16, v1i16], 16,
(sequence "H%u", 0, 31)> {
}
def FPR32 : RegisterClass<"AArch64", [f32, v1i32, v1f32], 32,
(sequence "S%u", 0, 31)> {
}
def FPR64 : RegisterClass<"AArch64", [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64],
64, (sequence "D%u", 0, 31)>;
def FPR128 : RegisterClass<"AArch64",
[f128,v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128,
(sequence "Q%u", 0, 31)>;
//===----------------------------------------------------------------------===//
// Vector registers:
//===----------------------------------------------------------------------===//
def VPR64AsmOperand : AsmOperandClass {
let Name = "VPR";
let PredicateMethod = "isReg";
let RenderMethod = "addRegOperands";
}
def VPR64 : RegisterOperand<FPR64, "printVPRRegister">;
def VPR128 : RegisterOperand<FPR128, "printVPRRegister">;
// Flags register
def NZCV : Register<"nzcv"> {
let Namespace = "AArch64";
}
def FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
let CopyCost = -1;
let isAllocatable = 0;
}