blob: 7b139dc38d01f1dd4f394e8206cc53badf7f7ea3 [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.impl.DiscreteValueStatisticsImpl
import org.eclipse.app4mc.amalthea.model.impl.DiscreteValueConstantImpl
import org.eclipse.app4mc.slg.config.ConfigModel
import org.eclipse.app4mc.slg.config.TickType
class TicksUtilsGenerator {
// Suppress default constructor
private new() {
throw new IllegalStateException("Utility class");
}
static def String toCMake(List<String> srcFiles)
'''
# «TicksUtilsTranslationUnit.getLibName» ################################################################
####
add_library(«TicksUtilsTranslationUnit.getLibName()» STATIC
«FOR srcFile : srcFiles»
${CMAKE_CURRENT_LIST_DIR}/_src/«srcFile»
«ENDFOR»
)
target_include_directories(«TicksUtilsTranslationUnit.getLibName()»
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/_inc/
)
'''
// ----- generate ticks -----
static def String generateTicksDeclaration(Object valueClass) {
switch valueClass {
case DiscreteValueConstantImpl: '''
void «execCall(valueClass, "int ticks")»;
'''
case DiscreteValueStatisticsImpl: '''
void «execCall(valueClass, "double average, int lowerBound, int upperBound")»;
'''
default: {
""
}
}
}
static def String generateTicks(Object valueClass) {
switch valueClass {
case DiscreteValueConstantImpl: '''
void «execCall(valueClass, "int ticks")» {
burnTicks(ticks);
}
'''
case DiscreteValueStatisticsImpl: '''
void «execCall(valueClass, "double average, int lowerBound, int upperBound")» {
burnTicksStatistics(average, lowerBound, upperBound);
}
'''
default: {
""
}
}
}
private static def String execCall(Object valueClass, String params) '''executeTicks_«valueClass.toString.split("\\.").last»(«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
'''
}