diff --git a/Main.hs b/Main.hs index cd70ced..8fb89b1 100644 --- a/Main.hs +++ b/Main.hs @@ -129,21 +129,6 @@ getOpts argv = (_,_,errs) -> error (concat errs ++ usageInfo header options) where header = "Usage: tock [OPTION...] SOURCEFILE" -writeOccamWrapper :: Handle -> IO () -writeOccamWrapper h = do - write "#INCLUDE \"cifccsp.inc\"\n" - write "#PRAGMA EXTERNAL \"PROC C.tock.main.init (INT raddr, CHAN BYTE in?, out!, err!) = 0\"\n" - write "#PRAGMA EXTERNAL \"PROC C.tock.main.free (VAL INT raddr) = 0\"\n" - write "PROC kroc.main (CHAN BYTE in?, out!, err!)\n" - write " INT addr:\n" - write " SEQ\n" - write " C.tock.main.init (addr, in?, out!, err!)\n" - write " cifccsp.startprocess (addr)\n" - write " C.tock.main.free (addr)\n" - write ":\n" - where - write = hPutStr h - main :: IO () main = do argv <- getArgs @@ -226,12 +211,8 @@ compileFull inputFile withOutputFile postCFile $ postCAnalyse sFile -- Compile this new "post" C file into an object file exec $ cCommand postCFile postOFile - -- Create a temporary occam file, and write the standard - -- occam wrapper into it - withOutputFile occFile $ liftIO . writeOccamWrapper - -- Use kroc to compile and link the occam file with the two - -- object files from the C compilation - exec $ krocLinkCommand occFile [oFile, postOFile] outputFile + -- Link the object files into a binary + exec $ cLinkCommand [oFile, postOFile] outputFile -- For C++, just compile the source file directly into a binary BackendCPPCSP -> diff --git a/Makefile.am b/Makefile.am index 2a12c57..8b449ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,23 +37,24 @@ GenOrdAST$(EXEEXT): $(GenOrdAST_SOURCES) ghc $(GHC_OPTS) -o GenOrdAST$(EXEEXT) -main-is GenOrdAST --make GenOrdAST -odir obj -hidir obj TOCK_CFLAGS = @gnu89_inline@ @CPPFLAGS@ @CFLAGS@ -Wall `kroc --cflags` `kroc --ccincpath` -fno-strict-aliasing +# FIXME: -ldl is only necessary on some platforms for CCSP +TOCK_CLDFLAGS = @LDFLAGS@ `kroc --cclibpath` -lccsp -lpthread -ldl -lm TOCK_CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ -Wall -ggdb3 -I. -fno-strict-aliasing TOCK_CXXLDFLAGS = @LDFLAGS@ -lcppcsp2 -pthread - CompilerCommands.hs: Makefile - echo -e 'module CompilerCommands where\n' > CompilerCommands.hs - echo -e '--This file is auto-generated by Makefile.am\n' >> CompilerCommands.hs - echo -e 'import Data.List\n' >> CompilerCommands.hs - echo -e 'cCommand :: String -> String -> String\n' >> CompilerCommands.hs - echo -e 'cCommand inp out = "$(CC) $(TOCK_CFLAGS) -c -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs - echo -e 'cAsmCommand :: String -> String -> String\n' >> CompilerCommands.hs - echo -e 'cAsmCommand inp out = "$(CC) $(TOCK_CFLAGS) -S -o " ++ out ++ " " ++ inp\n' >> CompilerCommands.hs - echo -e 'krocLinkCommand :: String -> [String] -> String -> String\n' >> CompilerCommands.hs - echo -e 'krocLinkCommand wrapper files out = "kroc -o " ++ out ++ " " ++ wrapper ++ " " ++ (concat (intersperse " " files)) ++ " -lcif"\n' >> CompilerCommands.hs - echo -e 'cxxCommand :: String -> String -> String\n' >> CompilerCommands.hs - echo -e 'cxxCommand inp out = "$(CXX) $(TOCK_CXXFLAGS) -o " ++ out ++ " " ++ inp ++ " $(TOCK_CXXLDFLAGS)"\n' >> CompilerCommands.hs + echo 'module CompilerCommands where' > CompilerCommands.hs + echo '--This file is auto-generated by Makefile.am' >> CompilerCommands.hs + echo 'import Data.List' >> CompilerCommands.hs + echo 'cCommand :: String -> String -> String' >> CompilerCommands.hs + echo 'cCommand inp out = "$(CC) $(TOCK_CFLAGS) -c -o " ++ out ++ " " ++ inp' >> CompilerCommands.hs + echo 'cAsmCommand :: String -> String -> String' >> CompilerCommands.hs + echo 'cAsmCommand inp out = "$(CC) $(TOCK_CFLAGS) -S -o " ++ out ++ " " ++ inp' >> CompilerCommands.hs + echo 'cLinkCommand :: [String] -> String -> String' >> CompilerCommands.hs + echo 'cLinkCommand files out = "$(CC) $(TOCK_CFLAGS) -o " ++ out ++ " " ++ (concat (intersperse " " files)) ++ " $(TOCK_CLDFLAGS)"' >> CompilerCommands.hs + echo 'cxxCommand :: String -> String -> String' >> CompilerCommands.hs + echo 'cxxCommand inp out = "$(CXX) $(TOCK_CXXFLAGS) -o " ++ out ++ " " ++ inp ++ " $(TOCK_CXXLDFLAGS)"' >> CompilerCommands.hs # Both these results are near-identical. The -g flag to alex tells it to generate # a lexer optimised for GHC. The other part of the rule inserts the diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 7358c69..63f7c7a 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -1,6 +1,6 @@ {- Tock: a compiler for parallel languages -Copyright (C) 2007 University of Kent +Copyright (C) 2007, 2008 University of Kent This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -157,24 +157,43 @@ cgenTopLevel :: A.AST -> CGen () cgenTopLevel s = do tell ["#include \n"] cs <- get + (tlpName, chans) <- tlpInterface + tell ["extern int " ++ nameString n ++ "_stack_size;\n" - | n <- Set.toList $ csParProcs cs] + | n <- tlpName : (Set.toList $ csParProcs cs)] + sequence_ $ map (call genForwardDeclaration) (listify (const True :: A.Specification -> Bool) s) call genStructured s (\m _ -> tell ["\n#error Invalid top-level item: ", show m]) - (name, chans) <- tlpInterface - tell ["void tock_main (Process *me, Channel *in, Channel *out, Channel *err) {\n"] - genName name - tell [" (me"] - sequence_ [tell [", "] >> call genTLPChannel c | (_,c) <- chans] - tell [");\n"] - tell ["}\n"] - - tell ["void _tock_main_init (int *ws) {"] - tell ["Process *p = ProcAlloc (tock_main, 65536, 3,"] - tell ["(Channel *) ws[1], (Channel *) ws[2], (Channel *) ws[3]);"] - tell ["*((int *) ws[0]) = (int) p;"] - tell ["}"] - tell ["void _tock_main_free (int *ws) {ProcAllocClean ((Process *) ws[0]);}"] + + tell ["void tock_main (Workspace wptr) {\n\ + \ Workspace tlp = ProcAlloc (wptr, ", show $ length chans, ", "] + genName tlpName + tell ["_stack_size);\n"] + sequence_ [do tell [" ProcParam (wptr, tlp, " ++ show i ++ ", "] + call genTLPChannel c + tell [");\n"] + | (i, (_, c)) <- zip [(0 :: Int)..] chans] + + tell ["\n\ + \ LightProcBarrier bar;\n\ + \ LightProcBarrierInit (wptr, &bar, 1);\n\ + \ LightProcStart (wptr, &bar, tlp, (Process) "] + genName tlpName + tell [");\n\ + \ LightProcBarrierWait (wptr, &bar);\n\ + \ Shutdown (wptr);\n\ + \}\n\ + \\n\ + \int main (int argc, char *argv[]) {\n\ + \ if (!ccsp_init ())\n\ + \ return 1;\n\ + \\n\ + \ Workspace p = ProcAllocInitial (0, 512);\n\ + \ ProcStartInitial (p, tock_main);\n\ + \\n\ + \ // NOTREACHED\n\ + \ return 0;\n\ + \}\n"] --}}} --{{{ utilities diff --git a/configure.ac b/configure.ac index 4cb0b24..2310e23 100644 --- a/configure.ac +++ b/configure.ac @@ -83,10 +83,10 @@ old_CFLAGS="$CFLAGS" old_CPPFLAGS="$CPPFLAGS" CFLAGS="$kroc_incpath" CPPFLAGS="$kroc_incpath" -AC_CHECK_HEADER([cifccsp.h],[HAVE_CIFCCSP=true],[HAVE_CIFCCSP=false]) +AC_CHECK_HEADER([cif.h],[HAVE_CIF=true],[HAVE_CIF=false]) -if test "x$HAVE_CIFCCSP" = "xfalse"; then - AC_MSG_WARN([cifccsp.h not found; you will not be able to compile output from the C backend on this machine]) +if test "x$HAVE_CIF" = "xfalse"; then + AC_MSG_WARN([cif.h not found; you will not be able to compile output from the C backend on this machine]) ccsp_kroc_available=false fi CFLAGS="$old_CFLAGS" diff --git a/tock_support.h b/tock_support.h index 17b3a71..506a34f 100644 --- a/tock_support.h +++ b/tock_support.h @@ -1,6 +1,6 @@ /* * C99 support code for Tock programs - * Copyright (C) 2007 University of Kent + * Copyright (C) 2007, 2008 University of Kent * * 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 @@ -27,14 +27,8 @@ #include #include -//For C++CSP: -#ifndef NO_CIFCCSP -#include -#else -#define EXTERNAL_CALLN(F,I,args...) (F)((I),##args) -#define EXTERNAL_CALL(F) (F)() -#define SetErr() -#define Channel int +#ifndef BACKEND_CPPCSP +#include #endif //{{{ mostneg/mostpos @@ -67,26 +61,23 @@ #endif //}}} -//{{{ helper functions to simplify the code generation -static inline void tock_init_chan_array(Channel*, Channel**, int) occam_unused; -static inline void tock_init_chan_array(Channel* pointTo, Channel** pointFrom, int count) { +//{{{ channel array initialisation +static inline void tock_init_chan_array (Channel *, Channel **, int) occam_unused; +static inline void tock_init_chan_array (Channel *pointTo, Channel **pointFrom, int count) { for (int i = 0; i < count; i++) { pointFrom[i] = &(pointTo[i]); - } + } } - //}}} //{{{ runtime check functions - -//C++CSP may have defined this function already: -#ifndef occam_stop -#define occam_stop(pos, format, args...) \ +#ifndef BACKEND_CPPCSP +#define occam_stop(pos, nargs, format, args...) \ do { \ - EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \ + ExternalCallN (fprintf, 3 + nargs, stderr, "Program stopped at %s: " format "\n", pos, ##args); \ SetErr (); \ } while (0) -#endif //occam_stop +#endif static inline int occam_check_slice (int, int, int, const char *) occam_unused; static inline int occam_check_slice (int start, int count, int limit, const char *pos) { @@ -94,21 +85,21 @@ static inline int occam_check_slice (int start, int count, int limit, const char if (count != 0 && (start < 0 || start >= limit || end < 0 || end > limit || count < 0)) { - occam_stop (pos, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit); + occam_stop (pos, 4, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit); } return count; } static inline int occam_check_index (int, int, const char *) occam_unused; static inline int occam_check_index (int i, int limit, const char *pos) { if (i < 0 || i >= limit) { - occam_stop (pos, "invalid array index %d (should be 0 <= i < %d)", i, limit); + occam_stop (pos, 3, "invalid array index %d (should be 0 <= i < %d)", i, limit); } return i; } static inline int occam_check_retype (int, int, const char *) occam_unused; static inline int occam_check_retype (int src, int dest, const char *pos) { if (src % dest != 0) { - occam_stop (pos, "invalid size for RETYPES/RESHAPES (%d does not divide into %d)", dest, src); + occam_stop (pos, 3, "invalid size for RETYPES/RESHAPES (%d does not divide into %d)", dest, src); } return src / dest; } @@ -119,7 +110,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) { static inline type occam_range_check_##type (type, type, type, const char *) occam_unused; \ static inline type occam_range_check_##type (type lower, type upper, type n, const char *pos) { \ if (n < lower || n > upper) { \ - occam_stop (pos, "invalid value in conversion " format " (should be " format " <= i <= " format ")", n, lower, upper); \ + occam_stop (pos, 4, "invalid value in conversion " format " (should be " format " <= i <= " format ")", n, lower, upper); \ } \ return n; \ } @@ -143,7 +134,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) { static inline type occam_div_##type (type, type, const char *) occam_unused; \ static inline type occam_div_##type (type a, type b, const char *pos) { \ if (b == 0) { \ - occam_stop (pos, "divide by zero"); \ + occam_stop (pos, 1, "divide by zero"); \ } \ return a / b; \ } @@ -159,7 +150,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) { static inline type occam_rem_##type (type, type, const char *) occam_unused; \ static inline type occam_rem_##type (type a, type b, const char *pos) { \ if (b == 0) { \ - occam_stop (pos, "modulo by zero"); \ + occam_stop (pos, 1, "modulo by zero"); \ } \ if (a < 0) { \ return -((-a) % (b < 0 ? -b : b)); \ @@ -174,7 +165,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) { static inline type occam_rem_##type (type, type, const char *) occam_unused; \ static inline type occam_rem_##type (type a, type b, const char *pos) { \ if (b == 0) { \ - occam_stop (pos, "modulo by zero"); \ + occam_stop (pos, 1, "modulo by zero"); \ } \ type i = round (a / b); \ return a - (i * b); \ @@ -184,7 +175,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) { static inline type occam_lshift_##type (type, int, const char*) occam_unused; \ static inline type occam_lshift_##type (type a, int b, const char* pos) { \ if (b < 0 || b > (int)(sizeof(type) * CHAR_BIT)) { \ - occam_stop (pos, "left shift by negative value or value (strictly) greater than number of bits in type"); \ + occam_stop (pos, 1, "left shift by negative value or value (strictly) greater than number of bits in type"); \ } else if (b == (int)(sizeof(type) * CHAR_BIT)) { \ return 0; \ } else { \ @@ -194,7 +185,7 @@ static inline int occam_check_retype (int src, int dest, const char *pos) { static inline type occam_rshift_##type (type, int, const char*) occam_unused; \ static inline type occam_rshift_##type (type a, int b, const char* pos) { \ if (b < 0 || b > (int)(sizeof(type) * CHAR_BIT)) { \ - occam_stop (pos, "right shift by negative value or value (strictly) greater than number of bits in type"); \ + occam_stop (pos, 1, "right shift by negative value or value (strictly) greater than number of bits in type"); \ } else if (b == (int)(sizeof(type) * CHAR_BIT)) { \ return 0; \ } else { \ @@ -249,7 +240,7 @@ MAKE_TIMES(uint8_t) static inline uint8_t occam_rem_uint8_t (uint8_t, uint8_t, const char *) occam_unused; static inline uint8_t occam_rem_uint8_t (uint8_t a, uint8_t b, const char *pos) { if (b == 0) { - occam_stop (pos, "modulo by zero"); + occam_stop (pos, 1, "modulo by zero"); } return a % b; } diff --git a/tock_support_cppcsp.h b/tock_support_cppcsp.h index 6b8029a..f408b69 100644 --- a/tock_support_cppcsp.h +++ b/tock_support_cppcsp.h @@ -1,6 +1,6 @@ /* * C++ support code for Tock programs - * Copyright (C) 2007 University of Kent + * Copyright (C) 2007, 2008 University of Kent * * 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 @@ -31,14 +31,14 @@ public: } }; -#define occam_stop(pos, format, args...) \ +#define occam_stop(pos, nargs, format, args...) \ do { \ - EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \ - SetErr (); \ + fprintf(stderr, "Program stopped at %s: " format "\n", pos, ##args); \ throw StopException(""); \ } while (0) -#define NO_CIFCCSP +#define BACKEND_CPPCSP +#define Channel int #include "tock_support.h" @@ -195,7 +195,7 @@ class tockArrayView //Check it fits exactly: if ((totalSourceBytes / totalDim) % sizeof(T) != 0) { - occam_stop ("","invalid size for RETYPES/RESHAPES (%d does not divide into %d)", (totalSourceBytes / totalDim), sizeof(T)); + occam_stop ("", 3, "invalid size for RETYPES/RESHAPES (%d does not divide into %d)", (totalSourceBytes / totalDim), sizeof(T)); } //Set the size of the unknown dimension: