Difference between revisions of "NaplesPUCallingConv.td"

From NaplesPU Documentation
Jump to: navigation, search
(Created page with "This file describes the conventions to use when a function is called, such as how to pass the arguments and how to return the function results. == Arguments passing == The n...")
 
 
(15 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This file describes the conventions to use when a function is called, such as how to pass the arguments and how to return the function results.  
+
[[Category:Tablegen Files]]
 +
This file describes the conventions to use when a function is called, such as how to pass the arguments and how to return the function results.
  
== Arguments passing ==
+
<syntaxhighlight>
The nu+ architecture natively supports 32-bit scalar integers (i32), 64-bit scalar integers (i64), 32-bit vector integers (v16i32), 64-bit vector integers (v8i64), 32-bit scalar floating-point (f32), 64-bit scalar floating-point (f64), 32-bit vector floating-point (v16f32) and  64-bit vector floating-point (v8f32).  
+
//===-- NaplesPUCallingConv.td - Calling Conventions NaplesPU ----*- tablegen -*-===//
 +
//
 +
//                    The LLVM Compiler Infrastructure
 +
//
 +
// This file is distributed under the University of Illinois Open Source
 +
// License. See LICENSE.TXT for details.
 +
//
 +
//===----------------------------------------------------------------------===//
 +
//
 +
// This describes the calling conventions for the NaplesPU architectures.
 +
//
 +
//===----------------------------------------------------------------------===//
  
The convention is to use the first '''eight''' register to pass arguments of the types listed above. For example, given the function foo
+
def CC_NaplesPU32 : CallingConv<[
  
<syntaxhighlight lang="c" line='line'>
+
  // i1, i8 and i16 integers are promoted to i32 by the caller.
void foo (int a, long long int b, vec16f32 c);
+
  CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
</syntaxhighlight>
+
 
 +
  CCIfType<[v16i8, v16i16], CCPromoteToType<v16i32>>,
 +
  CCIfType<[v8i8, v8i16, v8i32], CCPromoteToType<v8i64>>,
 +
 
 +
  // i32 f32 arguments get passed in integer registers if there is space.
 +
  CCIfNotVarArg<CCIfType<[i32, f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7]>>>,
  
the variable '''a''' will be passed using the register '''s0''', '''b''' using '''s2_s3''' and '''c''' will be stored in '''v0'''.
+
    // Vector arguments can be passed in their own registers, as above
If there are no registers available the variables will be passed using the stack.
+
  CCIfNotVarArg<CCIfType<[v16i32, v16f32], CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>>,
  
The non-native data-types are passed the same way as the native ones, however they are first extended to the nearest native data-type then they are passed using the convention discussed before.
+
  // Stick remaining registers onto stack, aligned by size
 +
  CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
 +
  CCIfType<[v16i32, v16f32], CCAssignToStack<64, 64>>
 +
]>;
  
The description is done using the tablegen classes contained in "compiler/include/llvm/Target/TargetCallingConv.td". The most used are '''CCIfType''',  
+
def RetCC_NaplesPU32 : CallingConv<[
'''CCPromoteToType''', '''CCAssignToReg''', '''CCAssignToStack''' and '''CCIfNotVarArg'''.
+
  CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
  
The following code shows how the conventions for the i8, i16, i32 and f32 are described.
+
  CCIfType<[i32, f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5]>>,
  
<syntaxhighlight lang="c" line='line'>
+
  CCIfType<[v16i8, v16i16], CCPromoteToType<v16i32>>,
...
 
CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,
 
...
 
CCIfNotVarArg<CCIfType<[i32, f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7]>>>,
 
...
 
CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
 
...
 
</syntaxhighlight>
 
  
Note that the registers in "CCAssignToReg" are the same defined in [[NuPlusRegisterInfo.td]].
+
  CCIfType<[v16i32, v16f32], CCAssignToReg<[V0, V1, V2, V3, V4, V5]>>
 +
]>;
  
== Results returning ==
+
//Callee only needs to save the callee-save registers that are used in the body of its subroutine.
 +
def NaplesPUCSR : CalleeSavedRegs<(add (sequence "S%u", 50, 57), MR_REG, FP_REG, RA_REG,
 +
                              (sequence "V%u", 56, 63))>;
 +
</syntaxhighlight>

Latest revision as of 15:58, 21 June 2019

This file describes the conventions to use when a function is called, such as how to pass the arguments and how to return the function results.

//===-- NaplesPUCallingConv.td - Calling Conventions NaplesPU ----*- tablegen -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This describes the calling conventions for the NaplesPU architectures.
//
//===----------------------------------------------------------------------===//

def CC_NaplesPU32 : CallingConv<[

  // i1, i8 and i16 integers are promoted to i32 by the caller.
  CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

  CCIfType<[v16i8, v16i16], CCPromoteToType<v16i32>>,
  CCIfType<[v8i8, v8i16, v8i32], CCPromoteToType<v8i64>>,

  // i32 f32 arguments get passed in integer registers if there is space.
  CCIfNotVarArg<CCIfType<[i32, f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5, S6, S7]>>>,

    // Vector arguments can be passed in their own registers, as above
  CCIfNotVarArg<CCIfType<[v16i32, v16f32], CCAssignToReg<[V0, V1, V2, V3, V4, V5, V6, V7]>>>,

  // Stick remaining registers onto stack, aligned by size
  CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
  CCIfType<[v16i32, v16f32], CCAssignToStack<64, 64>>
]>;

def RetCC_NaplesPU32 : CallingConv<[
  CCIfType<[i1, i8, i16], CCPromoteToType<i32>>,

  CCIfType<[i32, f32], CCAssignToReg<[S0, S1, S2, S3, S4, S5]>>,

  CCIfType<[v16i8, v16i16], CCPromoteToType<v16i32>>,

  CCIfType<[v16i32, v16f32], CCAssignToReg<[V0, V1, V2, V3, V4, V5]>>
]>;

//Callee only needs to save the callee-save registers that are used in the body of its subroutine.
def NaplesPUCSR : CalleeSavedRegs<(add (sequence "S%u", 50, 57), MR_REG, FP_REG, RA_REG,
                               (sequence "V%u", 56, 63))>;