00001
00013 #include <stdio.h>
00014
00015
00016
00017
00018
00019
00020 #define MAX(a, b) a > b ? a : b
00021 #define MIN(a, b) a < b ? a : b
00022
00023
00024
00025
00026 #ifndef __GNUC__
00027 #define _SC_SWITCHLOGIC
00028 #endif
00029
00030 #ifdef _SC_SWITCHLOGIC
00031 typedef int labeltype;
00032 #else
00033 typedef void *labeltype;
00034 #endif
00035
00036 typedef unsigned int bitvector;
00037 typedef bitvector signalvector;
00038 typedef int threadtype;
00039 typedef bitvector threadvector;
00040
00041
00042
00043
00044 signalvector signals;
00045 threadvector enabled;
00046 threadvector active;
00047
00048 #define _idMax 8*sizeof(threadvector)
00049
00050 int runCnt;
00051 int tickCnt;
00052 int tickInstrCnt;
00053 int _notInitial;
00054 threadtype _cid;
00055 labeltype _pc[_idMax];
00056 threadvector _descs[_idMax];
00057 threadtype _parent[_idMax];
00058 labeltype _returnAddress;
00059
00060 #ifndef _SC_SUPPRESS_ERROR_DETECT
00061 signalvector _presence_tested;
00062 #endif
00063
00064
00065
00066
00071 #ifdef _SC_NOTRACE // Tracing off
00072 #define clearPC(id)
00073 #define initPC(id, label) _pc[id] = _ref(label)
00074 #define setPC(id, label) _pc[id] = _ref(label)
00075
00076 #else // Tracing on
00077 char *statePrev[_idMax];
00078 char *state[_idMax];
00079
00080 #define clearPC(id) \
00081 statePrev[id] = "_L_INIT"; \
00082 state[id] = "_L_INIT"
00083
00084 #define initPC(p, label) \
00085 _pc[p] = _ref(label); \
00086 statePrev[p] = "_L_INIT"; \
00087 state[p] = #label
00088
00089 #define setPC(id, label) \
00090 _pc[id] = _ref(label); \
00091 statePrev[id] = state[id]; \
00092 state[id] = #label
00093 #endif // _SC_NOTRACE
00094
00095
00096
00097
00098
00099
00100 int runMax;
00101 int tickMax;
00102
00103 extern const char *s2signame[];
00104
00105
00106
00107
00108
00110 void getInputs();
00111
00113 int checkOutputs(signalvector *tickOutputs);
00114
00116 void printVal(int id);
00117
00119
00121 int tick();
00122
00124 void selectCid();
00125
00126
00127
00129
00132 #ifdef _SC_SWITCHLOGIC
00133 #define _declState static labeltype _state;
00134 #define _BEGIN_SWITCH while (1) { \
00135 _L_SWITCH: switch (_state) { \
00136 case _L_INIT:
00137 #define _END_SWITCH1 }
00138 #define _END_SWITCH2 }
00139 #define _case case
00140 #define _break break
00141 #define _goto(label) do { _state = label; goto _L_SWITCH; } while (0)
00142 #define _deref(label) label
00143 #define _ref(label) label
00144 #define _setStateInit _state = _L_INIT;
00145
00146 #else
00147 #define _declState
00148 #define _BEGIN_SWITCH
00149 #define _END_SWITCH1
00150 #define _END_SWITCH2
00151 #define _case
00152 #define _break
00153 #define _goto(label) goto label
00154 #define _deref(label) *label
00155 #define _ref(label) &&label
00156 #define _setStateInit
00157 #endif
00158
00159
00160
00161
00162
00163 #if ((defined __i386__ || defined __amd64__ || defined __x86_64__) && defined __GNUC__ && !defined _SC_NOASSEMBLER)
00164
00165
00166 #define selectCid_() \
00167 __asm volatile("bsrl %1,%0\n" \
00168 : "=r" (_cid) \
00169 : "c" (active) \
00170 )
00171
00172 #else
00173
00174
00175 #define selectCid_() selectCid()
00176 #endif
00177
00178 #define dispatch() selectCid_(); _goto(_deref(_pc[_cid]))
00179
00180
00181
00182
00183
00185
00188 #define u2b(u) (1 << u)
00189
00190
00191
00192
00193
00195 #define enable(id) \
00196 enabled |= u2b(id); \
00197 active |= u2b(id)
00198
00199 #define enableInit(id) \
00200 enabled = u2b(id); \
00201 active = enabled
00202
00203 #define disable(id) enabled &= ~u2b(id)
00204 #define disableSet(idset) enabled &= ~idset
00205 #define isEnabled(id) (enabled & u2b(id))
00206 #define isEnabledNotOnly(id) (enabled != u2b(id))
00207 #define isEnabledNoneOf(idset) ((enabled & idset) == 0)
00208 #define isEnabledAnyOf(idset) ((enabled & idset) != 0)
00209
00211 #define activate(id) active |= u2b(id)
00212 #define deactivate(id) active &= ~u2b(id)
00213 #define deactivateSet(idset) active &= ~idset
00214 #define isActive(id) (active & u2b(id))
00215
00216
00217
00218
00219
00220 #define _TickEnd 0 // Priority of TickEnd thread
00221
00223
00224 #define RESET() do { \
00225 trace0t("RESET:", "reset automaton\n") \
00226 _notInitial = 0; \
00227 tickCnt = 0; \
00228 } while (0)
00229
00231
00243 #ifdef _SC_SUPPRESS_ERROR_DETECT
00244 #define _SC_ERROR_DETECT_NORESET
00245 #else
00246 #define _SC_ERROR_DETECT_NORESET \
00247 if (_notInitial != 12345678) { \
00248 _SC_ERROR0(_SC_ERROR_NORESET, \
00249 "SC ERROR (Missing Reset): RESET() must be called before initial tick!\n");\
00250 }
00251 #endif
00252
00253 #define TICKSTART(p) \
00254 static threadtype _pid, _ppid; \
00255 static threadvector _forkdescs = 0; \
00256 _declindex \
00257 _declState \
00258 freezePreClear \
00259 _checkTickInit \
00260 if (_notInitial) { \
00261 _SC_ERROR_DETECT_NORESET \
00262 active = enabled; \
00263 dispatch_; \
00264 } else { \
00265 initPC(_TickEnd, _L_TICKEND); \
00266 enableInit(_TickEnd); \
00267 _cid = p; \
00268 _parent[_cid] = _TickEnd; \
00269 clearPC(_cid); \
00270 enable(_cid); \
00271 _setStateInit \
00272 _setPreInit \
00273 _setValInit \
00274 _notInitial = 12345678; \
00275 } \
00276 _BEGIN_SWITCH
00277
00278
00279
00281
00284 #define TICKEND \
00285 TERM_; \
00286 _case _L_TICKEND: setPre \
00287 return isEnabledNotOnly(_TickEnd); \
00288 _END_SWITCH1 \
00289 mergedDispatch \
00290 _END_SWITCH2
00291
00292
00295
00297 #ifdef _SC_INLINE_DISPATCH
00298 #define dispatch_ dispatch()
00299 #define mergedDispatch
00300
00301 #else // Shared dispatch
00302 #define dispatch_ goto _L_DISPATCH
00303 #define mergedDispatch \
00304 _L_TERM: disable(_cid); \
00305 _L_PAUSEG: deactivate(_cid); \
00306 _L_DISPATCH: dispatch();
00307
00308 #endif
00309
00310
00311
00312
00313
00314
00316
00333 #define _CONCAT_helper(a, b) a ## b
00334 #define _CONCAT(a, b) _CONCAT_helper(a, b)
00335 #define __LABELL__ _CONCAT(_LL, __LINE__)
00336
00337 #ifdef _SC_SWITCHLOGIC
00338 #define __LABEL__ __LINE__
00339 #else
00340 #define __LABEL__ _CONCAT(_L, __LINE__)
00341 #endif
00342
00344
00347 #define PAUSE \
00348 do { \
00349 trace1t("PAUSE:", "pauses, active = 0%o\n", active) \
00350 PAUSEG_(__LABEL__); _case __LABEL__: (void) 0; \
00351 } while (0)
00352
00354
00356 #define PAUSEG(label) do { \
00357 trace1t("PAUSEG:", "pauses, active = 0%o\n", active) \
00358 PAUSEG_(label); \
00359 } while (0)
00360
00362 #ifdef _SC_INLINE_DISPATCH
00363 #define PAUSEG_(label) \
00364 setPC(_cid, label); \
00365 deactivate(_cid); \
00366 dispatch_
00367
00368 #else
00369 #define PAUSEG_(label) \
00370 setPC(_cid, label); \
00371 goto _L_PAUSEG
00372 #endif
00373
00374
00376
00377
00378 #define HALT do { \
00379 _case __LABEL__: trace1t("HALT:", "pauses, active = 0%o\n", active) \
00380 PAUSEG_(__LABEL__); \
00381 } while (0)
00382
00383
00385
00389 #define SUSPEND(cond) do { \
00390 _case __LABEL__: if (cond) { \
00391 trace1t("SUSPEND:", "suspends itself and descendants 0%o\n", _descs[_cid]) \
00392 active &= ~_descs[_cid]; \
00393 freezePre \
00394 instrCntDecr \
00395 PAUSEG_(__LABEL__); \
00396 } \
00397 } while (0)
00398
00399
00401
00405 #define SUSPENDG(label) do { \
00406 trace1t("SUSPENDGOT:", "suspends itself and descendants 0%o\n", _descs[_cid]) \
00407 active &= ~_descs[_cid]; \
00408 freezePre \
00409 instrCntDecr \
00410 PAUSEG_(label); \
00411 } while (0)
00412
00413
00415
00417 #define TRANS(label) do { \
00418 ABORT_; \
00419 trace3t("TRANS:", "disables 0%o, transfers to %s, enabled = 0%o\n", \
00420 _descs[_cid], #label, enabled) \
00421 _goto(label); \
00422 } while (0)
00423
00424
00426 #define ABORT do { \
00427 ABORT_; \
00428 trace2t("ABORT:", "disables 0%o, enabled = 0%o\n", \
00429 _descs[_cid], enabled) \
00430 } while (0)
00431
00432
00434 #define ABORT_ \
00435 disableSet(_descs[_cid]); \
00436 deactivateSet(_descs[_cid])
00437
00438
00440
00441
00442 #define TERM do { \
00443 trace1t("TERM:", "terminates, enabled = 0%o\n", enabled & ~u2b(_cid)) \
00444 TERM_; \
00445 } while (0)
00446
00447
00449 #ifdef _SC_INLINE_DISPATCH
00450 #define TERM_ \
00451 disable(_cid); \
00452 deactivate(_cid); \
00453 dispatch_
00454 #else
00455 #define TERM_ goto _L_TERM
00456 #endif
00457
00458
00460 #ifdef _SC_INLINE_DISPATCH
00461 #define TERM_ \
00462 #else
00463 #define TERM_ goto _L_TERM
00464 #endif
00465
00466
00467
00468
00469
00471
00473 #define FORK(label, p) do { \
00474 FORK_(label, p); \
00475 trace3t("FORK:", "forks %d/%s, active = 0%o\n", p, #label, active) \
00476 } while (0)
00477
00478
00480 #define FORK_(label, p) \
00481 initPC(p, label); \
00482 _parent[p] = _cid; \
00483 _forkdescs |= u2b(p); \
00484 enable(p)
00485
00486
00488
00493 #define FORKE(label) do { \
00494 trace1t("FORKE:", "continues at %s\n", #label) \
00495 FORKE_(label); \
00496 } while (0)
00497
00498
00500 #define FORKE_(label) \
00501 setPC(_cid, label); \
00502 _descs[_cid] = _forkdescs; \
00503 _forkdescs = 0; \
00504 _pid = _cid; \
00505 while ((_ppid = _parent[_pid]) != _TickEnd) { \
00506 _descs[_ppid] |= _descs[_pid]; \
00507 _pid = _ppid; \
00508 } \
00509 dispatch_
00510
00512
00523 #define JOINELSE(elselabel) do { \
00524 JOINELSEG_(__LABEL__, elselabel); \
00525 _case __LABEL__: (void) 0; \
00526 } while (0)
00527
00528
00530
00534 #define JOINELSEG(thenlabel, elselabel) do { \
00535 JOINELSEG_(thenlabel, elselabel); \
00536 } while (0)
00537
00538
00540 #define JOINELSEG_(thenlabel, elselabel) \
00541 if (isEnabledNoneOf(_descs[_cid])) { \
00542 trace1t("JOINELSEG:", "joins, transfers to %s\n", #thenlabel) \
00543 _goto(thenlabel); \
00544 } \
00545 trace1t("JOINELSEG:", "does not join, pauses at %s\n", #elselabel) \
00546 instrCntDecr \
00547 PAUSEG_(elselabel)
00548
00549
00551
00555 #define JOIN do { \
00556 _case __LABEL__: \
00557 trace0t("JOIN:", isEnabledAnyOf(_descs[_cid]) ? "waits\n" : "joins\n") \
00558 if (isEnabledAnyOf(_descs[_cid])) { \
00559 PAUSEG_(__LABEL__); \
00560 } \
00561 } while (0)
00562
00563
00565
00568 #define PRIO(p) do { \
00569 trace1t("PRIO:", "set to priority %d\n", p) \
00570 PRIOG_(p, __LABEL__); \
00571 _case __LABEL__: (void) 0; \
00572 } while (0)
00573
00574
00576 #define PRIOG(p, label) do { \
00577 trace2t("PRIOG:", "set to priority %d, goto %s\n", p, #label) \
00578 PRIOG_(p, label); \
00579 } while (0)
00580
00581
00583 #ifdef _SC_SUPPRESS_ERROR_DETECT
00584 #define _SC_ERROR_DETECT_PRIO(p)
00585 #else
00586 #define _SC_ERROR_DETECT_PRIO(p) \
00587 if (isEnabled(p)) { \
00588 _SC_ERROR1(_SC_ERROR_PRIORITY, \
00589 "SC ERROR (Priority Uniqueness): Priority %d already in use!\n", \
00590 p) \
00591 }
00592 #endif
00593
00594
00596
00616 #define PRIO_(p) \
00617 if (p != _cid) { \
00618 _SC_ERROR_DETECT_PRIO(p); \
00619 _parent[p] = _parent[_cid]; \
00620 _pid = 0; \
00621 for (_ppid = _descs[_cid]; _ppid > 0; _ppid >>= 1) { \
00622 if (_parent[_pid] == _cid) \
00623 _parent[_pid] = p; \
00624 _pid++; \
00625 } \
00626 _descs[p] = _descs[_cid]; \
00627 _pid = _cid; \
00628 while ((_ppid = _parent[_pid]) != _TickEnd) { \
00629 _descs[_ppid] &= ~u2b(_cid); \
00630 _descs[_ppid] |= u2b(p); \
00631 _pid = _ppid; \
00632 } \
00633 deactivate(_cid); \
00634 disable(_cid); \
00635 _cid = p; \
00636 enable(_cid); \
00637 }
00638
00640 #define PRIOG_(p, label) \
00641 PRIO_(p); \
00642 setPC(_cid, label); \
00643 dispatch_
00644
00645
00646
00647
00648
00649
00651
00655 #define PPAUSEG(p, label) do { \
00656 trace2t("PPAUSEG:", "sets prio to %d, pauses, resumes at %s\n", p, #label) \
00657 PPAUSEG_(p, label); \
00658 } while (0)
00659
00660
00662 #define PPAUSEG_(p, label) \
00663 PRIO_(p); \
00664 instrCntDecr \
00665 PAUSEG_(label)
00666
00667
00669
00673 #define PPAUSE(p) do { \
00674 trace1t("PPAUSE:", "sets prio to %d, pauses\n", p) \
00675 PPAUSEG_(__LABEL__); \
00676 _case __LABEL__: (void) 0; \
00677 } while (0)
00678
00679
00681
00687 #define JPPAUSEG(p, thenlabel, elselabel) do { \
00688 trace2t("JPPAUSEG:", "%s, prio = %d\n", \
00689 isEnabledNoneOf(_descs[_cid]) ? "joins" : "does not join", p) \
00690 JPPAUSEG_(p, thenlabel, elselabel); \
00691 } while (0)
00692
00693
00695 #define JPPAUSEG_(p, thenlabel, elselabel) \
00696 if (isEnabledNoneOf(_descs[_cid])) { \
00697 _goto(thenlabel); } \
00698 instrCntDecr \
00699 PPAUSEG_(p, elselabel)
00700
00701
00703
00709 #define JPPAUSE(p, elselabel) do { \
00710 trace2t("JPPAUSE:", "%s, prio = %d\n", \
00711 isEnabledNoneOf(_descs[_cid]) ? "joins" : "does not join", p) \
00712 JPPAUSEG_(p, __LABEL__, elselabel); \
00713 _case __LABEL__: (void) 0; \
00714 } while (0)
00715
00716
00717
00718
00719
00721 #define SIGNAL(s) do { \
00722 trace2t("SIGNAL:", "initializes %s/%d\n", s2signame[s], s) \
00723 signals &= ~u2b(s); \
00724 } while (0)
00725
00726
00728 #ifdef _SC_SUPPRESS_ERROR_DETECT
00729 #define _checkTickInit
00730 #define _checkPRESENT(s)
00731 #define _checkPRESENTc(s)
00732 #define _checkEMIT(s)
00733 #else
00734 #define _checkTickInit _presence_tested = 0;
00735 #define _checkPRESENT(s) _presence_tested |= u2b(s);
00736 #define _checkPRESENTc(s) _presence_tested |= u2b(s),
00737 #define _checkEMIT(s) \
00738 if (_presence_tested & u2b(s)) { \
00739 _SC_ERROR2(_SC_ERROR_CAUSALITY, \
00740 "SC ERROR (Causality): Signal %s/%d emitted after test for presence!\n",\
00741 s2signame[s], s) \
00742 }
00743 #endif
00744
00746 #define EMIT(s) do { \
00747 trace2t("EMIT:", "emits %s/%d\n", s2signame[s], s) \
00748 _checkEMIT(s) \
00749 signals |= u2b(s); \
00750 } while (0)
00751
00752
00754 #define SUSTAIN(s) do { \
00755 _case __LABEL__: trace2t("SUSTAIN:", "emits %s/%d\n", s2signame[s], s) \
00756 EMIT(s); PAUSEG_(__LABEL__); \
00757 } while (0)
00758
00759
00761
00765 #define PRESENT(s) \
00766 (trace3tc("PRESENT:", "determines %s/%d %s\n", \
00767 s2signame[s], s, (signals & u2b(s)) ? "present" : "absent") \
00768 (_checkPRESENTc(s) signals & u2b(s)))
00769
00770
00771
00773
00777 #define PRESENTELSE(s, label) do { \
00778 _checkPRESENT(s) \
00779 if (!(signals & u2b(s))) { \
00780 trace3t("PRESENTELSE:", "determines %s/%d absent, transfers to %s\n", \
00781 s2signame[s], s, #label) \
00782 _goto(label); \
00783 } \
00784 trace2t("PRESENTELSE:", "determines %s/%d present\n", s2signame[s], s) \
00785 } while (0)
00786
00787
00789
00791 #define PRESENTEMIT(s, t) do { \
00792 _checkPRESENT(s) \
00793 if (signals & u2b(s)) { \
00794 trace4t("PRESENTEMIT:", "determines %s/%d present, emits %s/%d\n", \
00795 s2signame[s], s, s2signame[t], t) \
00796 _checkEMIT(t) \
00797 signals |= u2b(t); \
00798 } \
00799 elsetrace \
00800 trace2t("PRESENTEMIT:", "determines %s/%d absent\n", s2signame[s], s) \
00801 elsetraceend \
00802 } while (0)
00803
00804
00806
00812 #define AWAITI(s) do { \
00813 _case __LABEL__: _checkPRESENT(s) \
00814 if (!(signals & u2b(s))) { \
00815 trace2t("AWAITI:", "determines %s/%d absent, waits\n", \
00816 s2signame[s], s) \
00817 PAUSEG_(__LABEL__); \
00818 } \
00819 trace2t("AWAITI:", "determines %s/%d present, proceeds\n", s2signame[s], s) \
00820 } while (0)
00821
00822
00824
00831 #define AWAIT(s) do { \
00832 trace0t("AWAIT:", "initial pause\n") \
00833 goto __LABELL__; \
00834 _case __LABEL__: _checkPRESENT(s) \
00835 if (!(signals & u2b(s))) { \
00836 trace2t("AWAIT:", "determines %s/%d absent, waits\n", \
00837 s2signame[s], s) \
00838 __LABELL__: PAUSEG_(__LABEL__); \
00839 } \
00840 trace2t("AWAIT:", "determines %s/%d present, proceeds\n", s2signame[s], s) \
00841 } while (0)
00842
00843
00844
00845
00846
00847
00848
00849 #ifdef _SC_valSigInt_SIZE
00852 #define _declindex static int _i;
00853
00854 #define _setValInit \
00855 for (_i = 0; _i < _SC_valSigInt_SIZE; _i++) \
00856 valSigInt[_i] = -1;
00857
00858 #else // #ifdef _SC_valSigInt_SIZE
00859 #define _declindex
00860 #define _setValInit
00861 #endif
00862
00864 #define EMITINT(s, val) do { \
00865 valSigInt[s] = val; \
00866 trace3t("EMITINT:", "emits %s/%d, value %d\n", \
00867 s2signame[s], s, val) \
00868 _checkEMIT(s) \
00869 signals |= u2b(s); \
00870 } while (0)
00871
00872
00874 #define EMITINTMUL(s, val) do { \
00875 valSigInt[s] *= val; \
00876 trace4t("EMITINTMUL:", "emits %s/%d, value %d, result %d\n", \
00877 s2signame[s], s, val, valSigInt[s]) \
00878 _checkEMIT(s) \
00879 signals |= u2b(s); \
00880 } while (0)
00881
00882
00884 #define EMITINTADD(s, val) do { \
00885 valSigInt[s] += val; \
00886 trace4t("EMITINTADD:", "emits %s/%d, value %d, result %d\n", \
00887 s2signame[s], s, val, valSigInt[s]) \
00888 _checkEMIT(s) \
00889 signals |= u2b(s); \
00890 } while (0)
00891
00892
00894 #define EMITINTMAX(s, val) do { \
00895 valSigInt[s] = MAX(val, valSigInt[s]); \
00896 trace4t("EMITINTMAX:", "emits %s/%d, value %d, result %d\n", \
00897 s2signame[s], s, val, valSigInt[s]) \
00898 _checkEMIT(s) \
00899 signals |= u2b(s); \
00900 } while (0)
00901
00902
00904 #define EMITINTMIN(s, val) do { \
00905 valSigInt[s] = MIN(val, valSigInt[s]); \
00906 trace4t("EMITINTMIN:", "emits %s/%d, value %d, result %d\n", \
00907 s2signame[s], s, val, valSigInt[s]) \
00908 _checkEMIT(s) \
00909 signals |= u2b(s); \
00910 } while (0)
00911
00912
00914 #define VAL(s) ( \
00915 trace3tc("VAL:", "determines value of %s/%d as %d\n", \
00916 s2signame[s], s, valSigInt[s]) \
00917 valSigInt[s])
00918
00919
00921 #define VALREG(s, reg) do { \
00922 trace3t("VALREG:", "determines value of %s/%d as %d\n", \
00923 s2signame[s], s, valSigInt[s]) \
00924 reg = valSigInt[s]; \
00925 } while (0)
00926
00927
00928
00929
00930
00931
00932
00933 #ifdef _SC_USE_PRE
00934 signalvector sigsPre;
00935 signalvector sigsFreeze;
00936
00939 #define _setPreInit \
00940 sigsPre = 0; \
00941 setPreValInit;
00942
00945 #define setPre \
00946 sigsPre = (sigsPre & sigsFreeze) | (signals & ~sigsFreeze); \
00947 setPreVal
00948
00952 #define freezePre sigsFreeze |= sigsDescs[_cid];
00953
00956 #define freezePreClear sigsFreeze = 0;
00957
00958 #else // #ifdef _SC_USE_PRE
00959 #define _setPreInit
00960 #define setPre
00961 #define freezePre
00962 #define freezePreClear
00963 #endif // #ifdef _SC_USE_PRE
00964
00965
00967
00971 #define PRESENTPRE(s) \
00972 (trace3tc("PRESENTPRE:", "determines %s/%d %s\n", \
00973 s2signame[s], s, (sigsPre & u2b(s)) ? "present" : "absent") \
00974 (sigsPre & u2b(s)))
00975
00976
00978
00982 #define PRESENTPREELSE(s, label) do { \
00983 if (!(sigsPre & u2b(s))) { \
00984 trace3t("PRESENTPRE:", "determines previous %s/%d absent, transfers to %s\n", \
00985 s2signame[s], s, #label) \
00986 _goto(label); \
00987 } \
00988 trace2t("PRESENTPRE:", "determines previous %s/%d present\n", \
00989 s2signame[s], s) \
00990 } while (0)
00991
00992
00993
00994
00995
00996 #ifdef _SC_USE_PRE
00997 #ifdef _SC_valSigInt_SIZE
01000 #define setPreValInit \
01001 for (_i = 0; _i < _SC_valSigInt_SIZE; _i++) \
01002 valSigIntPre[_i] = -1;
01003
01006 #define setPreVal \
01007 for (_i = 0; _i < _SC_valSigInt_SIZE; _i++) \
01008 if (!(sigsFreeze & u2b(_i))) \
01009 valSigIntPre[_i] = valSigInt[_i];
01010
01011 #else // #ifdef _SC_valSigInt_SIZE
01012 #define setPreValInit
01013 #define setPreVal
01014 #endif // #ifdef _SC_valSigInt_SIZE
01015 #endif // #ifdef _SC_USE_PRE
01016
01017
01019 #define VALPRE(s) ( \
01020 trace3tc("VALPRE:", "determines value of %s/%d as %d\n", \
01021 s2signame[s], s, valSigIntPre[s]) \
01022 valSigIntPre[s])
01023
01024
01026 #define VALPREREG(s, reg) do { \
01027 trace3t("VALPREREG:", "determines value of %s/%d as %d\n", \
01028 s2signame[s], s, valSigIntPre[s]) \
01029 reg = valSigIntPre[s]; \
01030 } while (0)
01031
01032
01033
01034
01035
01037 #define GOTO(label) do { \
01038 trace1t("GOTO:", "transfer to %s\n", #label) \
01039 instrCntIncr \
01040 _goto(label); \
01041 } while (0)
01042
01043
01044
01045
01046
01048
01052 #define ISAT(id, statelabel) \
01053 (trace2tc("ISAT:", "%s at %s\n", \
01054 (isEnabled(id) && (_pc[id] == _ref(statelabel))) ? "_is_" : "is _not_", #statelabel) \
01055 (isEnabled(id) && (_pc[id] == _ref(statelabel))))
01056
01057
01059
01064 #define ISATELSE(id, statelabel, label) { \
01065 if (isEnabled(id) && (_pc[id] == _ref(statelabel))) { \
01066 trace1t("ISATELSE:", "_is_ at %s\n", #statelabel) \
01067 } else { \
01068 trace2t("ISATELSE:", "is _not_ at %s, transfer to %s\n", \
01069 #statelabel, #label) \
01070 _goto(label); \
01071 }}
01072
01073
01075
01077 #define CALL(label) do { \
01078 trace1t("CALL:", "calls %s\n", #label) \
01079 _returnAddress = _ref(__LABEL__); \
01080 _goto(label); \
01081 _case __LABEL__: (void) 0; \
01082 } while (0)
01083
01084
01086 #define RET do { \
01087 trace0t("RET:", "returns\n") \
01088 _goto(_deref(_returnAddress)); \
01089 } while (0)
01090
01091
01093
01098 #define ISATCALL(id, l_state, l_call) do { \
01099 if (isEnabled(id) && (_pc[id] == _ref(l_state))) { \
01100 trace1t("ISATCALL:", "calls %s\n", #l_call) \
01101 _returnAddress = _ref(__LABEL__); \
01102 _goto(l_call); \
01103 } \
01104 trace1t("ISATCALL:", "does _not_ call %s\n", #l_call) \
01105 _case __LABEL__: (void) 0; \
01106 } while (0)
01107
01108
01109
01111
01113
01116 #ifdef _SC_NOTRACE
01117 #define instrCntIncr tickInstrCnt++;
01118 #define instrCntIncrc tickInstrCnt++,
01119 #define instrCntDecr tickInstrCnt--;
01120 #else
01121 #define instrCntIncr
01122 #define instrCntIncrc
01123 #define instrCntDecr
01124 #endif
01125
01126
01128 #ifdef _SC_NOTRACE
01129 #define trace0(f)
01130 #define trace1(f, a)
01131 #define trace2(f, a, b)
01132 #define trace3(f, a, b, c)
01133 #define trace4(f, a, b, c, d)
01134 #define trace5(f, a, b, c, d, e)
01135 #define trace6(f, a, b, c, d, e, g)
01136 #define trace7(f, a, b, c, d, e, g, h)
01137 #define trace8(f, a, b, c, d, e, g, h, i)
01138 #define trace0c(f)
01139 #define trace1c(f, a)
01140 #define trace2c(f, a, b)
01141 #define trace3c(f, a, b, c)
01142 #define elsetrace
01143 #define elsetraceend
01144 #else
01145 #define trace0(f) printf(f);
01146 #define trace1(f, a) printf(f, a);
01147 #define trace2(f, a, b) printf(f, a, b);
01148 #define trace3(f, a, b, c) printf(f, a, b, c);
01149 #define trace4(f, a, b, c, d) printf(f, a, b, c, d);
01150 #define trace5(f, a, b, c, d, e) printf(f, a, b, c, d, e);
01151 #define trace6(f, a, b, c, d, e, g) printf(f, a, b, c, d, e, g);
01152 #define trace7(f, a, b, c, d, e, g, h) printf(f, a, b, c, d, e, g, h);
01153 #define trace8(f, a, b, c, d, e, g, h, i) printf(f, a, b, c, d, e, g, h, i);
01154 #define trace0c(f) printf(f),
01155 #define trace1c(f, a) printf(f, a),
01156 #define trace2c(f, a, b) printf(f, a, b),
01157 #define trace3c(f, a, b, c) printf(f, a, b, c),
01158 #define elsetrace else {
01159 #define elsetraceend }
01160 #endif
01161
01162
01164
01168 #define traceThread(s) \
01169 instrCntIncr \
01170 trace3("%-9s %d/%s ", s, _cid, state[_cid])
01171
01172
01173
01174 #define traceThreadc(s) \
01175 instrCntIncrc \
01176 trace3c("%-9s %d/%s ", s, _cid, state[_cid])
01177
01178
01180
01185 #define trace0t(s, f) traceThread(s) trace0(f)
01186 #define trace1t(s, f, a) traceThread(s) trace1(f, a)
01187 #define trace2t(s, f, a, b) traceThread(s) trace2(f, a, b)
01188 #define trace3t(s, f, a, b, c) traceThread(s) trace3(f, a, b, c)
01189 #define trace4t(s, f, a, b, c, d) traceThread(s) trace4(f, a, b, c, d)
01190 #define trace5t(s, f, a, b, c, d, e) traceThread(s) trace5(f, a, b, c, d, e)
01191 #define trace6t(s, f, a, b, c, d, e, f1) traceThread(s) trace6(f, a, b, c, d, e, f1)
01192 #define trace7t(s, f, a, b, c, d, e, f1, g) traceThread(s) trace7(f, a, b, c, d, e, f1, g)
01193 #define trace8t(s, f, a, b, c, d, e, f1, g, h) traceThread(s) trace7(f, a, b, c, d, e, f1, g, h)
01194
01195
01196
01197 #define trace0tc(s, f) traceThreadc(s) trace0c(f)
01198 #define trace1tc(s, f, a) traceThreadc(s) trace1c(f, a)
01199 #define trace2tc(s, f, a, b) traceThreadc(s) trace2c(f, a, b)
01200 #define trace3tc(s, f, a, b, c) traceThreadc(s) trace3c(f, a, b, c)
01201
01202
01203
01204
01205
01206 #define _SC_ERROR_NONE 0
01207 #define _SC_ERROR_NORESET 1
01208 #define _SC_ERROR_PRIORITY 2
01209 #define _SC_ERROR_CAUSALITY 3
01210
01212
01216 #ifndef _SC_SUPPRESS_ERROR_DETECT
01217 #include <stdlib.h>
01218 #define _SC_ERROR0(code, f) fprintf(stderr, f); exit(code);
01219 #define _SC_ERROR1(code, f, a) fprintf(stderr, f, a); exit(code);
01220 #define _SC_ERROR2(code, f, a, b) fprintf(stderr, f, a, b); exit(code);
01221 #define _SC_ERROR3(code, f, a, b, c) fprintf(stderr, f, a, b, c); exit(code);
01222 #endif