1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
/*
* Copyright (c) 2021 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Ada specifications generated by this assembler depend on the RP.PIO package,
* available in rp2040_hal.
*
* https://github.com/JeremyGrosser/rp2040_hal
* https://github.com/JeremyGrosser/pico_bsp
* https://github.com/JeremyGrosser/pico_examples
*/
#include <algorithm>
#include <iostream>
#include "output_format.h"
#include "pio_disassembler.h"
struct ada_output : public output_format {
struct factory {
factory() {
output_format::add(new ada_output());
}
};
ada_output() : output_format("ada") {}
std::string get_description() override {
return "Ada specification";
}
void output_symbols(FILE *out, const std::vector<compiled_source::symbol> &symbols) {
int count = 0;
for (const auto &s : symbols) {
if (!s.is_label) {
fprintf(out, "%s : constant := %d;\n", s.name.c_str(), s.value);
count++;
}
}
if (count) {
fprintf(out, "\n");
count = 0;
}
for (const auto &s : symbols) {
if (s.is_label) {
fprintf(out, " Offset_%s : constant := %d;\n", s.name.c_str(), s.value);
count++;
}
}
if (count) {
fprintf(out, "\n");
}
}
void ada_case(std::string &identifier) {
for(std::string::size_type i = 0; i < identifier.size(); ++i) {
if ((i == 0) || (identifier[i - 1] == '_')) {
identifier[i] = toupper(identifier[i]);
}
}
}
void header(FILE *out, const std::string msg, const int indent) {
const std::string dashes = std::string(msg.length() + 6, '-');
const std::string indent_str= std::string(indent, ' ');
fprintf(out, "%s%s\n", indent_str.c_str(), dashes.c_str());
fprintf(out, "%s-- %s --\n", indent_str.c_str(), msg.c_str());
fprintf(out, "%s%s\n", indent_str.c_str(), dashes.c_str());
fprintf(out, "\n");
}
int output(std::string destination, std::vector<std::string> output_options,
const compiled_source &source) override {
for (const auto &program : source.programs) {
for(const auto &p : program.lang_opts) {
if (p.first.size() >= name.size() && p.first.compare(0, name.size(), name) == 0) {
std::cerr << "warning: " << name << " does not support output options; " << p.first << " lang_opt ignored.\n";
}
}
}
std::string package_name;
switch (output_options.size()) {
case 0:
std::cerr << "error: missing package name options for Ada format" << std::endl;
return 1;
case 1:
package_name = output_options[0]; // Package name from command options
break;
default:
std::cerr << "error: too many options for Ada format" << std::endl;
return 1;
}
FILE *out = open_single_output(destination);
if (!out) return 1;
header(out, "This file is autogenerated by pioasm; do not edit!", 0);
fprintf(out, "pragma Style_Checks (Off);\n\n");
fprintf(out, "with RP.PIO;\n\n");
fprintf(out, "package %s is\n", package_name.c_str());
for (const auto &program : source.programs) {
std::string trailing_comma = ", ";
std::string prog_name= program.name;
ada_case(prog_name);
fprintf(out, "\n");
header(out, prog_name, 3);
output_symbols(out, source.global_symbols);
fprintf(out, " %s_Wrap_Target : constant := %d;\n", prog_name.c_str(), program.wrap_target);
fprintf(out, " %s_Wrap : constant := %d;\n", prog_name.c_str(), program.wrap);
fprintf(out, "\n");
output_symbols(out, program.symbols);
fprintf(out, " %s_Program_Instructions : RP.PIO.Program := (\n", prog_name.c_str());
for (int i = 0; i < (int)program.instructions.size(); i++) {
const auto &inst = program.instructions[i];
if (i == program.wrap_target) {
fprintf(out, " -- .wrap_target\n");
}
if (i == (int)program.instructions.size() - 1) {
trailing_comma = ");";
}
fprintf(out, " 16#%04x#%s -- %2d: %s\n", (uint16_t)inst, trailing_comma.c_str(), i,
disassemble(inst, program.sideset_bits_including_opt.get(), program.sideset_opt).c_str());
if (i == program.wrap) {
fprintf(out, " -- .wrap\n");
}
}
}
fprintf(out, "\n");
fprintf(out, "end %s;\n", package_name.c_str());
fclose(out);
return 0;
}
};
static ada_output::factory creator;
|