[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v9 10/10] target-avr: decoder generator. currently n
From: |
Michael Rolnik |
Subject: |
[Qemu-devel] [PATCH v9 10/10] target-avr: decoder generator. currently not used by the build, can be used manually |
Date: |
Wed, 22 Jun 2016 12:51:55 +0300 |
Signed-off-by: Michael Rolnik <address@hidden>
---
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
diff --git a/target-avr/cpugen/CMakeLists.txt b/target-avr/cpugen/CMakeLists.txt
new file mode 100644
index 0000000..ded391c
--- /dev/null
+++ b/target-avr/cpugen/CMakeLists.txt
@@ -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}
+)
diff --git a/target-avr/cpugen/README.md b/target-avr/cpugen/README.md
new file mode 100644
index 0000000..f0caa8b
--- /dev/null
+++ b/target-avr/cpugen/README.md
@@ -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
+```
diff --git a/target-avr/cpugen/cpu/avr.yaml b/target-avr/cpugen/cpu/avr.yaml
new file mode 100644
index 0000000..a626859
--- /dev/null
+++ b/target-avr/cpugen/cpu/avr.yaml
@@ -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
+
diff --git a/target-avr/cpugen/src/CMakeLists.txt
b/target-avr/cpugen/src/CMakeLists.txt
new file mode 100644
index 0000000..5f08761
--- /dev/null
+++ b/target-avr/cpugen/src/CMakeLists.txt
@@ -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}
+)
diff --git a/target-avr/cpugen/src/cpugen.cpp b/target-avr/cpugen/src/cpugen.cpp
new file mode 100644
index 0000000..912dc55
--- /dev/null
+++ b/target-avr/cpugen/src/cpugen.cpp
@@ -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";
+ }
+}
+
diff --git a/target-avr/cpugen/src/utils.cpp b/target-avr/cpugen/src/utils.cpp
new file mode 100644
index 0000000..2261139
--- /dev/null
+++ b/target-avr/cpugen/src/utils.cpp
@@ -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>
+
diff --git a/target-avr/cpugen/src/utils.h b/target-avr/cpugen/src/utils.h
new file mode 100644
index 0000000..0d96b7e
--- /dev/null
+++ b/target-avr/cpugen/src/utils.h
@@ -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
diff --git a/target-avr/cpugen/xsl/decode.c.xsl
b/target-avr/cpugen/xsl/decode.c.xsl
new file mode 100644
index 0000000..b8aa02c
--- /dev/null
+++ b/target-avr/cpugen/xsl/decode.c.xsl
@@ -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 = "address@hidden"
+ 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>
diff --git a/target-avr/cpugen/xsl/translate-inst.h.xsl
b/target-avr/cpugen/xsl/translate-inst.h.xsl
new file mode 100644
index 0000000..2830ce3
--- /dev/null
+++ b/target-avr/cpugen/xsl/translate-inst.h.xsl
@@ -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 = "address@hidden"
+ 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="../address@hidden =
concat('h', $field)]"/>
+ <xsl:variable name="l" select="../address@hidden =
concat('l', $field)]"/>
+ <xsl:variable name="m" select="../address@hidden =
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>
diff --git a/target-avr/cpugen/xsl/utils.xsl b/target-avr/cpugen/xsl/utils.xsl
new file mode 100644
index 0000000..b4511b6
--- /dev/null
+++ b/target-avr/cpugen/xsl/utils.xsl
@@ -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 = "address@hidden"
+ 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>
--
2.4.9 (Apple Git-60)
- [Qemu-devel] [PATCH v9 00/10] 8bit AVR cores, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 03/10] target-avr: adding a sample AVR board, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 05/10] target-avr: adding AVR interrupt handling, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 01/10] target-avr: AVR cores support is added. 1. basic CPU structure 2. registers 3. no instructions 4. saving sreg, rampD, rampX, rampY, rampD, eind in HW representation saving cpu features, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 04/10] target-avr: adding instructions encodings, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 06/10] target-avr: adding helpers for IN, OUT, SLEEP, WBR & unsupported instructions, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 07/10] target-avr: adding instruction decoder, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 02/10] target-avr: adding AVR CPU features/flavors, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 09/10] target-avr: updating translate.c to use instructions translation, Michael Rolnik, 2016/06/22
- [Qemu-devel] [PATCH v9 10/10] target-avr: decoder generator. currently not used by the build, can be used manually,
Michael Rolnik <=
- [Qemu-devel] [PATCH v9 08/10] target-avr: adding instruction translation, Michael Rolnik, 2016/06/22