File indexing completed on 2024-12-01 05:12:54

0001 /***************************************************************************
0002  *   Copyright (C) 2005 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "sdcc.h"
0012 #include "asminfo.h"
0013 #include "languagemanager.h"
0014 #include "logview.h"
0015 #include "microinfo.h"
0016 #include "microlibrary.h"
0017 
0018 #include <KLocalizedString>
0019 #include <KMessageBox>
0020 #include <KProcess>
0021 
0022 #include <ktlconfig.h>
0023 #include <ktechlab_debug.h>
0024 
0025 SDCC::SDCC(ProcessChain *processChain)
0026     : ExternalLanguage(processChain, "SDCC")
0027 {
0028     m_successfulMessage = i18n("*** Compilation successful ***");
0029     m_failedMessage = i18n("*** Compilation failed ***");
0030 }
0031 
0032 SDCC::~SDCC()
0033 {
0034 }
0035 
0036 void SDCC::processInput(ProcessOptions options)
0037 {
0038     resetLanguageProcess();
0039 
0040     MicroInfo *info = MicroLibrary::self()->microInfoWithID(options.m_picID);
0041     if (!info) {
0042         outputError(i18n("Could not find PIC with ID \"%1\".", options.m_picID));
0043         return;
0044     }
0045 
0046     m_processOptions = options;
0047 
0048     if (KTLConfig::sDCC_install_prefix().isEmpty()) {
0049         qCDebug(KTL_LOG) << "using system sdcc";
0050         *m_languageProcess << ("sdcc");
0051     } else {
0052         qCDebug(KTL_LOG) << "using sdcc at " << KTLConfig::sDCC_install_prefix();
0053         *m_languageProcess << (KTLConfig::sDCC_install_prefix().append("/bin/sdcc"));
0054     }
0055 
0056     // BEGIN Pass custom sdcc options
0057 #define ARG(text, option)                                                                                                                                                                                                                      \
0058     if (KTLConfig::text())                                                                                                                                                                                                                     \
0059         *m_languageProcess << (QString("--%1").arg(option));
0060     // General
0061     ARG(sDCC_nostdlib, "nostdlib")
0062     ARG(sDCC_nostdinc, "nostdinc")
0063     ARG(sDCC_less_pedantic, "less-pedantic")
0064     ARG(sDCC_std_c89, "std-c89")
0065     ARG(sDCC_std_c99, "std-c99")
0066     ARG(sDCC_use_non_free, "use-non-free");
0067 
0068     // Code generation
0069     ARG(sDCC_stack_auto, "stack-auto")
0070     ARG(sDCC_int_long_reent, "int-long-reent")
0071     ARG(sDCC_float_reent, "float-reent")
0072     ARG(sDCC_fommit_frame_pointer, "fommit-frame-pointer")
0073     ARG(sDCC_no_xinit_opt, "no-xinit-opt")
0074     ARG(sDCC_all_callee_saves, "all-callee-saves")
0075 
0076     // Optimization
0077     ARG(sDCC_nooverlay, "nooverlay")
0078     ARG(sDCC_nogcse, "nogcse")
0079     ARG(sDCC_nolabelopt, "nolabelopt")
0080     ARG(sDCC_noinvariant, "noinvariant")
0081     ARG(sDCC_noinduction, "noinduction")
0082     ARG(sDCC_no_peep, "no-peep")
0083     ARG(sDCC_noloopreverse, "noloopreverse")
0084     ARG(sDCC_opt_code_size, "opt-code-size")
0085     ARG(sDCC_opt_code_speed, "opt-code-speed")
0086     ARG(sDCC_peep_asm, "peep-asm")
0087     ARG(sDCC_nojtbound, "nojtbound")
0088 
0089     // PIC16 Specific
0090     if (info->instructionSet()->set() == AsmInfo::PIC16) {
0091         ARG(sDCC_nodefaultlibs, "nodefaultlibs")
0092         ARG(sDCC_pno_banksel, "pno-banksel")
0093         ARG(sDCC_pstack_model_large, "pstack-model=large")
0094         ARG(sDCC_debug_xtra, "debug-xtra")
0095         ARG(sDCC_denable_peeps, "denable-peeps")
0096         ARG(sDCC_calltree, "calltree")
0097         ARG(sDCC_fstack, "fstack")
0098         ARG(sDCC_optimize_goto, "optimize-goto")
0099         ARG(sDCC_optimize_cmp, "optimize-cmp")
0100         ARG(sDCC_optimize_df, "optimize-df")
0101     }
0102 #undef ARG
0103 
0104     if (!KTLConfig::sDCC_install_prefix().isEmpty()) {
0105         QString incDir = "";
0106         switch (info->instructionSet()->set()) {
0107         case AsmInfo::PIC14:
0108             incDir = "pic14";
0109             break;
0110         case AsmInfo::PIC16:
0111             incDir = "pic16";
0112             break;
0113         default:
0114             qCWarning(KTL_LOG) << "unsupported PIC instruction set " << info->instructionSet()->set();
0115         }
0116         *m_languageProcess << (QString("-I%1/share/sdcc/include").arg(KTLConfig::sDCC_install_prefix()));
0117         *m_languageProcess << (QString("-I%1/share/sdcc/include/%2").arg(KTLConfig::sDCC_install_prefix()).arg(incDir));
0118         *m_languageProcess << (QString("-I%1/share/sdcc/non-free/include/%2").arg(KTLConfig::sDCC_install_prefix()).arg(incDir));
0119     }
0120 
0121     if (!KTLConfig::miscSDCCOptions().isEmpty()) {
0122         // note: this will not work with quotes inside the text; those need special parsing
0123         *m_languageProcess << (KTLConfig::miscSDCCOptions().split(QRegExp(" ")));
0124     }
0125     // END Pass custom sdcc options
0126 
0127     *m_languageProcess << ("--debug"); // Enable debugging symbol output
0128     *m_languageProcess << ("-S");      // Compile only; do not assemble or link
0129 
0130     QString asmSwitch;
0131     switch (info->instructionSet()->set()) {
0132     case AsmInfo::PIC12:
0133         // Last time I checked, SDCC doesn't support Pic12, and probably never will, but whatever...
0134         asmSwitch = "-mpic12";
0135         break;
0136     case AsmInfo::PIC14:
0137         asmSwitch = "-mpic14";
0138         break;
0139     case AsmInfo::PIC16:
0140         asmSwitch = "-mpic16";
0141         break;
0142     }
0143 
0144     *m_languageProcess << (asmSwitch);
0145 
0146     *m_languageProcess << ("-" + options.m_picID.toLower());
0147 
0148     *m_languageProcess << (options.inputFiles().first());
0149 
0150     *m_languageProcess << ("-o");
0151     *m_languageProcess << (options.intermediaryOutput());
0152 
0153     if (!start()) {
0154         KMessageBox::error(LanguageManager::self()->logView(), i18n("Compilation failed. Please check you have sdcc installed."));
0155         processInitFailed();
0156         return;
0157     }
0158 }
0159 
0160 bool SDCC::isError(const QString &message) const
0161 {
0162     if (message.startsWith("Error:"))
0163         return true;
0164 
0165     return false;
0166 }
0167 
0168 bool SDCC::isStderrOutputFatal(const QString &message) const
0169 {
0170     qCDebug(KTL_LOG) << "message=" << message;
0171     if (message.startsWith("Processor:"))
0172         return false;
0173 
0174     return false; // note: return code from SDCC will tell if anything is fatal
0175                   // return true; // 2017.06.18 - by default stderr messages are not fatal
0176 }
0177 
0178 bool SDCC::isWarning(const QString &message) const
0179 {
0180     if (message.startsWith("Warning:"))
0181         return true;
0182     return false;
0183 }
0184 
0185 ProcessOptions::ProcessPath::Path SDCC::outputPath(ProcessOptions::ProcessPath::Path inputPath) const
0186 {
0187     switch (inputPath) {
0188     case ProcessOptions::ProcessPath::C_AssemblyRelocatable:
0189         return ProcessOptions::ProcessPath::None;
0190 
0191     case ProcessOptions::ProcessPath::C_Library:
0192         return ProcessOptions::ProcessPath::AssemblyRelocatable_Library;
0193 
0194     case ProcessOptions::ProcessPath::C_Object:
0195         return ProcessOptions::ProcessPath::AssemblyRelocatable_Object;
0196 
0197     case ProcessOptions::ProcessPath::C_PIC:
0198         return ProcessOptions::ProcessPath::AssemblyAbsolute_PIC;
0199 
0200     case ProcessOptions::ProcessPath::C_Program:
0201         return ProcessOptions::ProcessPath::AssemblyRelocatable_Program;
0202 
0203     case ProcessOptions::ProcessPath::AssemblyAbsolute_PIC:
0204     case ProcessOptions::ProcessPath::AssemblyAbsolute_Program:
0205     case ProcessOptions::ProcessPath::AssemblyRelocatable_Library:
0206     case ProcessOptions::ProcessPath::AssemblyRelocatable_Object:
0207     case ProcessOptions::ProcessPath::AssemblyRelocatable_PIC:
0208     case ProcessOptions::ProcessPath::AssemblyRelocatable_Program:
0209     case ProcessOptions::ProcessPath::FlowCode_AssemblyAbsolute:
0210     case ProcessOptions::ProcessPath::FlowCode_Microbe:
0211     case ProcessOptions::ProcessPath::FlowCode_PIC:
0212     case ProcessOptions::ProcessPath::FlowCode_Program:
0213     case ProcessOptions::ProcessPath::Microbe_AssemblyAbsolute:
0214     case ProcessOptions::ProcessPath::Microbe_PIC:
0215     case ProcessOptions::ProcessPath::Microbe_Program:
0216     case ProcessOptions::ProcessPath::Object_Disassembly:
0217     case ProcessOptions::ProcessPath::Object_Library:
0218     case ProcessOptions::ProcessPath::Object_PIC:
0219     case ProcessOptions::ProcessPath::Object_Program:
0220     case ProcessOptions::ProcessPath::PIC_AssemblyAbsolute:
0221     case ProcessOptions::ProcessPath::Program_Disassembly:
0222     case ProcessOptions::ProcessPath::Program_PIC:
0223     case ProcessOptions::ProcessPath::Invalid:
0224     case ProcessOptions::ProcessPath::None:
0225         return ProcessOptions::ProcessPath::Invalid;
0226     }
0227 
0228     return ProcessOptions::ProcessPath::Invalid;
0229 }