xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Sparc/SparcCallingConv.td (revision f3fd488f1e19a3d09c4bdcece893901de4f49cdd)
10b57cec5SDimitry Andric//===-- SparcCallingConv.td - Calling Conventions Sparc ----*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This describes the calling conventions for the Sparc architectures.
100b57cec5SDimitry Andric//
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric// SPARC v8 32-bit.
150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric
170b57cec5SDimitry Andricdef CC_Sparc32 : CallingConv<[
180b57cec5SDimitry Andric  // Custom assign SRet to [sp+64].
190b57cec5SDimitry Andric  CCIfSRet<CCCustom<"CC_Sparc_Assign_SRet">>,
200b57cec5SDimitry Andric  // i32 f32 arguments get passed in integer registers if there is space.
210b57cec5SDimitry Andric  CCIfType<[i32, f32], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
220b57cec5SDimitry Andric  // f64 arguments are split and passed through registers or through stack.
230b57cec5SDimitry Andric  CCIfType<[f64], CCCustom<"CC_Sparc_Assign_Split_64">>,
240b57cec5SDimitry Andric  // As are v2i32 arguments (this would be the default behavior for
250b57cec5SDimitry Andric  // v2i32 if it wasn't allocated to the IntPair register-class)
260b57cec5SDimitry Andric  CCIfType<[v2i32], CCCustom<"CC_Sparc_Assign_Split_64">>,
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric  // Alternatively, they are assigned to the stack in 4-byte aligned units.
300b57cec5SDimitry Andric  CCAssignToStack<4, 4>
310b57cec5SDimitry Andric]>;
320b57cec5SDimitry Andric
330b57cec5SDimitry Andricdef RetCC_Sparc32 : CallingConv<[
340b57cec5SDimitry Andric  CCIfType<[i32], CCAssignToReg<[I0, I1, I2, I3, I4, I5]>>,
350b57cec5SDimitry Andric  CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3]>>,
360b57cec5SDimitry Andric  CCIfType<[f64], CCAssignToReg<[D0, D1]>>,
370b57cec5SDimitry Andric  CCIfType<[v2i32], CCCustom<"CC_Sparc_Assign_Ret_Split_64">>
380b57cec5SDimitry Andric]>;
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
420b57cec5SDimitry Andric// SPARC v9 64-bit.
430b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
440b57cec5SDimitry Andric//
450b57cec5SDimitry Andric// The 64-bit ABI conceptually assigns all function arguments to a parameter
460b57cec5SDimitry Andric// array starting at [%fp+BIAS+128] in the callee's stack frame. All arguments
470b57cec5SDimitry Andric// occupy a multiple of 8 bytes in the array. Integer arguments are extended to
480b57cec5SDimitry Andric// 64 bits by the caller. Floats are right-aligned in their 8-byte slot, the
490b57cec5SDimitry Andric// first 4 bytes in the slot are undefined.
500b57cec5SDimitry Andric//
510b57cec5SDimitry Andric// The integer registers %i0 to %i5 shadow the first 48 bytes of the parameter
520b57cec5SDimitry Andric// array at fixed offsets. Integer arguments are promoted to registers when
530b57cec5SDimitry Andric// possible.
540b57cec5SDimitry Andric//
550b57cec5SDimitry Andric// The floating point registers %f0 to %f31 shadow the first 128 bytes of the
560b57cec5SDimitry Andric// parameter array at fixed offsets. Float and double parameters are promoted
570b57cec5SDimitry Andric// to these registers when possible.
580b57cec5SDimitry Andric//
590b57cec5SDimitry Andric// Structs up to 16 bytes in size are passed by value. They are right-aligned
600b57cec5SDimitry Andric// in one or two 8-byte slots in the parameter array. Struct members are
610b57cec5SDimitry Andric// promoted to both floating point and integer registers when possible. A
620b57cec5SDimitry Andric// struct containing two floats would thus be passed in %f0 and %f1, while two
630b57cec5SDimitry Andric// float function arguments would occupy 8 bytes each, and be passed in %f1 and
640b57cec5SDimitry Andric// %f3.
650b57cec5SDimitry Andric//
660b57cec5SDimitry Andric// When a struct { int, float } is passed by value, the int goes in the high
670b57cec5SDimitry Andric// bits of an integer register while the float goes in a floating point
680b57cec5SDimitry Andric// register.
690b57cec5SDimitry Andric//
705ffd83dbSDimitry Andric// The difference is encoded in LLVM IR using the inreg attribute on function
710b57cec5SDimitry Andric// arguments:
720b57cec5SDimitry Andric//
730b57cec5SDimitry Andric//   C:   void f(float, float);
740b57cec5SDimitry Andric//   IR:  declare void f(float %f1, float %f3)
750b57cec5SDimitry Andric//
760b57cec5SDimitry Andric//   C:   void f(struct { float f0, f1; });
770b57cec5SDimitry Andric//   IR:  declare void f(float inreg %f0, float inreg %f1)
780b57cec5SDimitry Andric//
790b57cec5SDimitry Andric//   C:   void f(int, float);
800b57cec5SDimitry Andric//   IR:  declare void f(int signext %i0, float %f3)
810b57cec5SDimitry Andric//
820b57cec5SDimitry Andric//   C:   void f(struct { int i0high; float f1; });
830b57cec5SDimitry Andric//   IR:  declare void f(i32 inreg %i0high, float inreg %f1)
840b57cec5SDimitry Andric//
850b57cec5SDimitry Andric// Two ints in a struct are simply coerced to i64:
860b57cec5SDimitry Andric//
870b57cec5SDimitry Andric//   C:   void f(struct { int i0high, i0low; });
880b57cec5SDimitry Andric//   IR:  declare void f(i64 %i0.coerced)
890b57cec5SDimitry Andric//
900b57cec5SDimitry Andric// The frontend and backend divide the task of producing ABI compliant code for
910b57cec5SDimitry Andric// C functions. The C frontend will:
920b57cec5SDimitry Andric//
930b57cec5SDimitry Andric//  - Annotate integer arguments with zeroext or signext attributes.
940b57cec5SDimitry Andric//
950b57cec5SDimitry Andric//  - Split structs into one or two 64-bit sized chunks, or 32-bit chunks with
960b57cec5SDimitry Andric//    inreg attributes.
970b57cec5SDimitry Andric//
980b57cec5SDimitry Andric//  - Pass structs larger than 16 bytes indirectly with an explicit pointer
990b57cec5SDimitry Andric//    argument. The byval attribute is not used.
1000b57cec5SDimitry Andric//
1010b57cec5SDimitry Andric// The backend will:
1020b57cec5SDimitry Andric//
1030b57cec5SDimitry Andric//  - Assign all arguments to 64-bit aligned stack slots, 32-bits for inreg.
1040b57cec5SDimitry Andric//
1050b57cec5SDimitry Andric//  - Promote to integer or floating point registers depending on type.
1060b57cec5SDimitry Andric//
1070b57cec5SDimitry Andric// Function return values are passed exactly like function arguments, except a
1080b57cec5SDimitry Andric// struct up to 32 bytes in size can be returned in registers.
1090b57cec5SDimitry Andric
1100b57cec5SDimitry Andric// Function arguments AND most return values.
1110b57cec5SDimitry Andricdef CC_Sparc64 : CallingConv<[
1120b57cec5SDimitry Andric  // The frontend uses the inreg flag to indicate i32 and float arguments from
1130b57cec5SDimitry Andric  // structs. These arguments are not promoted to 64 bits, but they can still
1140b57cec5SDimitry Andric  // be assigned to integer and float registers.
1150b57cec5SDimitry Andric  CCIfInReg<CCIfType<[i32, f32], CCCustom<"CC_Sparc64_Half">>>,
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric  // All integers are promoted to i64 by the caller.
1180b57cec5SDimitry Andric  CCIfType<[i32], CCPromoteToType<i64>>,
1190b57cec5SDimitry Andric
1200b57cec5SDimitry Andric  // Custom assignment is required because stack space is reserved for all
1210b57cec5SDimitry Andric  // arguments whether they are passed in registers or not.
1220b57cec5SDimitry Andric  CCCustom<"CC_Sparc64_Full">
1230b57cec5SDimitry Andric]>;
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andricdef RetCC_Sparc64 : CallingConv<[
1260b57cec5SDimitry Andric  // A single f32 return value always goes in %f0. The ABI doesn't specify what
1270b57cec5SDimitry Andric  // happens to multiple f32 return values outside a struct.
128*f3fd488fSDimitry Andric  CCIfType<[f32], CCCustom<"RetCC_Sparc64_Half">>,
1290b57cec5SDimitry Andric
130*f3fd488fSDimitry Andric  // Otherwise, return values are passed exactly like arguments, except that
131*f3fd488fSDimitry Andric  // returns that are too big to fit into the registers is passed as an sret
132*f3fd488fSDimitry Andric  // instead.
133*f3fd488fSDimitry Andric  CCIfInReg<CCIfType<[i32, f32], CCCustom<"RetCC_Sparc64_Half">>>,
134*f3fd488fSDimitry Andric  CCIfType<[i32], CCPromoteToType<i64>>,
135*f3fd488fSDimitry Andric  CCCustom<"RetCC_Sparc64_Full">
1360b57cec5SDimitry Andric]>;
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andric// Callee-saved registers are handled by the register window mechanism.
1390b57cec5SDimitry Andricdef CSR : CalleeSavedRegs<(add)> {
1400b57cec5SDimitry Andric  let OtherPreserved = (add (sequence "I%u", 0, 7),
14181ad6265SDimitry Andric                            (sequence "L%u", 0, 7), O6);
1420b57cec5SDimitry Andric}
1430b57cec5SDimitry Andric
1440b57cec5SDimitry Andric// Callee-saved registers for calls with ReturnsTwice attribute.
1450b57cec5SDimitry Andricdef RTCSR : CalleeSavedRegs<(add)> {
1460b57cec5SDimitry Andric  let OtherPreserved = (add I6, I7);
1470b57cec5SDimitry Andric}
148