1 /* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _OUTPUT_FORMAT_H 8 #define _OUTPUT_FORMAT_H 9 10 #include <vector> 11 #include <map> 12 #include <string> 13 #include <memory> 14 15 #include "pio_enums.h" 16 17 typedef unsigned int uint; 18 19 // can't use optional because we want to support older compilers 20 template<typename T> 21 struct simple_optional { 22 T value; 23 T default_value; 24 bool specified; 25 simple_optionalsimple_optional26 simple_optional() : default_value(), specified(false) {} 27 simple_optionalsimple_optional28 simple_optional(const T &value) : value(value), specified(true) {} 29 30 simple_optional<T> &operator=(const T &v) { 31 value = v; 32 specified = true; 33 return *this; 34 } 35 36 operator bool() = delete; // confusing getsimple_optional37 const T &get() const { return specified ? value : default_value; } 38 is_specifiedsimple_optional39 bool is_specified() const { return specified; } 40 with_defaultsimple_optional41 static simple_optional<T> with_default(const T &default_value) { 42 simple_optional<T> rc; 43 rc.default_value = default_value; 44 return rc; 45 } 46 }; 47 48 typedef simple_optional<int> optional_int; 49 typedef simple_optional<bool> optional_bool; 50 51 struct compiled_source { 52 struct symbol { 53 std::string name; 54 int value; 55 bool is_label; 56 symbolcompiled_source::symbol57 symbol(std::string name, int value, bool is_label) : name(std::move(name)), value(value), is_label(is_label) {} 58 }; 59 60 struct in_out { 61 int pin_count; 62 bool right; 63 bool autop; 64 int threshold; 65 }; 66 67 struct program { 68 std::string name; 69 optional_int origin = optional_int::with_default(-1); 70 optional_int sideset_bits_including_opt; 71 bool sideset_opt = false; 72 bool sideset_pindirs = false; 73 int wrap; 74 int wrap_target; 75 int pio_version; 76 int mov_status_type; 77 int mov_status_n; 78 in_out in; 79 in_out out; 80 int set_count; 81 uint clock_div_int; 82 uint clock_div_frac; 83 uint8_t used_gpio_ranges; 84 fifo_config fifo; 85 std::vector<uint> instructions; 86 std::vector<symbol> symbols; // public only 87 std::map<std::string, std::vector<std::string>> code_blocks; 88 std::map<std::string, std::vector<std::pair<std::string,std::string>>> lang_opts; 89 90 // todo can't have wrap at -1 programcompiled_source::program91 program(std::string name) : name(std::move(name)) {} 92 }; 93 94 std::vector<symbol> global_symbols; // public only 95 std::vector<program> programs; 96 }; 97 98 struct output_format { 99 static std::string default_name; 100 101 std::string name; 102 addoutput_format103 static void add(output_format *lang) { 104 all().push_back(std::shared_ptr<output_format>(lang)); 105 } 106 107 virtual int output(std::string destination, std::vector<std::string> output_options, 108 const compiled_source &source) = 0; 109 110 virtual std::string get_description() = 0; 111 112 FILE *open_single_output(std::string destination); 113 virtual ~output_format() = default; 114 alloutput_format115 static std::vector<std::shared_ptr<output_format>>& all() { 116 static std::vector<std::shared_ptr<output_format>> output_formats; 117 return output_formats; 118 } 119 protected: output_formatoutput_format120 output_format(std::string name) : name(std::move(name)) {} 121 }; 122 123 #endif