From 90e056166b29aa959c5075fac1f271712637d2a8 Mon Sep 17 00:00:00 2001 From: Wolfgang Thaller Date: Sat, 29 Aug 2015 03:33:14 +0200 Subject: [PATCH] Finally make ASFilter unnecessary. --- ASFilter/CMakeLists.txt | 42 ---------- ASFilter/asfilter.cc | 162 ------------------------------------ CMakeLists.txt | 1 - README.md | 13 +-- build-toolchain.sh | 6 -- gcc/gcc/config/m68k/m68k.c | 5 +- gcc/gcc/config/m68k/m68k.md | 11 ++- gcc/gcc/final.c | 9 ++ 8 files changed, 25 insertions(+), 224 deletions(-) delete mode 100644 ASFilter/CMakeLists.txt delete mode 100644 ASFilter/asfilter.cc diff --git a/ASFilter/CMakeLists.txt b/ASFilter/CMakeLists.txt deleted file mode 100644 index dfbfabbd07..0000000000 --- a/ASFilter/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2012 Wolfgang Thaller. -# -# This file is part of Retro68. -# -# Retro68 is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Retro68 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Retro68. If not, see . - -cmake_minimum_required(VERSION 2.8) - -set(CMAKE_CXX_FLAGS "--std=c++0x") - -set(USE_BOOST_REGEX FALSE CACHE BOOL "Force use of boost for regular expressions") - -if(CMAKE_COMPILER_IS_GNUCXX) - if(${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.9) - set(USE_BOOST_REGEX TRUE) - message(STATUS "forcing use of boost::regex") - endif() -endif() - -if(USE_BOOST_REGEX) - add_definitions(-DUSE_BOOST_REGEX) - find_package(Boost COMPONENTS regex) -endif() - -add_executable(asfilter asfilter.cc) - -if(USE_BOOST_REGEX) - target_link_libraries(asfilter ${Boost_LIBRARIES}) -endif() - -install(TARGETS asfilter RUNTIME DESTINATION bin) diff --git a/ASFilter/asfilter.cc b/ASFilter/asfilter.cc deleted file mode 100644 index 5b96a8546b..0000000000 --- a/ASFilter/asfilter.cc +++ /dev/null @@ -1,162 +0,0 @@ -/* - Copyright 2012 Wolfgang Thaller. - - This file is part of Retro68. - - Retro68 is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Retro68 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Retro68. If not, see . -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace std::placeholders; - -#ifdef USE_BOOST_REGEX -#include -namespace rx = boost; -#else -#include -namespace rx = std; -#endif - -int main(int argc, char *argv[]) -{ - std::vector argv2; - std::vector argv3; - - std::copy(argv, argv+argc, std::back_inserter(argv2)); - argv2[0] += ".real"; - - std::string inputFileName; - std::string tempFileName; - - char tempFileTemplate[] = "/tmp/filteredXXXXXX.s"; - int fd = mkstemps(tempFileTemplate, 2); - tempFileName = tempFileTemplate; - - for(auto& p : argv2) - { - if(p.substr(p.length()-2) == ".s") - { - inputFileName = p; - p = tempFileName; - //std::cerr << "Temp file: " << tempFileName << std::endl; - } - } - - { - std::ifstream in(inputFileName); - std::ofstream out(tempFileName); - - rx::regex rts("\trts"); - rx::regex instruction("\t[a-z]+.*"); - rx::regex macsbug("# macsbug symbol"); - rx::regex rtd("\trtd #([0-9]+)"); - - bool hadRts = false; - bool macsbugSymbol = false, macsbugSymbol1; - while(in) - { - std::string line; - std::getline(in, line); - if(!in) - break; - - macsbugSymbol1 = false; - - rx::smatch match; - // ******* 1. rtd hack - // - // GCC currently generates rtd instructions when returning - // from pascal functions. This instruction is not supported on the original 68000, - // so let's replace it. - // This should really be done by GCC itself. - - if(rx::regex_match(line, match, rtd)) - { - out << "\tmove.l (%a7)+, %a0\n"; - out << "\tlea " + match[1].str() + "(%a7), %a7\n"; - out << "\tjmp (%a0)\n"; - hadRts = true; - } - - // ******* 2. strip unneeded extra rts from "# macsbug symbol" paragraphs - // - // GCC is patched to add something like this to the end of every function: - // # macsbug symbol - // rts - // .byte 132 - // .ascii "main" - // .align 2,0 - // .short 0 - // .size main, .-main - // - // The rts is usually redundant as most functions already end in RTS. - // The following removes the RTS if there has already been an RTS immediately before. - else if(rx::regex_match(line, macsbug)) - { - out << line << std::endl; - macsbugSymbol1 = true; - } - else if(rx::regex_match(line, rts)) - { - if(!macsbugSymbol || !hadRts) - out << line << std::endl; - hadRts = true; - } - else if(rx::regex_match(line, instruction)) - { - hadRts = false; - out << line << std::endl; - } - - // Pass through everything else. - else - out << line << std::endl; - - macsbugSymbol = macsbugSymbol1; - } - } - - close(fd); - - std::transform(argv2.begin(), argv2.end(), std::back_inserter(argv3), - [](const std::string& str) { return str.c_str(); }); - - argv3.push_back(NULL); - - pid_t pid = fork(); - if(pid > 0) - { - waitpid(pid, NULL, 0); - unlink(tempFileName.c_str()); - return 0; - } - else if(pid == 0) - { - execvp(argv3[0], const_cast( argv3.data() )); - perror("execvp"); - } - else - perror("fork"); - return 1; -} diff --git a/CMakeLists.txt b/CMakeLists.txt index f7760716a8..4479765e42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,6 @@ configure_file(cmake/intree.toolchain.cmake.in cmake/intree.toolchain.cmake @ONL add_subdirectory(ResourceFiles) add_subdirectory(MakeAPPL) -add_subdirectory(ASFilter) add_subdirectory(Rez) endif() diff --git a/README.md b/README.md index a4260df5e4..9d64c89adb 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,6 @@ Third Party Components: - hfsutils 3.2.6 (just for convenience) Retro68-Specific Components: -- ASFilter - PrepareHeaders.hs - MakeAPPL - libretro @@ -140,14 +139,6 @@ Included for convenience. No changes. Apply any necessary patches to Apple's headers; currently, this only modifies `ConditionalMacros.h`. -### ASFilter: - -An evil hack. Installs a replacement for m68k-unknown-elf-as that -runs a few regexps on generated assembly code. Two things are changed: - -1. Replace occurrences of the RTD instruction with something that is supported on 68000 as well. GCC currently generates this in `pascal` functions that you declare. -2. While we're at it, remove unnecessary duplicate RTS instructions from MacsBug symbol names. - ### MakeAPPL Reads a FLAT executable as output by elf2flt and converts it to @@ -155,7 +146,9 @@ a MacBinary file containing a classic Macintosh application. ### Rez -A reimplementation of Apple's Rez resource compiler. Reader `.r` files countaining textual resource descriptions and +A reimplementation of Apple's Rez resource compiler. Reads `.r` files +containing textual resource descriptions and compiles them to binary +resource files. ### libretro diff --git a/build-toolchain.sh b/build-toolchain.sh index de1322104c..6ce327713e 100644 --- a/build-toolchain.sh +++ b/build-toolchain.sh @@ -71,12 +71,6 @@ cmake ${SRC} -DCMAKE_INSTALL_PREFIX=$PREFIX cd .. make -C build-host install -if test ! -e $PREFIX/bin/m68k-unknown-elf-as.real; then - mv $PREFIX/bin/m68k-unknown-elf-as $PREFIX/bin/m68k-unknown-elf-as.real - ln -s $PREFIX/bin/asfilter $PREFIX/bin/m68k-unknown-elf-as - mv $PREFIX/m68k-unknown-elf/bin/as $PREFIX/m68k-unknown-elf/bin/as.real - ln -s $PREFIX/bin/asfilter $PREFIX/m68k-unknown-elf/bin/as -fi # create an empty libretrocrt.a so that cmake's compiler test doesn't fail $PREFIX/bin/m68k-unknown-elf-ar cqs $PREFIX/m68k-unknown-elf/lib/libretrocrt.a diff --git a/gcc/gcc/config/m68k/m68k.c b/gcc/gcc/config/m68k/m68k.c index 6f356ded03..9d0fa84e20 100644 --- a/gcc/gcc/config/m68k/m68k.c +++ b/gcc/gcc/config/m68k/m68k.c @@ -6728,6 +6728,8 @@ m68k_epilogue_uses (int regno ATTRIBUTE_UNUSED) == m68k_fk_interrupt_handler)); } +extern int retro68_hack_asm_rts_counter; + void m68k_write_macsbug_name(FILE *file, const char *name) { @@ -6736,7 +6738,8 @@ m68k_write_macsbug_name(FILE *file, const char *name) len = 255; fprintf(file, "# macsbug symbol\n"); - fprintf(file, "\trts\n"); + if(!retro68_hack_asm_rts_counter) + fprintf(file, "\trts\n"); if(len < 32) fprintf(file, "\t.byte %d\n", len | 0x80); else diff --git a/gcc/gcc/config/m68k/m68k.md b/gcc/gcc/config/m68k/m68k.md index 6d96ad2b7b..3039e89adb 100644 --- a/gcc/gcc/config/m68k/m68k.md +++ b/gcc/gcc/config/m68k/m68k.md @@ -7072,6 +7072,7 @@ [(return)] "" { + extern int retro68_hack_asm_rts_counter; switch (m68k_get_function_kind (current_function_decl)) { case m68k_fk_interrupt_handler: @@ -7081,11 +7082,17 @@ return "sleep"; default: + retro68_hack_asm_rts_counter = 2; if (crtl->args.pops_args) { operands[0] = GEN_INT (crtl->args.pops_args); - return "rtd %0"; - } + if (TARGET_68020) + return "rtd %0"; + else + return "move.l (%%a7)+, %%a0\n" + "\tlea %a0(%%a7), %%a7\n" + "\tjmp (%%a0)"; + } else return "rts"; } diff --git a/gcc/gcc/final.c b/gcc/gcc/final.c index 1fa93d9036..91f1caaf04 100644 --- a/gcc/gcc/final.c +++ b/gcc/gcc/final.c @@ -3652,6 +3652,8 @@ do_assembler_dialects (const char *p, int *dialect) and print a constant expression for minus the value of the operand, with no other punctuation. */ +int retro68_hack_asm_rts_counter = 0; + void output_asm_insn (const char *templ, rtx *operands) { @@ -3669,6 +3671,13 @@ output_asm_insn (const char *templ, rtx *operands) if (*templ == 0) return; + /* Hack: in Retro68, we want to know whether the last + instruction we output was an rts, so we know + whether we have to output an extra one as part + of the MacsBug name. */ + if(retro68_hack_asm_rts_counter) + retro68_hack_asm_rts_counter--; + memset (opoutput, 0, sizeof opoutput); p = templ; putc ('\t', asm_out_file);