summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--parse.adb11
-rw-r--r--translate/gcc/dist-common.sh3
-rw-r--r--translate/grt/Makefile.inc10
-rw-r--r--translate/grt/config/pthread.c148
-rw-r--r--translate/grt/config/win32thr.c167
-rw-r--r--translate/grt/grt-sdf.adb16
6 files changed, 294 insertions, 61 deletions
diff --git a/parse.adb b/parse.adb
index 27a14cd..f4cfa21 100644
--- a/parse.adb
+++ b/parse.adb
@@ -288,7 +288,7 @@ package body Parse is
end if;
Scan.Scan;
if Current_Token = Tok_Box then
- Unexpected ("<> not allowed here");
+ Unexpected ("range expression expected");
Scan.Scan;
return Null_Iir;
end if;
@@ -385,6 +385,12 @@ package body Parse is
end if;
Scan.Scan;
+ if Current_Token = Tok_Box then
+ Error_Msg_Parse ("range constraint required");
+ Scan.Scan;
+ return Null_Iir;
+ end if;
+
return Parse_Range;
end Parse_Range_Constraint;
@@ -407,6 +413,9 @@ package body Parse is
when Tok_Range =>
-- FIXME: create a subtype indication.
Rng := Parse_Range_Constraint;
+ if Rng = Null_Iir then
+ return Left;
+ end if;
Set_Type (Rng, Left);
return Rng;
when others =>
diff --git a/translate/gcc/dist-common.sh b/translate/gcc/dist-common.sh
index fa63791..46d3478 100644
--- a/translate/gcc/dist-common.sh
+++ b/translate/gcc/dist-common.sh
@@ -256,4 +256,5 @@ times.c
clock.c
linux.c
pthread.c
-win32.c"
+win32.c
+win32thr.c"
diff --git a/translate/grt/Makefile.inc b/translate/grt/Makefile.inc
index ec0d4d0..002d177 100644
--- a/translate/grt/Makefile.inc
+++ b/translate/grt/Makefile.inc
@@ -72,9 +72,10 @@ endif
ifeq ($(filter-out i%86 mingw32,$(arch) $(osys)),)
GRT_TARGET_OBJS=win32.o clock.o
endif
-ifeq ($(filter-out i%86 cygwin,$(arch) $(osys)),)
- GRT_TARGET_OBJS=win32.o clock.o
-endif
+# Doesn't work for unknown reasons.
+#ifeq ($(filter-out i%86 cygwin,$(arch) $(osys)),)
+# GRT_TARGET_OBJS=win32.o clock.o
+#endif
# Fall-back: use a generic implementation based on pthreads.
ifndef GRT_TARGET_OBJS
GRT_TARGET_OBJS=pthread.o times.o
@@ -142,6 +143,9 @@ linux.o: $(GRTSRCDIR)/config/linux.c
win32.o: $(GRTSRCDIR)/config/win32.c
$(CC) -c $(GRT_FLAGS) -o $@ $<
+win32thr.o: $(GRTSRCDIR)/config/win32thr.c
+ $(CC) -c $(GRT_FLAGS) -o $@ $<
+
pthread.o: $(GRTSRCDIR)/config/pthread.c
$(CC) -c $(GRT_FLAGS) -o $@ $<
diff --git a/translate/grt/config/pthread.c b/translate/grt/config/pthread.c
index d42a753..f619ead 100644
--- a/translate/grt/config/pthread.c
+++ b/translate/grt/config/pthread.c
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
+#include <assert.h>
//#define INFO printf
#define INFO (void)
@@ -35,10 +36,14 @@
// GHDL names an endless loop calling FUNC with ARG a 'stack'
// at a given time, only one stack may be 'executed'
typedef struct
-{ pthread_t thread; // stack's thread
- pthread_mutex_t mutex; // mutex to suspend/resume thread
- void (*Func)(void*); // stack's FUNC
- void* Arg; // ARG passed to FUNC
+{
+ pthread_t thread; // stack's thread
+ pthread_mutex_t mutex; // mutex to suspend/resume thread
+#if defined(__CYGWIN__)
+ pthread_mutexattr_t mxAttr;
+#endif
+ void (*Func)(void*); // stack's FUNC
+ void* Arg; // ARG passed to FUNC
} Stack_Type_t, *Stack_Type;
static Stack_Type_t main_stack_context;
@@ -51,40 +56,56 @@ void grt_stack_init(void)
// This may adjust stack sizes.
// Must be called after grt.options.decode.
// => procedure Stack_Init;
-{ INFO("grt_stack_init\n");
- INFO(" main_stack_context=0x%08x\n", &main_stack_context);
+{
+ int res;
+ INFO("grt_stack_init\n");
+ INFO(" main_stack_context=0x%08x\n", &main_stack_context);
- pthread_mutex_init(&(main_stack_context.mutex), NULL);
- // lock the mutex, as we are currently running
- pthread_mutex_lock(&(main_stack_context.mutex));
+#if defined(__CYGWIN__)
+ res = pthread_mutexattr_init (&main_stack_context.mxAttr);
+ assert (res == 0);
+ res = pthread_mutexattr_settype (&main_stack_context.mxAttr,
+ PTHREAD_MUTEX_DEFAULT);
+ assert (res == 0);
+ res = pthread_mutex_init (&main_stack_context.mutex,
+ &main_stack_context.mxAttr);
+ assert (res == 0);
+#else
+ res = pthread_mutex_init (&main_stack_context.mutex, NULL);
+ assert (res == 0);
+#endif
+ // lock the mutex, as we are currently running
+ res = pthread_mutex_lock (&main_stack_context.mutex);
+ assert (res == 0);
- current = &main_stack_context;
+ current = &main_stack_context;
- grt_set_main_stack (&main_stack_context);
+ grt_set_main_stack (&main_stack_context);
}
//----------------------------------------------------------------------------
static void* grt_stack_loop(void* pv_myStack)
{
- Stack_Type myStack= (Stack_Type)pv_myStack;
+ Stack_Type myStack= (Stack_Type)pv_myStack;
- INFO("grt_stack_loop\n");
+ INFO("grt_stack_loop\n");
- INFO(" myStack=0x%08x\n", myStack);
+ INFO(" myStack=0x%08x\n", myStack);
- // block until mutex becomes available again.
- // this happens when this stack is enabled for the first time
- pthread_mutex_lock(&(myStack->mutex));
+ // block until mutex becomes available again.
+ // this happens when this stack is enabled for the first time
+ pthread_mutex_lock(&(myStack->mutex));
- // run stack's function in endless loop
- while(1)
- { INFO(" call 0x%08x with 0x%08x\n", myStack->Func, myStack->Arg);
- myStack->Func(myStack->Arg);
- }
+ // run stack's function in endless loop
+ while(1)
+ {
+ INFO(" call 0x%08x with 0x%08x\n", myStack->Func, myStack->Arg);
+ myStack->Func(myStack->Arg);
+ }
- // we never get here...
- return 0;
+ // we never get here...
+ return 0;
}
//----------------------------------------------------------------------------
@@ -93,29 +114,41 @@ Stack_Type grt_stack_create(void* Func, void* Arg)
// an argument ARG.
// => function Stack_Create (Func : Address; Arg : Address) return Stack_Type;
{
- Stack_Type newStack;
+ Stack_Type newStack;
+ int res;
- INFO("grt_stack_create\n");
- INFO(" call 0x%08x with 0x%08x\n", Func, Arg);
+ INFO("grt_stack_create\n");
+ INFO(" call 0x%08x with 0x%08x\n", Func, Arg);
- newStack= malloc(sizeof(Stack_Type_t));
-
- // init function and argument
- newStack->Func= Func;
- newStack->Arg= Arg;
+ newStack = malloc (sizeof(Stack_Type_t));
- // create mutex
- pthread_mutex_init(&(newStack->mutex), NULL);
+ // init function and argument
+ newStack->Func = Func;
+ newStack->Arg = Arg;
- // block the mutex, so that thread will blocked in grt_stack_loop
- pthread_mutex_lock(&(newStack->mutex));
+ // create mutex
+#if defined(__CYGWIN__)
+ res = pthread_mutexattr_init (&newStack->mxAttr);
+ assert (res == 0);
+ res = pthread_mutexattr_settype (&newStack->mxAttr, PTHREAD_MUTEX_DEFAULT);
+ assert (res == 0);
+ res = pthread_mutex_init (&newStack->mutex, &newStack->mxAttr);
+ assert (res == 0);
+#else
+ res = pthread_mutex_init (&newStack->mutex, NULL);
+ assert (res == 0);
+#endif
- INFO(" newStack=0x%08x\n", newStack);
+ // block the mutex, so that thread will blocked in grt_stack_loop
+ res = pthread_mutex_lock (&newStack->mutex);
+ assert (res == 0);
+
+ INFO(" newStack=0x%08x\n", newStack);
- // create thread, which executes grt_stack_loop
- pthread_create(&(newStack->thread), NULL, grt_stack_loop, newStack);
+ // create thread, which executes grt_stack_loop
+ pthread_create (&newStack->thread, NULL, grt_stack_loop, newStack);
- return newStack;
+ return newStack;
}
static int need_longjmp;
@@ -127,30 +160,35 @@ void grt_stack_switch(Stack_Type To, Stack_Type From)
// Resume stack TO and save the current context to the stack pointed by
// CUR.
// => procedure Stack_Switch (To : Stack_Type; From : Stack_Type);
-{ INFO("grt_stack_switch\n");
- INFO(" from 0x%08x to 0x%08x\n", From, To);
+{
+ int res;
+ INFO("grt_stack_switch\n");
+ INFO(" from 0x%08x to 0x%08x\n", From, To);
- current = To;
+ current = To;
- // unlock 'To' mutex. this will make the other thread either
- // - starts for first time in grt_stack_loop
- // - resumes at lock below
- pthread_mutex_unlock(&(To->mutex));
+ // unlock 'To' mutex. this will make the other thread either
+ // - starts for first time in grt_stack_loop
+ // - resumes at lock below
+ res = pthread_mutex_unlock (&To->mutex);
+ assert (res == 0);
- // block until 'From' mutex becomes available again
- // as we are running, our mutex is locked and we block here
- // when stacks are switched, with above unlock, we may proceed
- pthread_mutex_lock(&(From->mutex));
-
- if (From == &main_stack_context && need_longjmp != 0)
- longjmp (run_env, need_longjmp);
+ // block until 'From' mutex becomes available again
+ // as we are running, our mutex is locked and we block here
+ // when stacks are switched, with above unlock, we may proceed
+ res = pthread_mutex_lock (&From->mutex);
+ assert (res == 0);
+
+ if (From == &main_stack_context && need_longjmp != 0)
+ longjmp (run_env, need_longjmp);
}
//----------------------------------------------------------------------------
void grt_stack_delete(Stack_Type Stack)
// Delete stack STACK, which must not be currently executed.
// => procedure Stack_Delete (Stack : Stack_Type);
-{ INFO("grt_stack_delete\n");
+{
+ INFO("grt_stack_delete\n");
}
void
diff --git a/translate/grt/config/win32thr.c b/translate/grt/config/win32thr.c
new file mode 100644
index 0000000..bcebc49
--- /dev/null
+++ b/translate/grt/config/win32thr.c
@@ -0,0 +1,167 @@
+/* GRT stack implementation for Win32
+ Copyright (C) 2004, 2005 Felix Bertram.
+
+ GHDL 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 2, or (at your option) any later
+ version.
+
+ GHDL 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 GCC; see the file COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+*/
+//-----------------------------------------------------------------------------
+// Project: GHDL - VHDL Simulator
+// Description: Win32 port of stacks package
+// Note: Tristan's original i386/Linux used assembly-code
+// to manually switch stacks for performance reasons.
+// History: 2004feb09, FB, created.
+//-----------------------------------------------------------------------------
+
+#include <windows.h>
+//#include <pthread.h>
+//#include <stdlib.h>
+//#include <stdio.h>
+
+
+//#define INFO printf
+#define INFO (void)
+
+// GHDL names an endless loop calling FUNC with ARG a 'stack'
+// at a given time, only one stack may be 'executed'
+typedef struct
+{ HANDLE thread; // stack's thread
+ HANDLE mutex; // mutex to suspend/resume thread
+ void (*Func)(void*); // stack's FUNC
+ void* Arg; // ARG passed to FUNC
+} Stack_Type_t, *Stack_Type;
+
+
+static Stack_Type_t main_stack_context;
+extern void grt_set_main_stack (Stack_Type_t *stack);
+
+//------------------------------------------------------------------------------
+void grt_stack_init(void)
+// Initialize the stacks package.
+// This may adjust stack sizes.
+// Must be called after grt.options.decode.
+// => procedure Stack_Init;
+{ INFO("grt_stack_init\n");
+ INFO(" main_stack_context=0x%08x\n", &main_stack_context);
+
+ // create event. reset event, as we are currently running
+ main_stack_context.mutex = CreateEvent(NULL, // lpsa
+ FALSE, // fManualReset
+ FALSE, // fInitialState
+ NULL); // lpszEventName
+
+ grt_set_main_stack (&main_stack_context);
+}
+
+//------------------------------------------------------------------------------
+static unsigned long __stdcall grt_stack_loop(void* pv_myStack)
+{
+ Stack_Type myStack= (Stack_Type)pv_myStack;
+
+ INFO("grt_stack_loop\n");
+
+ INFO(" myStack=0x%08x\n", myStack);
+
+ // block until event becomes set again.
+ // this happens when this stack is enabled for the first time
+ WaitForSingleObject(myStack->mutex, INFINITE);
+
+ // run stack's function in endless loop
+ while(1)
+ { INFO(" call 0x%08x with 0x%08x\n", myStack->Func, myStack->Arg);
+ myStack->Func(myStack->Arg);
+ }
+
+ // we never get here...
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+Stack_Type grt_stack_create(void* Func, void* Arg)
+// Create a new stack, which on first execution will call FUNC with
+// an argument ARG.
+// => function Stack_Create (Func : Address; Arg : Address) return Stack_Type;
+{ Stack_Type newStack;
+ DWORD m_IDThread; // Thread's ID (dummy)
+
+ INFO("grt_stack_create\n");
+ INFO(" call 0x%08x with 0x%08x\n", Func, Arg);
+
+ newStack= malloc(sizeof(Stack_Type_t));
+
+ // init function and argument
+ newStack->Func= Func;
+ newStack->Arg= Arg;
+
+ // create event. reset event, so that thread will blocked in grt_stack_loop
+ newStack->mutex= CreateEvent(NULL, // lpsa
+ FALSE, // fManualReset
+ FALSE, // fInitialState
+ NULL); // lpszEventName
+
+ INFO(" newStack=0x%08x\n", newStack);
+
+ // create thread, which executes grt_stack_loop
+ newStack->thread= CreateThread(NULL, // lpsa
+ 0, // cbStack
+ grt_stack_loop, // lpStartAddr
+ newStack, // lpvThreadParm
+ 0, // fdwCreate
+ &m_IDThread); // lpIDThread
+
+ return newStack;
+}
+
+//------------------------------------------------------------------------------
+void grt_stack_switch(Stack_Type To, Stack_Type From)
+// Resume stack TO and save the current context to the stack pointed by
+// CUR.
+// => procedure Stack_Switch (To : Stack_Type; From : Stack_Type);
+{ INFO("grt_stack_switch\n");
+ INFO(" from 0x%08x to 0x%08x\n", From, To);
+
+ // set 'To' event. this will make the other thread either
+ // - start for first time in grt_stack_loop
+ // - resume at WaitForSingleObject below
+ SetEvent(To->mutex);
+
+ // block until 'From' event becomes set again
+ // as we are running, our event is reset and we block here
+ // when stacks are switched, with above SetEvent, we may proceed
+ WaitForSingleObject(From->mutex, INFINITE);
+}
+
+//------------------------------------------------------------------------------
+void grt_stack_delete(Stack_Type Stack)
+// Delete stack STACK, which must not be currently executed.
+// => procedure Stack_Delete (Stack : Stack_Type);
+{ INFO("grt_stack_delete\n");
+}
+
+//----------------------------------------------------------------------------
+#ifndef WITH_GNAT_RUN_TIME
+void __gnat_raise_storage_error(void)
+{
+ abort ();
+}
+
+void __gnat_raise_program_error(void)
+{
+ abort ();
+}
+#endif
+
+//----------------------------------------------------------------------------
+// end of file
+
diff --git a/translate/grt/grt-sdf.adb b/translate/grt/grt-sdf.adb
index c7391cc..360b461 100644
--- a/translate/grt/grt-sdf.adb
+++ b/translate/grt/grt-sdf.adb
@@ -315,7 +315,21 @@ package body Grt.Sdf is
Pos := Pos + 1;
when '/' =>
Pos := Pos + 1;
- return Tok_Div;
+ if Buf (Pos) = '/' then
+ Pos := Pos + 1;
+ -- Skip line comment.
+ loop
+ exit when Buf (Pos) = CR;
+ exit when Buf (Pos) = LF;
+ exit when Buf (Pos) = EOT;
+ Pos := Pos + 1;
+ if Pos >= Buf_Len then
+ Refill_Buf;
+ end if;
+ end loop;
+ else
+ return Tok_Div;
+ end if;
when '.' =>
Pos := Pos + 1;
return Tok_Dot;