blob: 8fccef671c360a625af25d7ca07f633644785f5b [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2020-2021 Robert Bosch GmbH.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
********************************************************************************
*/
package org.eclipse.app4mc.slg.commons.m2t.generators
import java.util.List
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage
import org.eclipse.app4mc.slg.config.ConfigModel
import org.eclipse.app4mc.slg.config.TickType
import org.eclipse.emf.ecore.EClass
class TicksUtilsGenerator {
public static val String LIB_NAME = "TICKS_UTILS";
// Suppress default constructor
private new() {
throw new IllegalStateException("Utility class");
}
static def String toCMake(List<String> srcFiles)
'''
# «LIB_NAME» ################################################################
####
add_library(«LIB_NAME» STATIC
«FOR srcFile : srcFiles»
${CMAKE_CURRENT_LIST_DIR}/_src/«srcFile»
«ENDFOR»
)
target_include_directories(«LIB_NAME»
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/_inc/
)
'''
// ----- generate ticks -----
static def String generateTicksDeclaration(EClass eClass) {
switch eClass {
case AmaltheaPackage.eINSTANCE.discreteValueConstant: '''
void «execCall(eClass, "int ticks")»;
'''
case AmaltheaPackage.eINSTANCE.discreteValueStatistics: '''
void «execCall(eClass, "double average, int lowerBound, int upperBound")»;
'''
default: {
""
}
}
}
static def String generateTicks(EClass eClass) {
switch eClass {
case AmaltheaPackage.eINSTANCE.discreteValueConstant: '''
void «execCall(eClass, "int ticks")» {
burnTicks(ticks);
}
'''
case AmaltheaPackage.eINSTANCE.discreteValueStatistics: '''
void «execCall(eClass, "double average, int lowerBound, int upperBound")» {
burnTicksStatistics(average, lowerBound, upperBound);
}
'''
default: {
""
}
}
}
static def String execCall(EClass eClass, String params) '''executeTicks_«eClass.name»(«params»)'''
// ----- burn ticks -----
static def String burnTicksDeclaration() '''
void burnTicks(int ticks);
'''
static def String burnTicks(String burnTicksBody)
'''
void burnTicks(int ticks) {
«burnTicksBody»
}
'''
// ----- burn ticks statistics -----
static def String burnTicksStatisticsDeclaration() '''
void burnTicksStatistics(double average, int lowerBound, int upperBound);
'''
static def String burnTicksStatistics(ConfigModel configModel)
'''
void burnTicksStatistics(double average, int lowerBound, int upperBound) {
burnTicks(«chooseTicks(configModel)»);
}
'''
// select statistics parameter according to configuration model
// TODO: choose final names of configuration parameters
private static def chooseTicks(ConfigModel configModel) {
switch configModel.defaultTickType {
case TickType.MINIMUM: "lowerBound"
case TickType.MAXIMUM: "upperBound"
case TickType.AVERAGE: "(int)average"
default: "(int)average"
}
}
// ----- Default implementations -----
static def String burnTicksDefault()
'''
// default implementation of tick burning
int numLoops = ticks / 400;
# if defined (__x86_64__)
for (int i = 0; i < numLoops; i++) {
«FOR i : 1..400»
__asm volatile("nop");
«ENDFOR»
}
# elif defined (__x86_32__)
for (int i = 0; i < numLoops; i++) {
«FOR i : 1..400»
__asm volatile("mov r0, r0");
«ENDFOR»
}
# elif defined (__aarch64__)
for (int i = 0; i < numLoops; i++) {
«FOR i : 1..400»
__asm volatile("mov x0, x0");
«ENDFOR»
}
# endif
'''
}