C test format
Overview
In order to facilitate the task of specifying tests to be reproduced/generated by Microprobe, we defined a C code environment so that the users can write down the test cases in C, and then let the compiler and the Microprobe framework to perform the code generation and all the plumbing required to make it work.
In brief, besides the actual implementation of the test case main function (named c2mpt_function), the user has to define a set of C macros so that the framework knows which variables and functions should also be included in the generated MPT. Optionally, the user can also define an initialization function, which will be called before the test case main function, to initialize the data values. The following sections explain more details about this environment.
Variable declaration and registration
The variables have to be declared and registered using a set of macros
provided by the C test environment (defined in c2mpt.h
file shown below).
This allows the environment to know which variables are required to be part of
the generated MPT.
The following macros are defined to declare variables:
DECLARE_VARIABLE(type, name, alignment)
DECLARE_VARIABLE_WITH_VALUE(type, name, alignment, init_value)
DECLARE_VARIABLE_ARRAY(type, name, name+dimension, alignment)
DECLARE_VARIABLE_ARRAY_WITH_VALUE(type, name, name+dimension alignment, init_value)
where:
type: is the variable type (e.g. char)
name: is the variable name (e.g. myvar)
name+dimension: is the name of the array and the dimensions of the array (e.g. myvar[10][20] )
alignment: is the minimum alignment for the variable
init_value: is the initial value
The following macros are defined to register the variables:
BEGIN_VARIABLE_REGISTRATION
REGISTER_VARIABLE(name)
END_VARIABLE_REGISTRATION
where:
name: is the variable name to register
Function registration
Besides the variables, the functions that need to be placed in the generated
MPT also have to be declared using special macros. Instead of using regular
fname(type1 arg1, type2 arg2, ... , type3 arg3)
function signature
declarations, the declarations should of the form MPT_FUNCTION(fname(type1
arg1, type2 arg2, ... , type3 arg3))
. That is, just wrap the function
signatures using the MPT_FUNCTION
macro.
Function implementation
After defining how to declare variables and define function signatures, one needs to provide the implementation of the following function:
void c2mpt_function()
: This is the main test function, which will be converted to the MPT format. This function can not perform library calls and it only should access to local variables (that will be placed in the stack) or global MPT register variables.void c2mpt_init_global_vars()
(optional): Use this function to initialize any global variables registered to the MPT. This function, since it is not going to be included in the generate MPT, can call any other functions and does not have any restriction.Any other subroutine called by the c2mpt_function. Again, these subroutines, like the c2mpt_function can not perform library calls or access to global variables not registered in the MPT environment.
Examples
A matrix multiply example:
1#include "c2mpt.h"
2
3/****************************************************************************/
4// Global variables
5//
6// Define in the section below the global variable to be used in the
7// "c2mpt_function" and its subroutines. Variable below are going to be
8// imported to the mpt format. The variables have to be declared first
9// and then, they have to be registered (see example below).
10//
11// The following macros are defined to declare variables:
12//
13// DECLARE_VARIABLE(type, name, alignment)
14// DECLARE_VARIABLE_WITH_VALUE(type, name, alignment, init_value)
15// DECLARE_VARIABLE_ARRAY(type, name, name+dimension, alignment)
16// DECLARE_VARIABLE_ARRAY_WITH_VALUE(type, name, name+dimension alignment, init_value)
17//
18// where:
19//
20// - type: is the variable type (e.g. char)
21// - name: is the variable name (e.g. myvar)
22// - name+dimension: is the name of the array and the dimensions of the array
23// (e.g. myvar[10][20] )
24// - alignment: is the minimum algnment for the variable
25// - init_value: is the initial value
26//
27// The following macros are defined to register the variables:
28//
29// BEGIN_VARIABLE_REGISTRATION
30// REGISTER_VARIABLE(name)
31// END_VARIABLE_REGISTRATION
32//
33// where:
34//
35// - name: is the variable name to register
36//
37/****************************************************************************/
38
39#define N 10
40
41DECLARE_VARIABLE_ARRAY(int64_t,matA,matA[N][N],sizeof(int64_t))
42DECLARE_VARIABLE_ARRAY(int64_t,matB,matB[N][N],sizeof(int64_t))
43DECLARE_VARIABLE_ARRAY_WITH_VALUE(int64_t,matC,matC[N][N],sizeof(int64_t), {[0][1]=2,[1][0]=1} )
44
45BEGIN_VARIABLE_REGISTRATION
46REGISTER_VARIABLE(matA)
47REGISTER_VARIABLE(matB)
48REGISTER_VARIABLE(matC)
49END_VARIABLE_REGISTRATION
50
51/****************************************************************************/
52// Function declaration
53//
54// Declare the functions to be converted to the MPT format. It is mandatory
55// to define a "c2mpt_function", which will be the "main" of the test. Also
56// include any related subroutines. The related subroutines have to be
57// defined using the MPT_FUNCTION(signature) macro provided.
58//
59// The function signature for the main c2mpt_function should not be modified.
60// It does not have any parameter. One can use global variables to pass parameters
61// to the function (see the example).
62//
63/****************************************************************************/
64
65MPT_FUNCTION(int64_t my_subroutine(int64_t X, int64_t Y, int64_t Z))
66
67/****************************************************************************/
68// Function implementation
69//
70// Include below the implementation of the routines defined above, which
71// should be included in the mpt. They should not call functions not defined
72// here because the test should be self-contained to be reproduced safely.
73//
74// Remember to defined the "c2mpt_function" main function.
75//
76/****************************************************************************/
77
78int64_t __attribute__ ((noinline)) my_subroutine(int64_t X, int64_t Y, int64_t Z)
79{
80 return Z + (X * Y);
81}
82
83void c2mpt_function()
84{
85 int i,j,k;
86
87 for(i=0;i<N;i++){
88 for(j=0;j<N;j++){
89 matC[i][j]=0;
90 for(k=0;k<N;k++){
91 matC[i][j]=my_subroutine(matA[i][k], matB[k][j], matC[i][j]);
92 }
93 }
94 }
95}
96
97
98/****************************************************************************/
99// Initialization function
100//
101// In case you need to initialize the global variables, you can do that in
102// the function below. This function can use any external function
103// including IO (e.g. reading values from disk) . This function will not
104// be included the mpt.
105//
106// If you initialize variable pointers, they should point to addresses of
107// variables defined to be included in the MPT.
108//
109/****************************************************************************/
110
111void c2mpt_init_global_vars()
112{
113 for(int i=0; i < N; i++){
114 for(int j=0; j < N; j++){
115 matA[i][j] = i;
116 matB[i][j] = j;
117 matC[i][j] = i+j;
118 }
119 }
120}
121
A linked list code example:
1#include "c2mpt.h"
2
3/****************************************************************************/
4// Global variables
5//
6// Define in the section below the global variable to be used in the
7// "c2mpt_function" and its subroutines. Variable below are going to be
8// imported to the mpt format. The variables have to be declared first
9// and then, they have to be registered (see example below).
10//
11// The following macros are defined to declare variables:
12//
13// DECLARE_VARIABLE(type, name, alignment)
14// DECLARE_VARIABLE_WITH_VALUE(type, name, alignment, init_value)
15// DECLARE_VARIABLE_ARRAY(type, name, name+dimension, alignment)
16// DECLARE_VARIABLE_ARRAY_WITH_VALUE(type, name, name+dimension alignment, init_value)
17//
18// where:
19//
20// - type: is the variable type (e.g. char)
21// - name: is the variable name (e.g. myvar)
22// - name+dimension: is the name of the array and the dimensions of the array
23// (e.g. myvar[10][20] )
24// - alignment: is the minimum algnment for the variable
25// - init_value: is the initial value
26//
27// The following macros are defined to register the variables:
28//
29// BEGIN_VARIABLE_REGISTRATION
30// REGISTER_VARIABLE(name)
31// END_VARIABLE_REGISTRATION
32//
33// where:
34//
35// - name: is the variable name to register
36//
37/****************************************************************************/
38
39#define N 5
40
41struct node {
42 int64_t x;
43 struct node *next;
44};
45
46typedef struct node node_t;
47node_t array[N];
48
49DECLARE_VARIABLE_ARRAY(node_t,linkedlist,linkedlist[N],sizeof(node_t))
50DECLARE_VARIABLE_WITH_VALUE(int64_t,count,sizeof(int64_t), 0xCAFECAFE)
51
52BEGIN_VARIABLE_REGISTRATION
53REGISTER_VARIABLE(count)
54REGISTER_VARIABLE(linkedlist)
55END_VARIABLE_REGISTRATION
56
57/****************************************************************************/
58// Function declaration
59//
60// Declare the functions to be converted to the MPT format. It is mandatory
61// to define a "c2mpt_function", which will be the "main" of the test. Also
62// include any related subroutines. The related subroutines have to be
63// defined using the MPT_FUNCTION(signature) macro provided.
64//
65// The function signature for the main c2mpt_function should not be modified.
66// It does not have any parameter. One can use global variables to pass parameters
67// to the function (see the example).
68//
69/****************************************************************************/
70
71MPT_FUNCTION(void my_subroutine(int64_t count))
72
73/****************************************************************************/
74// Function implementation
75//
76// Include below the implementation of the routines defined above, which
77// should be included in the mpt. They should not call functions not defined
78// here because the test should be self-contained to be reproduced safely.
79//
80// Remember to defined the "c2mpt_function" main function.
81//
82/****************************************************************************/
83
84void c2mpt_function()
85{
86
87 node_t* node = & linkedlist[0];
88 while(node->next != NULL)
89 {
90 node = node->next;
91 count += node->x;
92 }
93
94 my_subroutine(count);
95
96}
97
98void my_subroutine(int64_t lcount)
99{
100 count=lcount+lcount;
101}
102
103/****************************************************************************/
104// Initialization function
105//
106// In case you need to initialize the global variables, you can do that in
107// the function below. This function can use any external function
108// including IO (e.g. reading values from disk) . This function will not
109// be included the mpt.
110//
111// If you initialize variable pointers, they should point to addresses of
112// variables defined to be included in the MPT.
113//
114/****************************************************************************/
115
116void c2mpt_init_global_vars()
117{
118 for(int i=0; i < N; i++){
119 linkedlist[i].x = 0x0102030405060708;
120
121 if(i<N-1)
122 {
123 linkedlist[i].next = &(linkedlist[i+1]);
124 }
125 else
126 {
127 linkedlist[i].next = NULL;
128 }
129 }
130}
131
Template
Copy and paste the following template (or use the --dump-c2mpt-template
flag to get it) to start editing an empty C test format:
1#include "c2mpt.h"
2
3/****************************************************************************/
4// Global variables
5//
6// Define in the section below the global variable to be used in the
7// "c2mpt_function" and its subroutines. Variables below are going to be
8// imported to the mpt format. The variables have to be declared first
9// and then they have to be registered (see example below).
10//
11// The following macros are defined to declare variables:
12//
13// DECLARE_VARIABLE(type, name, alignment)
14// DECLARE_VARIABLE_WITH_VALUE(type, name, alignment, init_value)
15// DECLARE_VARIABLE_ARRAY(type, name, name+dimension, alignment)
16// DECLARE_VARIABLE_ARRAY_WITH_VALUE(type, name, name+dimension alignment, init_value)
17//
18// where:
19//
20// - type: is the variable type (e.g. char)
21// - name: is the variable name (e.g. myvar)
22// - name+dimension: is the name of the array and the dimensions of the array
23// (e.g. myvar[10][20] )
24// - alignment: is the minimum algnment for the variable
25// - init_value: is the initial value
26//
27// The following macros are defined to register the variables:
28//
29// BEGIN_VARIABLE_REGISTRATION
30// REGISTER_VARIABLE(name)
31// END_VARIABLE_REGISTRATION
32//
33// where:
34//
35// - name: is the variable name to register
36//
37// Example:
38//
39// #define N 10
40//
41// DECLARE_VARIABLE_ARRAY(int64_t,matA,matA[N][N],sizeof(int64_t))
42// DECLARE_VARIABLE_ARRAY(int64_t,matB,matB[N][N],sizeof(int64_t))
43// DECLARE_VARIABLE_ARRAY_WITH_VALUE(int64_t,matC,matC[N][N],sizeof(int64_t),
44// {[0][1]=2,[1][0]=1} )
45//
46// BEGIN_VARIABLE_REGISTRATION
47// REGISTER_VARIABLE(matA)
48// REGISTER_VARIABLE(matB)
49// REGISTER_VARIABLE(matC)
50// END_VARIABLE_REGISTRATION
51//
52/****************************************************************************/
53
54<< DECLARE AND REGISTER YOUR VARIABLES HERE >>
55
56/****************************************************************************/
57// Subroutine declaration
58//
59// Declare any subroutine to be included in the MPT generated using the
60// MPT_FUNCTION(signature) macro provided.
61//
62// Example:
63//
64// MPT_FUNCTION(int64_t my_subroutine(int64_t X, int64_t Y, int64_t Z))
65//
66/****************************************************************************/
67
68<< DECLARE YOUR SUBROUTINES HERE >>
69
70/****************************************************************************/
71// Function implementation
72//
73// Include below the implementation of the routines defined above, which
74// will be included in the MPT. They should not call functions that will not
75// be included in the MPT. That is, only call functions declared using the
76// MPT_FUNCTION macro.
77//
78// Remember to implement the "c2mpt_function", which will be the main test
79// function.
80//
81/****************************************************************************/
82
83void c2mpt_function()
84{
85
86 << IMPLEMENT THE MAIN FUNCTION HERE >>
87
88}
89
90<< IMPLEMENT ANY SUBROUTINES HERE >>
91
92/****************************************************************************/
93// Initialization function
94//
95// In case you need to initialize the global variables, you can do that in
96// the function below. This function can use any external function
97// including IO (e.g. reading values from disk) . This function will not
98// be included the MPT generated.
99//
100// If you initialize variable pointers, they should point to addresses of
101// variables defined to be included in the MPT.
102//
103/****************************************************************************/
104
105void c2mpt_init_global_vars()
106{
107
108 << INITIALIZE THE GLOBAL VARIABLES HERE >>
109
110}
111
Implementation details
The following two files are compiled along the C test file provided as input by the user. Check them to understand the implementation details in case you want to debug the functionality:
1#include <stdlib.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <inttypes.h>
5#include <strings.h>
6#include <string.h>
7#include <assert.h>
8
9typedef struct c2mpt_var {
10 char vartype[50];
11 char varname[50];
12 void * address;
13 uint_fast64_t nelems;
14 uint_fast64_t elems_size;
15 uint_fast64_t alignment;
16} c2mpt_var ;
17
18void c2mpt_dump_data(void);
19
20#define DECLARE_VARIABLE_ARRAY(type,name,array,alignment) \
21 type array \
22 __attribute__ ((section ("microprobe.data"))) \
23 __attribute__ ((aligned (alignment))) \
24 ; \
25 c2mpt_var c2mpt_var_##name = { #type, #name, \
26 (void * ) & name[0], \
27 sizeof(name)/ \
28 sizeof(type), \
29 alignment };
30
31#define DECLARE_VARIABLE_ARRAY_WITH_VALUE(type,name,array,alignment, ...) \
32 type array \
33 __attribute__ ((section ("microprobe.data"))) \
34 __attribute__ ((aligned (alignment))) \
35 = __VA_ARGS__; \
36 c2mpt_var c2mpt_var_##name = { #type, #name, \
37 (void * ) & name[0], \
38 sizeof(name)/ \
39 sizeof(type), \
40 alignment };
41
42#define DECLARE_VARIABLE(type,name,alignment) \
43 type name \
44 __attribute__ ((section ("microprobe.data"))) \
45 __attribute__ ((aligned (alignment))) \
46 ; \
47 c2mpt_var c2mpt_var_##name = { #type, #name, \
48 (void * ) & name, 1, \
49 sizeof(name), \
50 alignment };
51
52#define DECLARE_VARIABLE_WITH_VALUE(type,name,alignment, value) \
53 type name \
54 __attribute__ ((section ("microprobe.data"))) \
55 __attribute__ ((aligned (alignment))) \
56 = value; \
57 c2mpt_var c2mpt_var_##name = { #type, #name, \
58 (void * ) & name, 1, \
59 sizeof(name), \
60 alignment };
61
62#define BEGIN_VARIABLE_REGISTRATION \
63 c2mpt_var* c2mpt_vars[] = {
64
65#define REGISTER_VARIABLE(name) &c2mpt_var_##name,
66
67#define END_VARIABLE_REGISTRATION \
68 }; \
69 extern void c2mpt_dump_var(c2mpt_var var); \
70 MPT_DUMP_FUNCTION
71
72#define MPT_FUNCTION(signature) \
73 signature \
74 __attribute__ ((section ("microprobe.text")));
75
76MPT_FUNCTION(void c2mpt_function(void))
77
78#define MPT_DUMP_FUNCTION \
79 void c2mpt_dump_data(void) \
80 { \
81 uint_fast64_t i = 0; \
82 uint_fast64_t nvars = 0; \
83 nvars = sizeof(c2mpt_vars) / sizeof(c2mpt_vars[0]); \
84 for(i=0; i < nvars; i++) \
85 { \
86 c2mpt_dump_var(*(c2mpt_vars[i])); \
87 } \
88 } \
89
90#ifndef MPT_BASE_ADDRESS
91 #define MPT_BASE_ADDRESS 0x0
92#endif
1#include "c2mpt.h"
2
3extern c2mpt_var* c2mpt_vars;
4extern void c2mpt_function(void);
5extern void c2mpt_dump_data(void);
6extern void c2mpt_init_global_vars(void);
7
8/****************************************************************************/
9// Dump data functions
10/****************************************************************************/
11
12void c2mpt_print_value(void * value, uint_fast64_t size, char* vartype)
13{
14 // pointers
15 if(index(vartype, '*') != NULL)
16 {
17 assert(size == sizeof(void *));
18 printf("%p", value);
19 }
20 // C generic data types
21 else if(strcasecmp(vartype, "char") == 0)
22 {
23 assert(size == sizeof(char));
24 printf("%hhu", *((char *) value));
25 }
26 else if(strcasecmp(vartype, "signed char") == 0)
27 {
28 assert(size == sizeof(signed char));
29 printf("%hhi", *((signed char *) value));
30 }
31 else if(strcasecmp(vartype, "unsigned char") == 0)
32 {
33 assert(size == sizeof(unsigned char));
34 printf("%hhu", *((unsigned char *) value));
35 }
36 else if(strcasecmp(vartype, "short") == 0)
37 {
38 assert(size == sizeof(short));
39 printf("%hi", *((short *) value));
40 }
41 else if(strcasecmp(vartype, "short int") == 0)
42 {
43 assert(size == sizeof(short int));
44 printf("%hi", *((short int *) value));
45 }
46 else if(strcasecmp(vartype, "signed short") == 0)
47 {
48 assert(size == sizeof(signed short));
49 printf("%hi", *((signed short *) value));
50 }
51 else if(strcasecmp(vartype, "signed short int") == 0)
52 {
53 assert(size == sizeof(signed short int));
54 printf("%hi", *((signed short int *) value));
55 }
56 else if(strcasecmp(vartype, "unsigned short") == 0)
57 {
58 assert(size == sizeof(unsigned short));
59 printf("%hu", *((unsigned short *) value));
60 }
61 else if(strcasecmp(vartype, "unsigned short int") == 0)
62 {
63 assert(size == sizeof(unsigned short int));
64 printf("%hu", *((unsigned short int *) value));
65 }
66 else if(strcasecmp(vartype, "int") == 0)
67 {
68 assert(size == sizeof(int));
69 printf("%d", *((int *) value));
70 }
71 else if(strcasecmp(vartype, "signed") == 0)
72 {
73 assert(size == sizeof(signed));
74 printf("%d", *((signed *) value));
75 }
76 else if(strcasecmp(vartype, "signed int") == 0)
77 {
78 assert(size == sizeof(signed int));
79 printf("%d", *((signed int *) value));
80 }
81 else if(strcasecmp(vartype, "unsigned") == 0)
82 {
83 assert(size == sizeof(unsigned));
84 printf("%u", *((unsigned *) value));
85 }
86 else if(strcasecmp(vartype, "unsigned int") == 0)
87 {
88 assert(size == sizeof(unsigned int));
89 printf("%u", *((unsigned int *) value));
90 }
91 else if(strcasecmp(vartype, "long") == 0)
92 {
93 assert(size == sizeof(long));
94 printf("%li", *((long *) value));
95 }
96 else if(strcasecmp(vartype, "long int") == 0)
97 {
98 assert(size == sizeof(long int));
99 printf("%li", *((long int *) value));
100 }
101 else if(strcasecmp(vartype, "signed long") == 0)
102 {
103 assert(size == sizeof(signed long));
104 printf("%li", *((signed long *) value));
105 }
106 else if(strcasecmp(vartype, "signed long int") == 0)
107 {
108 assert(size == sizeof(signed long int));
109 printf("%li", *((signed long int *) value));
110 }
111 else if(strcasecmp(vartype, "unsigned long") == 0)
112 {
113 assert(size == sizeof(unsigned long));
114 printf("%lu", *((unsigned long *) value));
115 }
116 else if(strcasecmp(vartype, "unsigned long int") == 0)
117 {
118 assert(size == sizeof(unsigned long int));
119 printf("%lu", *((unsigned long int *) value));
120 }
121 else if(strcasecmp(vartype, "long long") == 0)
122 {
123 assert(size == sizeof(long long));
124 printf("%lli", *((long long *) value));
125 }
126 else if(strcasecmp(vartype, "long long int") == 0)
127 {
128 assert(size == sizeof(long long int));
129 printf("%lli", *((long long int *) value));
130 }
131 else if(strcasecmp(vartype, "signed long long") == 0)
132 {
133 assert(size == sizeof(signed long long));
134 printf("%lli", *((signed long long *) value));
135 }
136 else if(strcasecmp(vartype, "signed long long int") == 0)
137 {
138 assert(size == sizeof(signed long long int));
139 printf("%lli", *((signed long long int *) value));
140 }
141 else if(strcasecmp(vartype, "float") == 0)
142 {
143 assert(size == sizeof(float));
144 printf("%f", *((float *) value));
145 }
146 else if(strcasecmp(vartype, "double") == 0)
147 {
148 assert(size == sizeof(double));
149 printf("%f", *((double *) value));
150 }
151 else if(strcasecmp(vartype, "long double") == 0)
152 {
153 assert(size == sizeof(long double));
154 printf("%Lf", *((long double *) value));
155 }
156 // C width fixed data types
157 else if(strcasecmp(vartype, "int8_t") == 0)
158 {
159 assert(size == sizeof(int8_t));
160 printf("%hhi", *((int8_t *) value));
161 }
162 else if(strcasecmp(vartype, "int_least8_t") == 0)
163 {
164 assert(size == sizeof(int_least8_t));
165 printf("%"PRIdLEAST8, *((int_least8_t *) value));
166 }
167 else if(strcasecmp(vartype, "int_fast8_t") == 0)
168 {
169 assert(size == sizeof(int_fast8_t));
170 printf("%"PRIdFAST8, *((int_fast8_t *) value));
171 }
172 else if(strcasecmp(vartype, "uint8_t") == 0)
173 {
174 assert(size == sizeof(uint8_t));
175 printf("%hhu", *((uint8_t *) value));
176 }
177 else if(strcasecmp(vartype, "uint_least8_t") == 0)
178 {
179 assert(size == sizeof(uint_least8_t));
180 printf("%"PRIuLEAST8, *((uint_least8_t *) value));
181 }
182 else if(strcasecmp(vartype, "uint_fast8_t") == 0)
183 {
184 assert(size == sizeof(uint_fast8_t));
185 printf("%"PRIuFAST8, *((uint_fast8_t *) value));
186 }
187 else if(strcasecmp(vartype, "int16_t") == 0)
188 {
189 assert(size == sizeof(int16_t));
190 printf("%hi", *((int16_t *) value));
191 }
192 else if(strcasecmp(vartype, "int_least16_t") == 0)
193 {
194 assert(size == sizeof(int_least16_t));
195 printf("%"PRIdLEAST16, *((int_least16_t *) value));
196 }
197 else if(strcasecmp(vartype, "int_fast16_t") == 0)
198 {
199 assert(size == sizeof(int_fast16_t));
200 printf("%"PRIdFAST16, *((int_fast16_t *) value));
201 }
202 else if(strcasecmp(vartype, "uint16_t") == 0)
203 {
204 assert(size == sizeof(uint16_t));
205 printf("%hu", *((uint16_t *) value));
206 }
207 else if(strcasecmp(vartype, "uint_least16_t") == 0)
208 {
209 assert(size == sizeof(uint_least16_t));
210 printf("%"PRIuLEAST16, *((uint_least16_t *) value));
211 }
212 else if(strcasecmp(vartype, "uint_fast16_t") == 0)
213 {
214 assert(size == sizeof(uint_fast16_t));
215 printf("%"PRIuFAST16, *((uint_fast16_t *) value));
216 }
217 else if(strcasecmp(vartype, "int32_t") == 0)
218 {
219 assert(size == sizeof(int32_t));
220 printf("%d", *((int32_t *) value));
221 }
222 else if(strcasecmp(vartype, "int_least32_t") == 0)
223 {
224 assert(size == sizeof(int_least32_t));
225 printf("%"PRIdLEAST32, *((int_least32_t *) value));
226 }
227 else if(strcasecmp(vartype, "int_fast32_t") == 0)
228 {
229 assert(size == sizeof(int_fast32_t));
230 printf("%"PRIdFAST32, *((int_fast32_t *) value));
231 }
232 else if(strcasecmp(vartype, "uint32_t") == 0)
233 {
234 assert(size == sizeof(uint32_t));
235 printf("%u", *((uint32_t *) value));
236 }
237 else if(strcasecmp(vartype, "uint_least32_t") == 0)
238 {
239 assert(size == sizeof(uint_least32_t));
240 printf("%"PRIuLEAST32, *((uint_least32_t *) value));
241 }
242 else if(strcasecmp(vartype, "uint_fast32_t") == 0)
243 {
244 assert(size == sizeof(uint_fast32_t));
245 printf("%"PRIdFAST32, *((uint_fast32_t *) value));
246 }
247 else if(strcasecmp(vartype, "int64_t") == 0)
248 {
249 assert(size == sizeof(int64_t));
250 printf("%li", *((int64_t *) value));
251 }
252 else if(strcasecmp(vartype, "int_least64_t") == 0)
253 {
254 assert(size == sizeof(int_least64_t));
255 printf("%"PRIdLEAST64, *((int_least64_t *) value));
256 }
257 else if(strcasecmp(vartype, "int_fast64_t") == 0)
258 {
259 assert(size == sizeof(int_fast64_t));
260 printf("%"PRIdFAST64, *((int_fast64_t *) value));
261 }
262 else if(strcasecmp(vartype, "uint64_t") == 0)
263 {
264 assert(size == sizeof(uint64_t));
265 printf("%lu", *((uint64_t *) value));
266 }
267 else if(strcasecmp(vartype, "uint_least64_t") == 0)
268 {
269 assert(size == sizeof(uint_least64_t));
270 printf("%"PRIuLEAST64, *((uint_least64_t *) value));
271 }
272 else if(strcasecmp(vartype, "uint_fast64_t") == 0)
273 {
274 assert(size == sizeof(uint_fast64_t));
275 printf("%"PRIuFAST64, *((uint_fast64_t *) value));
276 }
277 // Fall back to char
278 else
279 {
280 for(int i=0; i < size; i++)
281 {
282 if ((i>0) && (i < size)) printf(", ");
283 printf("%hhu", *((char *) value));
284 value = (void *) ((uint64_t) value + sizeof(char));
285 }
286 }
287
288}
289
290void c2mpt_fix_vartype(char* fix_vartype, char* vartype)
291{
292 if((index(vartype, '*') != NULL)||
293 (strcasecmp(vartype, "char") == 0)||
294 (strcasecmp(vartype, "signed char") == 0)||
295 (strcasecmp(vartype, "unsigned char") == 0)||
296 (strcasecmp(vartype, "short") == 0)||
297 (strcasecmp(vartype, "short int") == 0)||
298 (strcasecmp(vartype, "signed short") == 0)||
299 (strcasecmp(vartype, "signed short int") == 0)||
300 (strcasecmp(vartype, "unsigned short") == 0)||
301 (strcasecmp(vartype, "unsigned short int") == 0)||
302 (strcasecmp(vartype, "int") == 0)||
303 (strcasecmp(vartype, "signed") == 0)||
304 (strcasecmp(vartype, "signed int") == 0)||
305 (strcasecmp(vartype, "unsigned") == 0)||
306 (strcasecmp(vartype, "unsigned int") == 0)||
307 (strcasecmp(vartype, "long") == 0)||
308 (strcasecmp(vartype, "long int") == 0)||
309 (strcasecmp(vartype, "signed long") == 0)||
310 (strcasecmp(vartype, "signed long int") == 0)||
311 (strcasecmp(vartype, "unsigned long") == 0)||
312 (strcasecmp(vartype, "unsigned long int") == 0)||
313 (strcasecmp(vartype, "long long") == 0)||
314 (strcasecmp(vartype, "long long int") == 0)||
315 (strcasecmp(vartype, "signed long long") == 0)||
316 (strcasecmp(vartype, "signed long long int") == 0)||
317 (strcasecmp(vartype, "float") == 0)||
318 (strcasecmp(vartype, "double") == 0)||
319 (strcasecmp(vartype, "long double") == 0)||
320 (strcasecmp(vartype, "int8_t") == 0)||
321 (strcasecmp(vartype, "int_least8_t") == 0)||
322 (strcasecmp(vartype, "int_fast8_t") == 0)||
323 (strcasecmp(vartype, "uint8_t") == 0)||
324 (strcasecmp(vartype, "uint_least8_t") == 0)||
325 (strcasecmp(vartype, "uint_fast8_t") == 0)||
326 (strcasecmp(vartype, "int16_t") == 0)||
327 (strcasecmp(vartype, "int_least16_t") == 0)||
328 (strcasecmp(vartype, "int_fast16_t") == 0)||
329 (strcasecmp(vartype, "uint16_t") == 0)||
330 (strcasecmp(vartype, "uint_least16_t") == 0)||
331 (strcasecmp(vartype, "uint_fast16_t") == 0)||
332 (strcasecmp(vartype, "int32_t") == 0)||
333 (strcasecmp(vartype, "int_least32_t") == 0)||
334 (strcasecmp(vartype, "int_fast32_t") == 0)||
335 (strcasecmp(vartype, "uint32_t") == 0)||
336 (strcasecmp(vartype, "uint_least32_t") == 0)||
337 (strcasecmp(vartype, "uint_fast32_t") == 0)||
338 (strcasecmp(vartype, "int64_t") == 0)||
339 (strcasecmp(vartype, "int_least64_t") == 0)||
340 (strcasecmp(vartype, "int_fast64_t") == 0)||
341 (strcasecmp(vartype, "uint64_t") == 0)||
342 (strcasecmp(vartype, "uint_least64_t") == 0)||
343 (strcasecmp(vartype, "uint_fast64_t") == 0))
344 {
345 strcpy(fix_vartype, vartype);
346 }
347 else
348 {
349 strcpy(fix_vartype, "uint8_t");
350 }
351
352}
353
354
355void c2mpt_dump_var(c2mpt_var var)
356{
357 uint_fast64_t i = 0;
358 uint_fast64_t multiplier = 1;
359
360 void * cval;
361 char fix_vartype[50];
362
363 c2mpt_fix_vartype(fix_vartype, var.vartype);
364
365 if(strcasecmp(fix_vartype, var.vartype) != 0)
366 {
367 printf("WARNING: Variable '%s' is not a base type ('%s'). You might"
368 " hit endianness issues if the host and target platforms"
369 " have different endianness. Double check your initialization"
370 " data in the generated MPT file\n",
371 var.varname, var.vartype);
372 multiplier = var.elems_size;
373
374 }
375
376
377 #if __64BIT__ || __x86_64__ || __ppc64__ || __aarch64__ || __powerpc64__ || __s390x__
378 printf("%s = [ \"%s\", %"PRIu64", 0x%"PRIx64", %"PRIu64", ",
379 var.varname, fix_vartype, var.nelems * multiplier,
380 (uint64_t) var.address - (uint64_t) MPT_BASE_ADDRESS,
381 var.alignment);
382 #else
383 printf("%s = [ \"%s\", %"PRIu64", 0x%"PRIx64", %"PRIu64", ",
384 var.varname, fix_vartype, var.nelems * multiplier,
385 (uint64_t) var.address - (uint64_t) MPT_BASE_ADDRESS,
386 var.alignment);
387 #endif
388
389 if (var.nelems > 1)
390 {
391 printf("[ ");
392 }
393
394 cval = (void *) var.address;
395 for(i=0; i < var.nelems; i++)
396 {
397 if ((i>0) && (i < var.nelems)) printf(", ");
398 c2mpt_print_value(cval, var.elems_size, var.vartype);
399 cval = (void *) ((uint_fast64_t) cval + var.elems_size);
400 }
401
402 if (var.nelems > 1)
403 {
404 printf(" ]");
405 }
406
407 printf(" ]\n");
408
409}
410
411/****************************************************************************/
412// Main c2mpt function
413/****************************************************************************/
414
415int main(int argc, char** argv)
416{
417 c2mpt_init_global_vars();
418 c2mpt_dump_data();
419 c2mpt_function();
420 exit(0);
421}