1480093f4SDimitry Andric//===-- VECallingConv.td - Calling Conventions VE ----------*- tablegen -*-===// 2480093f4SDimitry Andric// 3480093f4SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric// 7480093f4SDimitry Andric//===----------------------------------------------------------------------===// 8480093f4SDimitry Andric// 9480093f4SDimitry Andric// This describes the calling conventions for the VE architectures. 10480093f4SDimitry Andric// 11480093f4SDimitry Andric//===----------------------------------------------------------------------===// 12480093f4SDimitry Andric 13480093f4SDimitry Andric//===----------------------------------------------------------------------===// 14480093f4SDimitry Andric// Aurora VE 15480093f4SDimitry Andric//===----------------------------------------------------------------------===// 165ffd83dbSDimitry Andricdef CC_VE_C_Stack: CallingConv<[ 17*e8d8bef9SDimitry Andric // F128 are assigned to the stack in 16-byte aligned units 18*e8d8bef9SDimitry Andric CCIfType<[f128], CCAssignToStackWithShadow<16, 16, [SX7]>>, 195ffd83dbSDimitry Andric 205ffd83dbSDimitry Andric // All of the rest are assigned to the stack in 8-byte aligned units. 215ffd83dbSDimitry Andric CCAssignToStack<0, 8> 225ffd83dbSDimitry Andric]>; 235ffd83dbSDimitry Andric 24*e8d8bef9SDimitry Andric///// C Calling Convention (VE ABI v2.1) ///// 25*e8d8bef9SDimitry Andric// 26*e8d8bef9SDimitry Andric// Reference: https://www.nec.com/en/global/prod/hpc/aurora/document/VE-ABI_v2.1.pdf 27*e8d8bef9SDimitry Andric// 28*e8d8bef9SDimitry Andricdef CC_VE_C : CallingConv<[ 295ffd83dbSDimitry Andric // All arguments get passed in generic registers if there is space. 305ffd83dbSDimitry Andric 31*e8d8bef9SDimitry Andric // Promote i1/i8/i16/i32 arguments to i64. 32*e8d8bef9SDimitry Andric CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>, 335ffd83dbSDimitry Andric 34*e8d8bef9SDimitry Andric // Convert float arguments to i64 with padding. 35*e8d8bef9SDimitry Andric // 63 31 0 36*e8d8bef9SDimitry Andric // +------+------+ 37*e8d8bef9SDimitry Andric // | float| 0 | 38*e8d8bef9SDimitry Andric // +------+------+ 39*e8d8bef9SDimitry Andric CCIfType<[f32], CCBitConvertToType<i64>>, 405ffd83dbSDimitry Andric 41*e8d8bef9SDimitry Andric // bool, char, int, enum, long, long long, float, double 42*e8d8bef9SDimitry Andric // --> generic 64 bit registers 435ffd83dbSDimitry Andric CCIfType<[i64, f64], 445ffd83dbSDimitry Andric CCAssignToReg<[SX0, SX1, SX2, SX3, SX4, SX5, SX6, SX7]>>, 455ffd83dbSDimitry Andric 46*e8d8bef9SDimitry Andric // long double --> pair of generic 64 bit registers 47*e8d8bef9SDimitry Andric // 48*e8d8bef9SDimitry Andric // NOTE: If Q1 is allocated while SX1 is free, llvm tries to allocate SX1 for 49*e8d8bef9SDimitry Andric // following operands, this masks SX1 to avoid such behavior. 50*e8d8bef9SDimitry Andric CCIfType<[f128], 51*e8d8bef9SDimitry Andric CCAssignToRegWithShadow<[Q0, Q1, Q2, Q3], 52*e8d8bef9SDimitry Andric [SX0, SX1, SX3, SX5]>>, 53*e8d8bef9SDimitry Andric 545ffd83dbSDimitry Andric // Alternatively, they are assigned to the stack in 8-byte aligned units. 555ffd83dbSDimitry Andric CCDelegateTo<CC_VE_C_Stack> 565ffd83dbSDimitry Andric]>; 575ffd83dbSDimitry Andric 58*e8d8bef9SDimitry Andric///// Standard vararg C Calling Convention (VE ABI v2.1) ///// 595ffd83dbSDimitry Andric// All arguments get passed in stack for varargs function or non-prototyped 605ffd83dbSDimitry Andric// function. 615ffd83dbSDimitry Andricdef CC_VE2 : CallingConv<[ 62*e8d8bef9SDimitry Andric // Promote i1/i8/i16/i32 arguments to i64. 63*e8d8bef9SDimitry Andric CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>, 64*e8d8bef9SDimitry Andric 65*e8d8bef9SDimitry Andric // Convert float arguments to i64 with padding. 66*e8d8bef9SDimitry Andric // 63 31 0 675ffd83dbSDimitry Andric // +------+------+ 68*e8d8bef9SDimitry Andric // | float| 0 | 695ffd83dbSDimitry Andric // +------+------+ 70*e8d8bef9SDimitry Andric CCIfType<[f32], CCBitConvertToType<i64>>, 71*e8d8bef9SDimitry Andric 72*e8d8bef9SDimitry Andric // F128 are assigned to the stack in 16-byte aligned units 73*e8d8bef9SDimitry Andric CCIfType<[f128], CCAssignToStack<16, 16>>, 745ffd83dbSDimitry Andric 755ffd83dbSDimitry Andric CCAssignToStack<0, 8> 765ffd83dbSDimitry Andric]>; 775ffd83dbSDimitry Andric 78*e8d8bef9SDimitry Andricdef RetCC_VE_C : CallingConv<[ 79*e8d8bef9SDimitry Andric // Promote i1/i8/i16/i32 return values to i64. 80*e8d8bef9SDimitry Andric CCIfType<[i1, i8, i16, i32], CCPromoteToType<i64>>, 815ffd83dbSDimitry Andric 82*e8d8bef9SDimitry Andric // Convert float return values to i64 with padding. 83*e8d8bef9SDimitry Andric // 63 31 0 84*e8d8bef9SDimitry Andric // +------+------+ 85*e8d8bef9SDimitry Andric // | float| 0 | 86*e8d8bef9SDimitry Andric // +------+------+ 87*e8d8bef9SDimitry Andric CCIfType<[f32], CCBitConvertToType<i64>>, 885ffd83dbSDimitry Andric 89*e8d8bef9SDimitry Andric // bool, char, int, enum, long, long long, float, double 90*e8d8bef9SDimitry Andric // --> generic 64 bit registers 915ffd83dbSDimitry Andric CCIfType<[i64, f64], 925ffd83dbSDimitry Andric CCAssignToReg<[SX0, SX1, SX2, SX3, SX4, SX5, SX6, SX7]>>, 93*e8d8bef9SDimitry Andric 94*e8d8bef9SDimitry Andric // long double --> pair of generic 64 bit registers 95*e8d8bef9SDimitry Andric CCIfType<[f128], 96*e8d8bef9SDimitry Andric CCAssignToRegWithShadow<[Q0, Q1, Q2, Q3], 97*e8d8bef9SDimitry Andric [SX0, SX1, SX3, SX5]>>, 98*e8d8bef9SDimitry Andric]>; 99*e8d8bef9SDimitry Andric 100*e8d8bef9SDimitry Andric///// Custom fastcc ///// 101*e8d8bef9SDimitry Andric// 102*e8d8bef9SDimitry Andric// This passes vector params and return values in registers. Scalar values are 103*e8d8bef9SDimitry Andric// handled conforming to the standard cc. 104*e8d8bef9SDimitry Andricdef CC_VE_Fast : CallingConv<[ 105*e8d8bef9SDimitry Andric // vector --> generic vector registers 106*e8d8bef9SDimitry Andric CCIfType<[v256i32, v256f32, v256i64, v256f64], 107*e8d8bef9SDimitry Andric CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>, 108*e8d8bef9SDimitry Andric // TODO: make this conditional on packed mode 109*e8d8bef9SDimitry Andric CCIfType<[v512i32, v512f32], 110*e8d8bef9SDimitry Andric CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>, 111*e8d8bef9SDimitry Andric 112*e8d8bef9SDimitry Andric // vector mask --> generic vector mask registers 113*e8d8bef9SDimitry Andric CCIfType<[v256i1], 114*e8d8bef9SDimitry Andric CCAssignToReg<[VM1, VM2, VM3, VM4, VM5, VM6, VM7]>>, 115*e8d8bef9SDimitry Andric 116*e8d8bef9SDimitry Andric // pair of vector mask --> generic vector mask registers 117*e8d8bef9SDimitry Andric CCIfType<[v512i1], 118*e8d8bef9SDimitry Andric CCAssignToRegWithShadow<[VMP1, VMP2, VMP3], 119*e8d8bef9SDimitry Andric [VM1, VM3, VM5]>>, 120*e8d8bef9SDimitry Andric 121*e8d8bef9SDimitry Andric // Follow the standard C CC for scalars. 122*e8d8bef9SDimitry Andric CCDelegateTo<CC_VE_C> 123*e8d8bef9SDimitry Andric]>; 124*e8d8bef9SDimitry Andric 125*e8d8bef9SDimitry Andricdef RetCC_VE_Fast : CallingConv<[ 126*e8d8bef9SDimitry Andric // vector --> generic vector registers 127*e8d8bef9SDimitry Andric CCIfType<[v256i32, v256f32, v256i64, v256f64], 128*e8d8bef9SDimitry Andric CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>, 129*e8d8bef9SDimitry Andric // TODO: make this conditional on packed mode 130*e8d8bef9SDimitry Andric CCIfType<[v512i32, v512f32], 131*e8d8bef9SDimitry Andric CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>, 132*e8d8bef9SDimitry Andric 133*e8d8bef9SDimitry Andric // vector mask --> generic vector mask registers 134*e8d8bef9SDimitry Andric CCIfType<[v256i1], 135*e8d8bef9SDimitry Andric CCAssignToReg<[VM1, VM2, VM3, VM4, VM5, VM6, VM7]>>, 136*e8d8bef9SDimitry Andric 137*e8d8bef9SDimitry Andric // pair of vector mask --> generic vector mask registers 138*e8d8bef9SDimitry Andric CCIfType<[v512i1], 139*e8d8bef9SDimitry Andric CCAssignToRegWithShadow<[VMP1, VMP2, VMP3], 140*e8d8bef9SDimitry Andric [VM1, VM3, VM5]>>, 141*e8d8bef9SDimitry Andric 142*e8d8bef9SDimitry Andric // Follow the standard C CC for scalars. 143*e8d8bef9SDimitry Andric CCDelegateTo<RetCC_VE_C> 1445ffd83dbSDimitry Andric]>; 145480093f4SDimitry Andric 146480093f4SDimitry Andric// Callee-saved registers 147480093f4SDimitry Andricdef CSR : CalleeSavedRegs<(add (sequence "SX%u", 18, 33))>; 148480093f4SDimitry Andricdef CSR_NoRegs : CalleeSavedRegs<(add)>; 1495ffd83dbSDimitry Andric 1505ffd83dbSDimitry Andric// PreserveAll (clobbers s62,s63) - used for ve_grow_stack 151*e8d8bef9SDimitry Andricdef CSR_preserve_all : CalleeSavedRegs<(add (sequence "SX%u", 0, 61), 152*e8d8bef9SDimitry Andric (sequence "V%u", 0, 63), 153*e8d8bef9SDimitry Andric (sequence "VM%u", 1, 15))>; 154