new file mode 100644
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(cpugen)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -ggdb -g3")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+
+set(Boost_USE_STATIC_LIBS ON)
+find_package(
+ Boost 1.60.0
+ REQUIRED
+ COMPONENTS
+ system
+ regex)
+#set(BUILD_SHARED_LIBS OFF)
+#set(BUILD_STATIC_LIBS ON)
+add_subdirectory(tinyxml2)
+add_subdirectory(yaml-cpp)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../yaml-cpp/include
+ ${Boost_INCLUDE_DIRS}
+)
+
+add_executable(
+ cpugen
+ src/cpugen.cpp
+ src/utils.cpp
+)
+
+target_link_libraries(
+ cpugen
+ yaml-cpp
+ tinyxml2
+ ${Boost_LIBRARIES}
+)
new file mode 100644
@@ -0,0 +1,17 @@
+# CPUGEN
+## How to build
+within ```cpugen``` directory do
+```
+git clone https://github.com/leethomason/tinyxml2
+git clone https://github.com/jbeder/yaml-cpp
+mkdir build
+cd build
+cmake ..
+make
+```
+## How to use
+```
+cpugen ../cpu/avr.yaml
+xsltproc ../xsl/decode.c.xsl output.xml > ../../decode.c
+xsltproc ../xsl/translate-inst.h.xsl output.xml > ../../translate-inst.h
+```
new file mode 100644
@@ -0,0 +1,214 @@
+cpu:
+ name: avr
+ instructions:
+ - ADC:
+ opcode: 0001 11 hRr[1] Rd[5] lRr[4]
+ - ADD:
+ opcode: 0000 11 hRr[1] Rd[5] lRr[4]
+ - ADIW:
+ opcode: 1001 0110 hImm[2] Rd[2] lImm[4]
+ - AND:
+ opcode: 0010 00 hRr[1] Rd[5] lRr[4]
+ - ANDI:
+ opcode: 0111 hImm[4] Rd[4] lImm[4]
+ - ASR:
+ opcode: 1001 010 Rd[5] 0101
+ - BCLR:
+ opcode: 1001 0100 1 Bit[3] 1000
+ - BLD:
+ opcode: 1111 100 Rd[5] 0 Bit[3]
+ - BRBC:
+ opcode: 1111 01 Imm[7] Bit[3]
+ - BRBS:
+ opcode: 1111 00 Imm[7] Bit[3]
+ - BREAK:
+ opcode: 1001 0101 1001 1000
+ - BSET:
+ opcode: 1001 0100 0 Bit[3] 1000
+ - BST:
+ opcode: 1111 101 Rd[5] 0 Bit[3]
+ - CALL:
+ opcode: 1001 010 hImm[5] 111 lImm[17]
+ - CBI:
+ opcode: 1001 1000 Imm[5] Bit[3]
+ - COM:
+ opcode: 1001 010 Rd[5] 0000
+ - CP:
+ opcode: 0001 01 hRr[1] Rd[5] lRr[4]
+ - CPC:
+ opcode: 0000 01 hRr[1] Rd[5] lRr[4]
+ - CPI:
+ opcode: 0011 hImm[4] Rd[4] lImm[4]
+ - CPSE:
+ opcode: 0001 00 hRr[1] Rd[5] lRr[4]
+ - DEC:
+ opcode: 1001 010 Rd[5] 1010
+ - DES:
+ opcode: 1001 0100 Imm[4] 1011
+ - EICALL:
+ opcode: 1001 0101 0001 1001
+ - EIJMP:
+ opcode: 1001 0100 0001 1001
+ - ELPM1:
+ opcode: 1001 0101 1101 1000
+ - ELPM2:
+ opcode: 1001 000 Rd[5] 0110
+ - ELPMX:
+ opcode: 1001 000 Rd[5] 0111
+ - EOR:
+ opcode: 0010 01 hRr[1] Rd[5] lRr[4]
+ - FMUL:
+ opcode: 0000 0011 0 Rd[3] 1 Rr[3]
+ - FMULS:
+ opcode: 0000 0011 1 Rd[3] 0 Rr[3]
+ - FMULSU:
+ opcode: 0000 0011 1 Rd[3] 1 Rr[3]
+ - ICALL:
+ opcode: 1001 0101 0000 1001
+ - IJMP:
+ opcode: 1001 0100 0000 1001
+ - IN:
+ opcode: 1011 0 hImm[2] Rd[5] lImm[4]
+ - INC:
+ opcode: 1001 010 Rd[5] 0011
+ - JMP:
+ opcode: 1001 010 hImm[5] 110 lImm[17]
+ - LAC:
+ opcode: 1001 001 Rr[5] 0110
+ - LAS:
+ opcode: 1001 001 Rr[5] 0101
+ - LAT:
+ opcode: 1001 001 Rr[5] 0111
+ - LDX1:
+ opcode: 1001 000 Rd[5] 1100
+ - LDX2:
+ opcode: 1001 000 Rd[5] 1101
+ - LDX3:
+ opcode: 1001 000 Rd[5] 1110
+# - LDY1:
+# opcode: 1000 000 Rd[5] 1000
+ - LDY2:
+ opcode: 1001 000 Rd[5] 1001
+ - LDY3:
+ opcode: 1001 000 Rd[5] 1010
+ - LDDY:
+ opcode: 10 hImm[1] 0 mImm[2] 0 Rd[5] 1 lImm[3]
+# - LDZ1:
+# opcode: 1000 000 Rd[5] 0000
+ - LDZ2:
+ opcode: 1001 000 Rd[5] 0001
+ - LDZ3:
+ opcode: 1001 000 Rd[5] 0010
+ - LDDZ:
+ opcode: 10 hImm[1] 0 mImm[2] 0 Rd[5] 0 lImm[3]
+ - LDI:
+ opcode: 1110 hImm[4] Rd[4] lImm[4]
+ - LDS:
+ opcode: 1001 000 Rd[5] 0000 Imm[16]
+# - LDS16:
+# opcode: 1010 0 hImm[3] Rd[4] lImm[4]
+ - LPM1:
+ opcode: 1001 0101 1100 1000
+ - LPM2:
+ opcode: 1001 000 Rd[5] 0100
+ - LPMX:
+ opcode: 1001 000 Rd[5] 0101
+ - LSR:
+ opcode: 1001 010 Rd[5] 0110
+ - MOV:
+ opcode: 0010 11 hRr[1] Rd[5] lRr[4]
+ - MOVW:
+ opcode: 0000 0001 Rd[4] Rr[4]
+ - MUL:
+ opcode: 1001 11 hRr[1] Rd[5] lRr[4]
+ - MULS:
+ opcode: 0000 0010 Rd[4] Rr[4]
+ - MULSU:
+ opcode: 0000 0011 0 Rd[3] 0 Rr[3]
+ - NEG:
+ opcode: 1001 010 Rd[5] 0001
+ - NOP:
+ opcode: 0000 0000 0000 0000
+ - OR:
+ opcode: 0010 10 hRr[1] Rd[5] lRr[4]
+ - ORI:
+ opcode: 0110 hImm[4] Rd[4] lImm[4]
+ - OUT:
+ opcode: 1011 1 hImm[2] Rd[5] lImm[4]
+ - POP:
+ opcode: 1001 000 Rd[5] 1111
+ - PUSH:
+ opcode: 1001 001 Rd[5] 1111
+ - RCALL:
+ opcode: 1101 Imm[12]
+ - RET:
+ opcode: 1001 0101 0000 1000
+ - RETI:
+ opcode: 1001 0101 0001 1000
+ - RJMP:
+ opcode: 1100 Imm[12]
+ - ROR:
+ opcode: 1001 010 Rd[5] 0111
+ - SBC:
+ opcode: 0000 10 hRr[1] Rd[5] lRr[4]
+ - SBCI:
+ opcode: 0100 hImm[4] Rd[4] lImm[4]
+ - SBI:
+ opcode: 1001 1010 Imm[5] Bit[3]
+ - SBIC:
+ opcode: 1001 1001 Imm[5] Bit[3]
+ - SBIS:
+ opcode: 1001 1011 Imm[5] Bit[3]
+ - SBIW:
+ opcode: 1001 0111 hImm[2] Rd[2] lImm[4]
+# - SBR:
+# opcode: 0110 hImm[4] Rd[4] lImm[4]
+ - SBRC:
+ opcode: 1111 110 Rr[5] 0 Bit[3]
+ - SBRS:
+ opcode: 1111 111 Rr[5] 0 Bit[3]
+ - SLEEP:
+ opcode: 1001 0101 1000 1000
+ - SPM:
+ opcode: 1001 0101 1110 1000
+ - SPMX:
+ opcode: 1001 0101 1111 1000
+ - STX1:
+ opcode: 1001 001 Rr[5] 1100
+ - STX2:
+ opcode: 1001 001 Rr[5] 1101
+ - STX3:
+ opcode: 1001 001 Rr[5] 1110
+# - STY1:
+# opcode: 1000 001 Rd[5] 1000
+ - STY2:
+ opcode: 1001 001 Rd[5] 1001
+ - STY3:
+ opcode: 1001 001 Rd[5] 1010
+ - STDY:
+ opcode: 10 hImm[1] 0 mImm[2] 1 Rd[5] 1 lImm[3]
+# - STZ1:
+# opcode: 1000 001 Rd[5] 0000
+ - STZ2:
+ opcode: 1001 001 Rd[5] 0001
+ - STZ3:
+ opcode: 1001 001 Rd[5] 0010
+ - STDZ:
+ opcode: 10 hImm[1] 0 mImm[2] 1 Rd[5] 0 lImm[3]
+ - STS:
+ opcode: 1001 001 Rd[5] 0000 Imm[16]
+# - STS16:
+# opcode: 1010 1 hImm[3] Rd[4] lImm[4]
+ - SUB:
+ opcode: 0001 10 hRr[1] Rd[5] lRr[4]
+ - SUBI:
+ opcode: 0101 hImm[4] Rd[4] lImm[4]
+ - SWAP:
+ opcode: 1001 010 Rd[5] 0010
+# - TST:
+# opcode: 0010 00 Rd[10]
+ - WDR:
+ opcode: 1001 0101 1010 1000
+ - XCH:
+ opcode: 1001 001 Rd[5] 0100
+
new file mode 100644
@@ -0,0 +1,62 @@
+#
+# CPUGEN
+#
+# Copyright (c) 2016 Michael Rolnik
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+cmake_minimum_required(VERSION 2.8)
+
+project(cpugen)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -ggdb -g3")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+
+set(Boost_USE_STATIC_LIBS ON)
+find_package(
+ Boost 1.60.0
+ REQUIRED
+ COMPONENTS
+ system
+ regex)
+set(BUILD_SHARED_LIBS OFF)
+set(BUILD_STATIC_LIBS ON)
+add_subdirectory(../tinyxml2 ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2)
+add_subdirectory(../yaml-cpp ${CMAKE_CURRENT_BINARY_DIR}/yaml-cpp)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ ${CMAKE_CURRENT_SOURCE_DIR}/../yaml-cpp/include
+ ${Boost_INCLUDE_DIRS}
+)
+
+add_executable(
+ cpugen
+ cpugen.cpp
+ utils.cpp
+)
+
+target_link_libraries(
+ cpugen
+ yaml-cpp
+ tinyxml2_static
+ ${Boost_LIBRARIES}
+)
new file mode 100644
@@ -0,0 +1,460 @@
+/*
+ * CPUGEN
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <cstdio>
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <limits>
+#include <stdint.h>
+#include <algorithm>
+#include <iomanip>
+#include <string>
+#include <vector>
+#include <boost/regex.hpp>
+
+#include "yaml-cpp/yaml.h"
+#include "tinyxml2/tinyxml2.h"
+
+#include "utils.h"
+
+#include <boost/algorithm/string.hpp>
+
+struct inst_info_t {
+ std::string name;
+ std::string opcode;
+
+ tinyxml2::XMLElement *nodeFields;
+};
+
+struct cpu_info_t {
+ std::string name;
+ std::vector<inst_info_t * > instructions;
+};
+
+int countbits(uint64_t value)
+{
+ int counter = 0;
+ uint64_t mask = 1;
+
+ for (size_t i = 0; i < sizeof(value) * 8; ++i) {
+ if (value & mask) {
+ counter++;
+ }
+
+ mask <<= 1;
+ }
+
+ return counter;
+}
+
+int encode(uint64_t mask, uint64_t value)
+{
+ uint64_t i = 0x0000000000000001;
+ uint64_t j = 0x0000000000000001;
+ uint64_t v = 0x0000000000000000;
+
+ for (size_t it = 0; it < sizeof(value) * 8; ++it) {
+ if (mask & i) {
+ if (value & j) {
+ v |= i;
+ }
+ j <<= 1;
+ }
+
+ i <<= 1;
+ }
+
+ return v;
+}
+
+std::string num2hex(uint64_t value)
+{
+ std::ostringstream str;
+ str << "0x" << std::hex << std::setw(8) << std::setfill('0') << value;
+
+ return str.str();
+}
+
+tinyxml2::XMLDocument doc;
+
+
+void operator >> (const YAML::Node & node, inst_info_t & info)
+{
+ for (auto it = node.begin(); it != node.end(); ++it) {
+ const YAML::Node & curr = it->second;
+ std::string name = it->first.as<std::string>();
+
+ info.opcode = curr["opcode"].as<std::string>();
+
+ const char *response;
+ std::vector<std::string> fields;
+ std::string opcode = "";
+ int offset;
+ tinyxml2::XMLElement *nodeFields = doc.NewElement("fields");
+ uint32_t bitoffset = 0;
+
+ do {
+ opcode = info.opcode;
+ boost::replace_all(info.opcode, " ", " ");
+ boost::replace_all(info.opcode, "0 0", "00");
+ boost::replace_all(info.opcode, "0 1", "01");
+ boost::replace_all(info.opcode, "1 0", "10");
+ boost::replace_all(info.opcode, "1 1", "11");
+ } while (opcode != info.opcode);
+
+ boost::replace_all(info.opcode, "- -", "--");
+
+ fields = boost::split(fields, info.opcode, boost::is_any_of(" "));
+
+ opcode = "";
+ info.opcode = "";
+ unsigned f = 0;
+ for (int i = 0; i < fields.size(); i++) {
+ std::string field = fields[i];
+
+ if (field.empty()) {
+ continue;
+ }
+
+ size_t len = field.length();
+ boost::cmatch match;
+ tinyxml2::XMLElement *nodeField = doc.NewElement("field");
+
+ nodeFields->LinkEndChild(nodeField);
+
+ if (boost::regex_match(field.c_str(),
+ match,
+ boost::regex("^[01]+$"))) {
+ int length = field.length();
+
+ nodeField->SetAttribute("name", field.c_str());
+ nodeField->SetAttribute("length", length);
+ nodeField->SetAttribute("offset", bitoffset);
+
+ info.opcode += field;
+
+ bitoffset += len;
+ } else if (boost::regex_match(
+ field.c_str(),
+ match,
+ boost::regex("^[-]+$")))
+ {
+ int length = field.length();
+
+ nodeField->SetAttribute("name", "RESERVED");
+ nodeField->SetAttribute("length", length);
+ nodeField->SetAttribute("offset", bitoffset);
+
+ info.opcode += field;
+
+ bitoffset += len;
+ } else if (boost::regex_match(field.c_str(),
+ match,
+ boost::regex("^([a-zA-Z][a-zA-Z0-9]*)\\[([0-9]+)\\]"))) {
+ int length = std::atoi(match[2].first);
+ std::string name = std::string(match[1].first, match[1].second);
+
+ nodeField->SetAttribute("name", name.c_str());
+ nodeField->SetAttribute("length", length);
+ nodeField->SetAttribute("offset", bitoffset);
+
+ for (int j = 0; j < length; j++) {
+ info.opcode += 'a' + f;
+ }
+
+ f++;
+
+ bitoffset += length;
+ } else if (field == "~") {
+ /* nothing */
+ } else {
+ std::cout << "cannot parse " << name
+ << ": '" << field << "'" << std::endl;
+ exit(0);
+ }
+ }
+
+ info.nodeFields = nodeFields;
+ info.name = name;
+ }
+}
+
+void operator >> (inst_info_t & info, tinyxml2::XMLElement & node)
+{
+ node.SetAttribute("length", (unsigned)info.opcode.length());
+ node.SetAttribute("name", info.name.c_str());
+ node.SetAttribute("opcode", info.opcode.c_str());
+}
+
+void operator >> (const YAML::Node & node, cpu_info_t & cpu)
+{
+ const YAML::Node & insts = node["instructions"];
+
+ cpu.name = node["name"].as<std::string>();
+
+ for (unsigned i = 0; i < insts.size(); i++) {
+ inst_info_t *inst = new inst_info_t();
+
+ insts[i] >> (*inst);
+
+ if (inst->opcode != "" &&inst->opcode != "~") {
+ cpu.instructions.push_back(inst);
+ }
+ }
+}
+
+std::pair<size_t, size_t> getMinMaxInstructionLength(
+ std::vector<inst_info_t * > &instructions)
+{
+ size_t min = std::numeric_limits<size_t>::max();
+ size_t max = std::numeric_limits<size_t>::min();
+
+ for (size_t i = 0; i < instructions.size(); i++) {
+ inst_info_t *inst = instructions[i];
+ std::string opcode = inst->opcode;
+ size_t length = opcode.length();
+
+ if (opcode != "~") {
+ min = std::min(min, length);
+ max = std::max(max, length);
+ }
+ }
+
+ return std::make_pair(min, max);
+}
+
+uint64_t getXs(std::string const &opcode, size_t len, char chr)
+{
+ uint64_t result = 0;
+ size_t cur;
+ uint64_t bit = 1ull << (len - 1);
+
+ for (cur = 0; cur < len; cur++) {
+ if (opcode[cur] == chr) {
+ result |= bit;
+ }
+
+ bit >>= 1;
+ }
+
+ return result;
+}
+
+uint64_t get0s(std::string const &opcode, size_t len)
+{
+ return getXs(opcode, len, '0');
+}
+
+uint64_t get1s(std::string const &opcode, size_t len)
+{
+ return getXs(opcode, len, '1');
+}
+
+class InstSorter
+{
+ public:
+ InstSorter(size_t offset, size_t length)
+ : offset(offset), length(length)
+ {
+
+ }
+
+ bool operator()(inst_info_t *a, inst_info_t *b)
+ {
+ uint64_t field0;
+ uint64_t field1;
+ uint64_t fieldA;
+ uint64_t fieldB;
+
+ field0 = get0s(a->opcode, length);
+ field1 = get1s(a->opcode, length);
+ fieldA = field0 | field1;
+
+ field0 = get0s(b->opcode, length);
+ field1 = get1s(b->opcode, length);
+ fieldB = field0 | field1;
+
+ return fieldB < fieldA;
+ }
+
+ private:
+ size_t offset;
+ size_t length;
+
+};
+
+void divide(uint64_t select0, uint64_t select1,
+ std::vector<inst_info_t * > &info,
+ size_t level, tinyxml2::XMLElement *root)
+{
+ std::pair<size_t, size_t> minmaxSize;
+
+ minmaxSize = getMinMaxInstructionLength(info);
+
+ size_t minlen = minmaxSize.first;
+ size_t maxlen = minmaxSize.second;
+ size_t bits = std::min(minlen, sizeof(select0) * 8);
+ uint64_t all1 = (1ULL << bits) - 1;
+ uint64_t all0 = (1ULL << bits) - 1;
+ uint64_t allx = (1ULL << bits) - 1;
+ uint64_t diff;
+
+ for (size_t i = 0; i < info.size(); ++i) {
+ std::string opcode = info[i]->opcode;
+ uint64_t field0 = get0s(opcode, minlen);
+ uint64_t field1 = get1s(opcode, minlen);
+ uint64_t fieldx = field0 | field1;
+
+ if (opcode == "~") {
+ continue;
+ }
+ all0 &= field0;
+ all1 &= field1;
+ allx &= fieldx;
+ }
+
+ diff = allx ^ (all0 | all1);
+
+ if (diff == 0) {
+ tinyxml2::XMLElement *oopsNode = doc.NewElement("oops");
+ oopsNode->SetAttribute("bits", (unsigned)bits);
+ oopsNode->SetAttribute("maxlen", (unsigned)maxlen);
+ oopsNode->SetAttribute("allx", num2hex(allx).c_str());
+ oopsNode->SetAttribute("all0", num2hex(all0).c_str());
+ oopsNode->SetAttribute("all1", num2hex(all1).c_str());
+ oopsNode->SetAttribute("select0", num2hex(select0).c_str());
+ oopsNode->SetAttribute("select1", num2hex(select1).c_str());
+ root->LinkEndChild(oopsNode);
+
+ std::sort(info.begin(), info.end(), InstSorter(0, minlen));
+
+ for (size_t i = 0; i < info.size(); ++i) {
+ inst_info_t *inst = info[i];
+ tinyxml2::XMLElement *instNode = doc.NewElement("instruction");
+ tinyxml2::XMLElement *matchNode = doc.NewElement("match01");
+
+ uint64_t field0 = get0s(inst->opcode, minlen);
+ uint64_t field1 = get1s(inst->opcode, minlen);
+ uint64_t fieldx = field0 | field1;
+
+ root->LinkEndChild(matchNode);
+ matchNode->LinkEndChild(instNode);
+
+ matchNode->SetAttribute("mask", num2hex(fieldx).c_str());
+ matchNode->SetAttribute("value", num2hex(field1).c_str());
+
+ *inst >> *instNode;
+
+ instNode->LinkEndChild(inst->nodeFields);
+ }
+
+ return;
+ }
+
+ uint64_t bitsN = countbits(diff); /* number of meaningfull bits*/
+
+ tinyxml2::XMLElement *switchNode = doc.NewElement("switch");
+ switchNode->SetAttribute("bits", (unsigned)bits);
+ switchNode->SetAttribute("bitoffset", (unsigned)0);
+ switchNode->SetAttribute("mask", num2hex(diff).c_str());
+ root->LinkEndChild(switchNode);
+
+ /* there are at most 1 << length subsets*/
+ for (size_t s = 0; s < (1 << bitsN); ++s) {
+ std::vector<inst_info_t * > subset;
+ uint64_t index = encode(diff, s);
+
+ tinyxml2::XMLElement *caseNode = doc.NewElement("case");
+ caseNode->SetAttribute("value", num2hex(index).c_str());
+ switchNode->LinkEndChild(caseNode);
+
+ for (size_t i = 0; i < info.size(); ++i) {
+ std::string opcode = info[i]->opcode;
+ uint64_t field0 = get0s(opcode, minlen);
+ uint64_t field1 = get1s(opcode, minlen);
+
+ if (((field0 & diff) == (~index & diff))
+ && ((field1 & diff) == (index & diff))) {
+ subset.push_back(info[i]);
+ }
+ }
+
+ if (subset.size() == 1) {
+ inst_info_t *inst = subset[0];
+ tinyxml2::XMLElement *instNode = doc.NewElement("instruction");
+
+ *inst >> *instNode;
+
+ instNode->LinkEndChild(inst->nodeFields);
+
+ caseNode->LinkEndChild(instNode);
+ } else if (subset.size() > 1) {
+ /* this is a set of instructions, continue dividing*/
+ divide(select0 | (diff & ~index),
+ select1 | (diff & index),
+ subset,
+ level + 2,
+ caseNode);
+ }
+ }
+}
+
+
+void generateParser(cpu_info_t & cpu)
+{
+ tinyxml2::XMLElement *cpuNode = doc.NewElement("cpu");
+ tinyxml2::XMLElement *instNode = doc.NewElement("instructions");
+
+ cpuNode->SetAttribute("name", cpu.name.c_str());
+ cpuNode->LinkEndChild(instNode);
+
+ doc.LinkEndChild(cpuNode);
+
+ divide(0, 0, cpu.instructions, 1, instNode);
+
+ doc.SaveFile("output.xml");
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2) {
+ std::cerr << "error: usage: cpuarg [input.yaml]" << std::endl;
+ std::exit(0);
+ }
+
+ try {
+ char const *filename = argv[1];
+ std::ifstream input(filename);
+ YAML::Node doc = YAML::Load(input);
+ cpu_info_t cpu;
+
+ doc["cpu"] >> cpu;
+
+ generateParser(cpu);
+ } catch(const YAML::Exception & e) {
+ std::cerr << e.what() << "\n";
+ }
+}
+
new file mode 100644
@@ -0,0 +1,27 @@
+/*
+ * CPUGEN
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "utils.h"
+#include <sstream>
+
new file mode 100644
@@ -0,0 +1,79 @@
+/*
+ * CPUGEN
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef UTILS_H_
+#define UTILS_H_
+
+#include <string>
+#include <vector>
+#include <iostream>
+#include <iomanip>
+
+typedef std::vector<std::string> string_vector_t;
+
+std::string extract(std::string & str, std::string delimiter);
+std::string rextract(std::string & str, std::string del);
+string_vector_t split(std::string str, std::string delimeter);
+std::string join(string_vector_t const &vec, std::string delimeter);
+
+int countbits(uint64_t value);
+int encode(uint64_t mask, uint64_t value);
+std::string num2hex(uint64_t value);
+
+
+class multi
+{
+/*
+ http://www.angelikalanger.com/Articles/Cuj/05.Manipulators/Manipulators.html
+*/
+ public:
+ multi(char c, size_t n)
+ : how_many_(n)
+ , what_(c)
+ {
+ }
+
+ private:
+ const size_t how_many_;
+ const char what_;
+
+ public:
+ template <class Ostream>
+ Ostream & apply(Ostream & os) const
+ {
+ for (unsigned int i = 0; i < how_many_; ++i) {
+ os.put(what_);
+ }
+ os.flush();
+ return os;
+ }
+};
+
+template <class Ostream>
+Ostream & operator << (Ostream & os, const multi & m)
+{
+ return m.apply(os);
+}
+
+#endif
new file mode 100644
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+ CPUGEN
+
+ Copyright (c) 2016 Michael Rolnik
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
+ xmlns:func = "http://exslt.org/functions"
+ xmlns:str = "http://exslt.org/strings"
+ xmlns:mine = "mrolnik@gmail.com"
+ extension-element-prefixes="func"
+ >
+
+ <xsl:strip-space elements="*"/>
+ <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
+
+ <xsl:include href="utils.xsl"/>
+
+ <xsl:template match="/cpu/instructions">
+ <xsl:value-of select="$license" />
+ <xsl:text>
+#include <stdint.h>
+#include "translate.h"
+
+void </xsl:text><xsl:value-of select="/cpu/@name"/><xsl:text>_decode(uint32_t pc, uint32_t *l, uint32_t c, translate_function_t *t)
+{
+</xsl:text>
+ <xsl:apply-templates select="switch">
+ <xsl:with-param name="ident" ><xsl:value-of select="$tab"/></xsl:with-param>
+ </xsl:apply-templates>
+<xsl:text>
+}
+</xsl:text>
+</xsl:template>
+
+ <xsl:template match="switch">
+ <xsl:param name="ident" />
+ <xsl:if test="not (@bitoffset = ../../@bitoffset and @bits = ../../@bits)" >
+ <xsl:value-of select="concat($ident, 'uint32_t opc = extract32(c, ', @bitoffset, ', ', @bits, ');', $newline)" />
+ </xsl:if>
+ <xsl:value-of select="concat($ident, 'switch (opc & ', @mask, ') {', $newline)"/>
+ <xsl:apply-templates select="case">
+ <xsl:with-param name="ident" ><xsl:value-of select="$ident"/><xsl:value-of select="$tab"/></xsl:with-param>
+ </xsl:apply-templates>
+ <xsl:value-of select="concat($ident, '}', $newline)"/>
+ </xsl:template>
+
+ <xsl:template match="case">
+ <xsl:param name="ident" />
+
+ <xsl:value-of select="concat($ident, 'case ', @value, ': {', $newline)"/>
+ <xsl:apply-templates select="switch">
+ <xsl:with-param name="ident"><xsl:value-of select="concat($ident, $tab)"/></xsl:with-param>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="match01">
+ <xsl:with-param name="ident"><xsl:value-of select="concat($ident, $tab)"/></xsl:with-param>
+ </xsl:apply-templates>
+ <xsl:apply-templates select="instruction">
+ <xsl:with-param name="ident"><xsl:value-of select="concat($ident, $tab)"/></xsl:with-param>
+ </xsl:apply-templates>
+ <xsl:value-of select="concat($ident, $tab, 'break;', $newline)"/>
+ <xsl:value-of select="concat($ident, '}', $newline)"/>
+ </xsl:template>
+
+ <xsl:template match="instruction">
+ <xsl:param name="ident" />
+
+ <xsl:value-of select="concat($ident, '*l = ', string-length(@opcode), ';', $newline)" />
+ <xsl:value-of select="concat($ident, '*t = &', /cpu/@name, '_translate_', @name, ';', $newline)" />
+ </xsl:template>
+
+ <xsl:template match="match01">
+ <xsl:param name="ident" />
+
+ <xsl:value-of select="concat($ident, 'if((opc & ', @mask, ' == ', @value, ') {', $newline)" />
+ <xsl:apply-templates select="instruction">
+ <xsl:with-param name="ident"><xsl:value-of select="concat($ident, $tab)"/></xsl:with-param>
+ </xsl:apply-templates>
+ <xsl:value-of select="concat($ident, 'break;', $newline)"/>
+ <xsl:value-of select="concat($ident, '}', $newline)"/>
+ </xsl:template>
+
+</xsl:stylesheet>
new file mode 100644
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+
+<!--
+ CPUGEN
+
+ Copyright (c) 2016 Michael Rolnik
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+-->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
+ xmlns:func = "http://exslt.org/functions"
+ xmlns:str = "http://exslt.org/strings"
+ xmlns:mine = "mrolnik@gmail.com"
+ extension-element-prefixes="func"
+ >
+
+ <xsl:include href="utils.xsl"/>
+
+<xsl:strip-space elements="*"/>
+<xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
+
+<xsl:template match="/cpu/instructions">
+ <xsl:value-of select="$license" />
+<xsl:text>
+#ifndef AVR_TRANSLATE_INST_H_
+#define AVR_TRANSLATE_INST_H_
+
+typedef struct DisasContext DisasContext;
+
+</xsl:text>
+
+<xsl:apply-templates select="//instruction" />
+
+<xsl:text>
+#endif
+</xsl:text>
+</xsl:template>
+
+<xsl:template match="instruction">
+ <xsl:variable name="length" select="string-length(@opcode)" />
+ <xsl:variable name="datatype" select="mine:get-opcode-struct-type($length)" />
+ <xsl:variable name="namestem" select="@name"/>
+ <xsl:variable name="ilength" select="@length"/>
+
+ <xsl:value-of select="concat('int ', /cpu/@name, '_translate_', @name, '(CPUAVRState *env, DisasContext* ctx, uint32_t opcode);', $newline)" />
+ <xsl:for-each select="fields/field">
+ <xsl:sort select="position()" data-type="number" order="descending"/>
+ <xsl:choose>
+ <xsl:when test="str:replace(str:replace(@name, '0', ''), '1', '') = ''">
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="field" select="substring(@name, 2, string-length(@name) - 1)" />
+ <xsl:variable name="h" select="../field[@name = concat('h', $field)]"/>
+ <xsl:variable name="l" select="../field[@name = concat('l', $field)]"/>
+ <xsl:variable name="m" select="../field[@name = concat('m', $field)]"/>
+
+ <xsl:if test="not($h/@name = @name or $m/@name = @name or $l/@name = @name)">
+ <xsl:value-of select="concat('static inline uint32_t ', $namestem, '_', @name, '(uint32_t opcode)', $newline)" />
+ <xsl:value-of select="concat('{', $newline)" />
+ <xsl:value-of select="concat(' return extract32(opcode, ', $ilength - @offset - @length, ', ', @length, ');', $newline)" />
+ <xsl:value-of select="concat('}', $newline)" />
+ </xsl:if>
+
+ <xsl:if test="$l and $h and ($h/@name = @name)">
+ <xsl:value-of select="concat('static inline uint32_t ', $namestem, '_', $field, '(uint32_t opcode)', $newline)" />
+ <xsl:value-of select="concat('{', $newline)" />
+ <xsl:value-of select="' return '" />
+
+<xsl:variable name="l_length" select="$l/@length"/>
+<xsl:variable name="l_offset" select="$ilength - $l/@offset - $l_length"/>
+
+<xsl:variable name="m_length" select="$m/@length"/>
+<xsl:variable name="m_offset" select="$ilength - $m/@offset - $m_length"/>
+
+<xsl:variable name="h_length" select="$h/@length"/>
+<xsl:variable name="h_offset" select="$ilength - $h/@offset - $h_length"/>
+
+
+ <xsl:choose>
+ <xsl:when test="$h and $m and $l">
+ <xsl:value-of select="concat('(extract32(opcode, ', $h_offset, ', ', $h_length, ') << ', $l_length + $m_length, ') | ')" />
+ <xsl:value-of select="concat('(extract32(opcode, ', $m_offset, ', ', $m_length, ') << ', $l_length, ') | ')" />
+ <xsl:value-of select="concat('(extract32(opcode, ', $l_offset, ', ', $l_length, '))')" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="concat('(extract32(opcode, ', $h_offset, ', ', $h_length, ') << ', $l_length, ') | ')" />
+ <xsl:value-of select="concat('(extract32(opcode, ', $l_offset, ', ', $l_length, '))')" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <xsl:value-of select="concat(';', $newline)"/>
+ <xsl:value-of select="concat('}', $newline)"/>
+ </xsl:if>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:for-each>
+ <xsl:value-of select="$newline" />
+</xsl:template>
+
+</xsl:stylesheet>
new file mode 100644
@@ -0,0 +1,108 @@
+<?xml version="1.0"?>
+<!--
+ CPUGEN
+
+ Copyright (c) 2016 Michael Rolnik
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+-->
+<xsl:stylesheet version="1.0"
+ xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
+ xmlns:str = "http://exslt.org/strings"
+ xmlns:func = "http://exslt.org/functions"
+ xmlns:exsl = "http://exslt.org/common"
+ xmlns:mine = "mrolnik@gmail.com"
+ extension-element-prefixes="func">
+
+ <xsl:output method = "text" />
+ <xsl:strip-space elements="*"/>
+
+ <xsl:variable name="newline">
+ <xsl:text>
+</xsl:text>
+ </xsl:variable>
+ <xsl:variable name="license">
+ <xsl:text>/*
+ * QEMU AVR CPU
+ *
+ * Copyright (c) 2016 Michael Rolnik
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+</xsl:text>
+ </xsl:variable>
+
+ <xsl:variable name="tab">
+ <xsl:text> </xsl:text>
+ </xsl:variable>
+
+ <func:function name="mine:pad" as="string">
+ <xsl:param name="str" as="xs:string"/>
+ <xsl:param name="len" as="xs:integer"/>
+ <xsl:variable name="lstr" select="string-length($str)"/>
+ <xsl:variable name="pad" select="str:padding($len - $lstr, ' ')"/>
+ <func:result select="concat($str,$pad)"/>
+ </func:function>
+
+ <func:function name="mine:toupper" as="string">
+ <xsl:param name="str" as="xs:string"/>
+ <xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ ,-.'" />
+ <xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz____'" />
+ <func:result select="translate($str, $upper, $lower)" />
+ </func:function>
+
+ <func:function name="mine:toname" as="string">
+ <xsl:param name="str" as="xs:string"/>
+ <xsl:variable name="src" select="'. ,-'" />
+ <xsl:variable name="dst" select="'_'" />
+ <func:result select="translate($str, $src, $dst)" />
+ </func:function>
+
+ <func:function name="mine:get-opcode-struct-type">
+ <xsl:param name="length"/>
+ <xsl:choose>
+ <xsl:when test="$length < '9'">
+ <func:result select="'uint8_t '"/>
+ </xsl:when>
+ <xsl:when test="$length < '17'">
+ <func:result select="'uint16_t'"/>
+ </xsl:when>
+ <xsl:when test="$length < '33'">
+ <func:result select="'uint32_t'"/>
+ </xsl:when>
+ <xsl:when test="$length < '65'">
+ <func:result select="'uint64_t'"/>
+ </xsl:when>
+ </xsl:choose>
+ </func:function>
+
+</xsl:stylesheet>
Signed-off-by: Michael Rolnik <mrolnik@gmail.com> --- target-avr/cpugen/CMakeLists.txt | 38 +++ target-avr/cpugen/README.md | 17 ++ target-avr/cpugen/cpu/avr.yaml | 214 ++++++++++++++ target-avr/cpugen/src/CMakeLists.txt | 62 ++++ target-avr/cpugen/src/cpugen.cpp | 460 +++++++++++++++++++++++++++++ target-avr/cpugen/src/utils.cpp | 27 ++ target-avr/cpugen/src/utils.h | 79 +++++ target-avr/cpugen/xsl/decode.c.xsl | 103 +++++++ target-avr/cpugen/xsl/translate-inst.h.xsl | 118 ++++++++ target-avr/cpugen/xsl/utils.xsl | 108 +++++++ 10 files changed, 1226 insertions(+) create mode 100644 target-avr/cpugen/CMakeLists.txt create mode 100644 target-avr/cpugen/README.md create mode 100644 target-avr/cpugen/cpu/avr.yaml create mode 100644 target-avr/cpugen/src/CMakeLists.txt create mode 100644 target-avr/cpugen/src/cpugen.cpp create mode 100644 target-avr/cpugen/src/utils.cpp create mode 100644 target-avr/cpugen/src/utils.h create mode 100644 target-avr/cpugen/xsl/decode.c.xsl create mode 100644 target-avr/cpugen/xsl/translate-inst.h.xsl create mode 100644 target-avr/cpugen/xsl/utils.xsl