| /** |
| * Copyright (c) 2020 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 org.eclipse.app4mc.amalthea.model.impl.DiscreteValueConstantImpl; |
| import org.eclipse.app4mc.amalthea.model.impl.DiscreteValueStatisticsImpl; |
| import org.eclipse.app4mc.slg.config.ConfigModel; |
| import org.eclipse.app4mc.slg.config.TickType; |
| import org.eclipse.app4mc.transformation.util.OutputBuffer; |
| import org.eclipse.xtend2.lib.StringConcatenation; |
| import org.eclipse.xtext.xbase.lib.Conversions; |
| import org.eclipse.xtext.xbase.lib.IntegerRange; |
| import org.eclipse.xtext.xbase.lib.IterableExtensions; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.google.common.base.Objects; |
| |
| public class TicksUtilsTranslationUnit extends TranslationUnit { |
| private static final Logger LOG = LoggerFactory.getLogger(TicksUtilsTranslationUnit.class); |
| |
| public static String getModulePathStatic() { |
| return "synthetic_gen" + "/" + getModuleNameStatic(); |
| } |
| |
| public static String getMakeFilePathStatic() { |
| return getModulePathStatic() + "/" + "CMakeLists.txt"; |
| } |
| |
| public static String getModuleNameStatic() { |
| return "ticksUtils"; |
| } |
| |
| public static String getLibName() { |
| return "TICKS_UTILS"; |
| } |
| |
| public String getModuleName() { |
| return TicksUtilsTranslationUnit.getModuleNameStatic(); |
| } |
| |
| public CharSequence getExecCall(final String params) { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("executeTicks_"); |
| String _last = IterableExtensions |
| .<String>last(((Iterable<String>) Conversions.doWrapArray(this.valueClass.toString().split("\\.")))); |
| _builder.append(_last); |
| _builder.append("("); |
| _builder.append(params); |
| _builder.append(")"); |
| return _builder; |
| } |
| |
| public String getIncFile() { |
| return this.getModuleName() + ".h"; |
| } |
| |
| private final ConfigModel configModel; |
| |
| private final Object valueClass; |
| |
| private OutputBuffer outputBuffer; |
| |
| public TicksUtilsTranslationUnit(final OutputBuffer outputBuffer, final ConfigModel configModel, |
| final Object valueClass) { |
| super(); |
| this.configModel = configModel; |
| this.valueClass = valueClass; |
| this.outputBuffer = outputBuffer; |
| this.genFiles(); |
| } |
| |
| public boolean genFiles() { |
| boolean _xblockexpression = false; |
| { |
| boolean _isIncFileEmpty = this.isIncFileEmpty(); |
| if (_isIncFileEmpty) { |
| this.toH(); |
| } |
| boolean _isSrcFileEmpty = this.isSrcFileEmpty(); |
| if (_isSrcFileEmpty) { |
| this.toCPP(); |
| } |
| this.srcAppend(this.generateTicks(this.valueClass)); |
| _xblockexpression = this.incAppend(this.generateTicksDecleration(this.valueClass)); |
| } |
| return _xblockexpression; |
| } |
| |
| private boolean toCPP() { |
| boolean _xblockexpression = false; |
| { |
| String _incFile = this.getIncFile(); |
| String _plus = ("#include \"" + _incFile); |
| String _plus_1 = (_plus + "\"\n"); |
| this.srcAppend(_plus_1); |
| final String ticksCodeSnippet = this.configModel.getCustomTickImpl().getValue(); |
| String _xifexpression = null; |
| boolean _isEnable = this.configModel.getCustomTickImpl().isEnable(); |
| if (_isEnable) { |
| _xifexpression = ticksCodeSnippet; |
| } else { |
| _xifexpression = this.burnTicksDefault().toString(); |
| } |
| final String burnTicksBody = _xifexpression; |
| this.srcAppend(this.burnTicks(burnTicksBody).toString()); |
| _xblockexpression = this.srcAppend(this.burnTicksStatistics(this.configModel).toString()); |
| } |
| return _xblockexpression; |
| } |
| |
| private boolean toH() { |
| boolean _xblockexpression = false; |
| { |
| this.incAppend(this.burnTicksDecleration().toString()); |
| _xblockexpression = this.incAppend(this.burnTicksStatisticsDecleration().toString()); |
| } |
| return _xblockexpression; |
| } |
| |
| private String generateTicks(final Object valueClass) { |
| String _switchResult = null; |
| boolean _matched = false; |
| if (Objects.equal(valueClass, DiscreteValueConstantImpl.class)) { |
| _matched = true; |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("void "); |
| CharSequence _execCall = this.getExecCall("int ticks"); |
| _builder.append(_execCall); |
| _builder.append(" {"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("\t"); |
| _builder.append("burnTicks(ticks);"); |
| _builder.newLine(); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.newLine(); |
| _switchResult = _builder.toString(); |
| } |
| if (!_matched) { |
| if (Objects.equal(valueClass, DiscreteValueStatisticsImpl.class)) { |
| _matched = true; |
| StringConcatenation _builder_1 = new StringConcatenation(); |
| _builder_1.append("void "); |
| CharSequence _execCall_1 = this.getExecCall("double average, int lowerBound, int upperBound"); |
| _builder_1.append(_execCall_1); |
| _builder_1.append(" {"); |
| _builder_1.newLineIfNotEmpty(); |
| _builder_1.append("\t"); |
| _builder_1.append("burnTicksStatistics(average, lowerBound, upperBound);"); |
| _builder_1.newLine(); |
| _builder_1.append("}"); |
| _builder_1.newLine(); |
| _builder_1.newLine(); |
| _switchResult = _builder_1.toString(); |
| } |
| } |
| if (!_matched) { |
| String _xblockexpression = null; |
| { |
| String _string = valueClass.toString(); |
| String _plus = ("Unsupported ticks type is used : " + _string); |
| TicksUtilsTranslationUnit.LOG.error(_plus); |
| _xblockexpression = ""; |
| } |
| _switchResult = _xblockexpression; |
| } |
| return _switchResult; |
| } |
| |
| private CharSequence burnTicks(final String burnTicksBody) { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("void burnTicks(int ticks) {"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append(burnTicksBody, "\t"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.newLine(); |
| return _builder; |
| } |
| |
| private String chooseTicks(final ConfigModel configModel) { |
| String _switchResult = null; |
| TickType _defaultTickType = configModel.getDefaultTickType(); |
| if (_defaultTickType != null) { |
| switch (_defaultTickType) { |
| case MINIMUM: |
| _switchResult = "lowerBound"; |
| break; |
| case MAXIMUM: |
| _switchResult = "upperBound"; |
| break; |
| case AVERAGE: |
| _switchResult = "(int)average"; |
| break; |
| default: |
| _switchResult = "(int)average"; |
| break; |
| } |
| } else { |
| _switchResult = "(int)average"; |
| } |
| return _switchResult; |
| } |
| |
| private CharSequence burnTicksStatistics(final ConfigModel configModel) { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("void burnTicksStatistics(double average, int lowerBound, int upperBound) {"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("burnTicks("); |
| String _chooseTicks = this.chooseTicks(configModel); |
| _builder.append(_chooseTicks, "\t"); |
| _builder.append(");"); |
| _builder.newLineIfNotEmpty(); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.newLine(); |
| return _builder; |
| } |
| |
| private CharSequence burnTicksDefault() { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("\t"); |
| _builder.append("// default implementation of tick burning"); |
| _builder.newLine(); |
| _builder.append("\t"); |
| _builder.append("int numLoops = ticks / 400; "); |
| _builder.newLine(); |
| _builder.append("#\tif defined (__x86_64__)"); |
| _builder.newLine(); |
| _builder.append(" \t"); |
| _builder.append("for (int i = 0; i < numLoops; i++) {"); |
| _builder.newLine(); |
| { |
| IntegerRange _upTo = new IntegerRange(1, 400); |
| for (final Integer i : _upTo) { |
| _builder.append(" \t\t"); |
| _builder.append("__asm volatile(\"nop\");"); |
| _builder.newLine(); |
| } |
| } |
| _builder.append(" \t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("#\telif defined (__x86_32__) \t\t"); |
| _builder.newLine(); |
| _builder.append(" \t\t"); |
| _builder.append("for (int i = 0; i < numLoops; i++) {"); |
| _builder.newLine(); |
| { |
| IntegerRange _upTo_1 = new IntegerRange(1, 400); |
| for (final Integer i_1 : _upTo_1) { |
| _builder.append(" \t\t\t \t"); |
| _builder.append("__asm volatile(\"mov r0, r0\");"); |
| _builder.newLine(); |
| } |
| } |
| _builder.append(" \t\t\t\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("#\telif defined (__aarch64__) \t\t"); |
| _builder.newLine(); |
| _builder.append(" \t"); |
| _builder.append("for (int i = 0; i < numLoops; i++) {"); |
| _builder.newLine(); |
| { |
| IntegerRange _upTo_2 = new IntegerRange(1, 400); |
| for (final Integer i_2 : _upTo_2) { |
| _builder.append(" \t"); |
| _builder.append("__asm volatile(\"mov x0, x0\");"); |
| _builder.newLine(); |
| } |
| } |
| _builder.append("\t"); |
| _builder.append("}"); |
| _builder.newLine(); |
| _builder.append("#\tendif"); |
| _builder.newLine(); |
| return _builder; |
| } |
| |
| private CharSequence burnTicksDecleration() { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("void burnTicks(int ticks);"); |
| _builder.newLine(); |
| _builder.newLine(); |
| return _builder; |
| } |
| |
| private CharSequence burnTicksStatisticsDecleration() { |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("void burnTicksStatistics(double average, int lowerBound, int upperBound);"); |
| _builder.newLine(); |
| _builder.newLine(); |
| return _builder; |
| } |
| |
| private String generateTicksDecleration(final Object valueClass) { |
| String _switchResult = null; |
| boolean _matched = false; |
| if (Objects.equal(valueClass, DiscreteValueConstantImpl.class)) { |
| _matched = true; |
| StringConcatenation _builder = new StringConcatenation(); |
| _builder.append("void "); |
| CharSequence _execCall = this.getExecCall("int ticks"); |
| _builder.append(_execCall); |
| _builder.append(";"); |
| _builder.newLineIfNotEmpty(); |
| _builder.newLine(); |
| _switchResult = _builder.toString(); |
| } |
| if (!_matched) { |
| if (Objects.equal(valueClass, DiscreteValueStatisticsImpl.class)) { |
| _matched = true; |
| StringConcatenation _builder_1 = new StringConcatenation(); |
| _builder_1.append("void "); |
| CharSequence _execCall_1 = this.getExecCall("double average, int lowerBound, int upperBound"); |
| _builder_1.append(_execCall_1); |
| _builder_1.append(";"); |
| _builder_1.newLineIfNotEmpty(); |
| _builder_1.newLine(); |
| _switchResult = _builder_1.toString(); |
| } |
| } |
| if (!_matched) { |
| String _xblockexpression = null; |
| { |
| String _string = valueClass.toString(); |
| String _plus = ("Unsupported ticks type is used : " + _string); |
| TicksUtilsTranslationUnit.LOG.error(_plus); |
| _xblockexpression = ""; |
| } |
| _switchResult = _xblockexpression; |
| } |
| return _switchResult; |
| } |
| |
| public String getBasePath() { |
| return "synthetic_gen"; |
| } |
| |
| public String getModulePath() { |
| String _basePath = this.getBasePath(); |
| String _plus = (_basePath + "/"); |
| String _moduleName = this.getModuleName(); |
| return (_plus + _moduleName); |
| } |
| |
| @Override |
| public String getSrcFile() { |
| String _moduleName = this.getModuleName(); |
| return (_moduleName + ".cpp"); |
| } |
| |
| public String getIncPath() { |
| String _modulePath = this.getModulePath(); |
| String _plus = (_modulePath + "/_inc/"); |
| String _incFile = this.getIncFile(); |
| return (_plus + _incFile); |
| } |
| |
| public String getSrcPath() { |
| String _modulePath = this.getModulePath(); |
| String _plus = (_modulePath + "/_src/"); |
| String _srcFile = this.getSrcFile(); |
| return (_plus + _srcFile); |
| } |
| |
| public boolean isIncFileEmpty() { |
| String _modulePath = this.getModulePath(); |
| String _plus = (_modulePath + "/_inc/"); |
| String _moduleName = this.getModuleName(); |
| String _plus_1 = (_plus + _moduleName); |
| boolean _bufferExists = this.outputBuffer.bufferExists("INC", _plus_1); |
| return (!_bufferExists); |
| } |
| |
| public boolean isSrcFileEmpty() { |
| String _modulePath = this.getModulePath(); |
| String _plus = (_modulePath + "/_src/"); |
| String _moduleName = this.getModuleName(); |
| String _plus_1 = (_plus + _moduleName); |
| boolean _bufferExists = this.outputBuffer.bufferExists("SRC", _plus_1); |
| return (!_bufferExists); |
| } |
| |
| public boolean incAppend(final String str) { |
| String _modulePath = this.getModulePath(); |
| String _plus = (_modulePath + "/_inc/"); |
| String _moduleName = this.getModuleName(); |
| String _plus_1 = (_plus + _moduleName); |
| return this.outputBuffer.appendTo("INC", _plus_1, str); |
| } |
| |
| public boolean srcAppend(final String str) { |
| String _modulePath = this.getModulePath(); |
| String _plus = (_modulePath + "/_src/"); |
| String _moduleName = this.getModuleName(); |
| String _plus_1 = (_plus + _moduleName); |
| return this.outputBuffer.appendTo("SRC", _plus_1, str); |
| } |
| } |