Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 5 commits
  • 8 files changed
  • 0 commit comments
  • 1 contributor
View
219 src/cgen.c
@@ -1750,18 +1750,35 @@ static void cgen_array_signal_store(LLVMValueRef lhs, type_t lhs_type,
{
assert(type_is_array(lhs_type));
+ int levels = 0;
+ type_t elem = lhs_type;
+ do {
+ elem = type_elem(elem);
+ levels++;
+ } while (type_is_array(elem));
+
char name[256];
- snprintf(name, sizeof(name), "%s_vec_store",
- istr(type_ident(type_elem(lhs_type))));
+ snprintf(name, sizeof(name), "%s_vec_store", istr(type_ident(elem)));
LLVMValueRef rhs_data = cgen_array_data_ptr(rhs_type, rhs);
- LLVMValueRef indexes[] = { llvm_int32(0) };
- LLVMValueRef p_rhs = LLVMBuildGEP(builder, rhs_data, indexes, 1, "");
+ LLVMValueRef indexes[levels];
+ for (int i = 0; i < levels; i++)
+ indexes[i] = llvm_int32(0);
+ LLVMValueRef p_rhs = LLVMBuildGEP(builder, rhs_data, indexes, levels, "");
- LLVMValueRef n_elems = cgen_array_len(rhs_type, rhs);
+ LLVMValueRef p_lhs = lhs;
+ if (levels > 1)
+ p_lhs = LLVMBuildGEP(builder, lhs, indexes, levels, "");
+
+ LLVMValueRef n_elems = llvm_int32(1);
+ type_t dim = rhs_type;
+ for (int i = 0; i < levels; i++) {
+ LLVMValueRef dim_len = cgen_array_len(dim, rhs);
+ n_elems = LLVMBuildMul(builder, n_elems, dim_len, "");
+ }
- LLVMValueRef args[] = { lhs, p_rhs, n_elems };
+ LLVMValueRef args[] = { p_lhs, p_rhs, n_elems };
LLVMBuildCall(builder, llvm_fn(name), args, ARRAY_LEN(args), "");
}
@@ -2380,6 +2397,9 @@ static void cgen_array_signal_load_fn(type_t elem_type)
{
// Build a function to load the array into a temporary
+ while (type_is_array(elem_type))
+ elem_type = type_elem(elem_type);
+
char name[256];
snprintf(name, sizeof(name), "%s_vec_load",
istr(type_ident(elem_type)));
@@ -2407,12 +2427,8 @@ static void cgen_array_signal_load_fn(type_t elem_type)
LLVMBasicBlockRef merge_bb = LLVMAppendBasicBlock(fn, "merge");
LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlock(fn, "exit");
- LLVMBasicBlockRef norm_bb = NULL;
- LLVMBasicBlockRef last_bb = NULL;
- if (!type_is_array(elem_type)) {
- norm_bb = LLVMAppendBasicBlock(fn, "normal");
- last_bb = LLVMAppendBasicBlock(fn, "last");
- }
+ LLVMBasicBlockRef norm_bb = LLVMAppendBasicBlock(fn, "normal");
+ LLVMBasicBlockRef last_bb = LLVMAppendBasicBlock(fn, "last");
// Prelude
LLVMPositionBuilderAtEnd(builder, entry_bb);
@@ -2436,69 +2452,37 @@ static void cgen_array_signal_load_fn(type_t elem_type)
index, ARRAY_LEN(index),
"signal");
- if (type_is_array(elem_type)) {
- // Recursively load the sub-array
+ // Select either the current or last value
- char sub_name[256];
- snprintf(sub_name, sizeof(sub_name), "%s_vec_load",
- istr(type_ident(type_elem(elem_type))));
+ LLVMBuildCondBr(builder, LLVMGetParam(fn, 4), last_bb, norm_bb);
- cgen_array_signal_load_fn(type_elem(elem_type));
+ LLVMPositionBuilderAtEnd(builder, last_bb);
+ LLVMValueRef ptr_last =
+ LLVMBuildStructGEP(builder, signal, SIGNAL_LAST_VALUE, "last_value");
+ LLVMBuildBr(builder, merge_bb);
- LLVMValueRef indexes[] = {
- LLVMBuildSub(builder, i_loaded, LLVMGetParam(fn, 2), ""),
- llvm_int32(0)
- };
- LLVMValueRef dst = LLVMBuildGEP(builder, LLVMGetParam(fn, 1),
- indexes, ARRAY_LEN(indexes), "dst");
- LLVMValueRef src = LLVMBuildGEP(builder, signal,
- indexes, ARRAY_LEN(indexes), "src");
+ LLVMPositionBuilderAtEnd(builder, norm_bb);
+ LLVMValueRef ptr_resolved =
+ LLVMBuildStructGEP(builder, signal, SIGNAL_RESOLVED, "resolved");
+ LLVMBuildBr(builder, merge_bb);
- range_t r = type_dim(elem_type, 0);
- LLVMValueRef left = llvm_int32(assume_int(r.left));
- LLVMValueRef right = llvm_int32(assume_int(r.right));
-
- LLVMValueRef args[] = {
- src, dst, left, right, LLVMGetParam(fn, 4)
- };
- LLVMBuildCall(builder, llvm_fn(sub_name), args, ARRAY_LEN(args), "");
-
- LLVMBuildBr(builder, merge_bb);
- LLVMPositionBuilderAtEnd(builder, merge_bb);
- }
- else {
- // Select either the current or last value
+ LLVMPositionBuilderAtEnd(builder, merge_bb);
+ LLVMValueRef phi = LLVMBuildPhi(builder, LLVMTypeOf(ptr_last), "ptr");
- LLVMBuildCondBr(builder, LLVMGetParam(fn, 4), last_bb, norm_bb);
-
- LLVMPositionBuilderAtEnd(builder, last_bb);
- LLVMValueRef ptr_last =
- LLVMBuildStructGEP(builder, signal, SIGNAL_LAST_VALUE, "last_value");
- LLVMBuildBr(builder, merge_bb);
-
- LLVMPositionBuilderAtEnd(builder, norm_bb);
- LLVMValueRef ptr_resolved =
- LLVMBuildStructGEP(builder, signal, SIGNAL_RESOLVED, "resolved");
- LLVMBuildBr(builder, merge_bb);
-
- LLVMPositionBuilderAtEnd(builder, merge_bb);
- LLVMValueRef phi = LLVMBuildPhi(builder, LLVMTypeOf(ptr_last), "ptr");
-
- LLVMValueRef values[] = { ptr_last, ptr_resolved };
- LLVMBasicBlockRef bbs[] = { last_bb, norm_bb };
- LLVMAddIncoming(phi, values, bbs, 2);
+ LLVMValueRef values[] = { ptr_last, ptr_resolved };
+ LLVMBasicBlockRef bbs[] = { last_bb, norm_bb };
+ LLVMAddIncoming(phi, values, bbs, 2);
- LLVMValueRef deref = LLVMBuildLoad(builder, phi, "deref");
- LLVMValueRef val = LLVMBuildIntCast(builder, deref,
- llvm_type(elem_type), "val");
- LLVMValueRef dst_index[] = {
- LLVMBuildSub(builder, i_loaded, LLVMGetParam(fn, 2), "")
- };
- LLVMValueRef dst = LLVMBuildGEP(builder, LLVMGetParam(fn, 1),
- dst_index, ARRAY_LEN(dst_index),
- "dst");
- LLVMBuildStore(builder, val, dst);
- }
+ LLVMValueRef deref = LLVMBuildLoad(builder, phi, "deref");
+ LLVMValueRef val = LLVMBuildIntCast(builder, deref,
+ llvm_type(elem_type), "val");
+ LLVMValueRef dst_index[] = {
+ LLVMBuildSub(builder, i_loaded, LLVMGetParam(fn, 2), "")
+ };
+ LLVMValueRef dst = LLVMBuildGEP(builder, LLVMGetParam(fn, 1),
+ dst_index, ARRAY_LEN(dst_index),
+ "dst");
+ LLVMBuildStore(builder, val, dst);
LLVMValueRef inc =
LLVMBuildAdd(builder, i_loaded, llvm_int32(1), "inc");
@@ -2516,6 +2500,9 @@ static void cgen_array_signal_store_fn(type_t elem_type)
{
// Build a function to schedule an array assignment
+ while (type_is_array(elem_type))
+ elem_type = type_elem(elem_type);
+
char name[256];
snprintf(name, sizeof(name), "%s_vec_store",
istr(type_ident(elem_type)));
@@ -2541,82 +2528,25 @@ static void cgen_array_signal_store_fn(type_t elem_type)
LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock(fn, "entry");
LLVMPositionBuilderAtEnd(builder, entry_bb);
- if (type_is_array(elem_type)) {
- // Recursively store each sub-array
-
- LLVMBasicBlockRef test_bb = LLVMAppendBasicBlock(fn, "test");
- LLVMBasicBlockRef body_bb = LLVMAppendBasicBlock(fn, "body");
- LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlock(fn, "exit");
-
- // Prelude
- LLVMValueRef i = LLVMBuildAlloca(builder, LLVMInt32Type(), "i");
- LLVMBuildStore(builder, llvm_int32(0), i);
- LLVMBuildBr(builder, test_bb);
-
- // Loop test
- LLVMPositionBuilderAtEnd(builder, test_bb);
- LLVMValueRef i_loaded = LLVMBuildLoad(builder, i, "");
- LLVMValueRef ge = LLVMBuildICmp(builder, LLVMIntUGE,
- LLVMGetParam(fn, 2),
- i_loaded, "ge");
- LLVMBuildCondBr(builder, ge, body_bb, exit_bb);
-
- // Loop body
- LLVMPositionBuilderAtEnd(builder, body_bb);
-
- LLVMValueRef index[] = { i_loaded };
- LLVMValueRef signal = LLVMBuildGEP(builder, LLVMGetParam(fn, 0),
- index, ARRAY_LEN(index),
- "signal");
-
- char sub_name[256];
- snprintf(sub_name, sizeof(sub_name), "%s_vec_store",
- istr(type_ident(type_elem(elem_type))));
-
- cgen_array_signal_store_fn(type_elem(elem_type));
-
- LLVMValueRef indexes[] = {
- LLVMBuildSub(builder, i_loaded, LLVMGetParam(fn, 2), ""),
- llvm_int32(0)
- };
- LLVMValueRef dst = LLVMBuildGEP(builder, LLVMGetParam(fn, 1),
- indexes, ARRAY_LEN(indexes), "dst");
- LLVMValueRef src = LLVMBuildGEP(builder, signal,
- indexes, ARRAY_LEN(indexes), "src");
-
- LLVMValueRef args[] = {
- src, dst, cgen_array_len(elem_type, NULL)
- };
- LLVMBuildCall(builder, llvm_fn(sub_name), args, ARRAY_LEN(args), "");
-
- LLVMValueRef inc =
- LLVMBuildAdd(builder, i_loaded, llvm_int32(1), "inc");
- LLVMBuildStore(builder, inc, i);
- LLVMBuildBr(builder, test_bb);
+ LLVMValueRef dst_index[] = { llvm_int32(0) };
+ LLVMValueRef signal = LLVMBuildGEP(builder, LLVMGetParam(fn, 0),
+ dst_index, ARRAY_LEN(dst_index),
+ "signal");
- LLVMPositionBuilderAtEnd(builder, exit_bb);
- }
- else {
- LLVMValueRef dst_index[] = { llvm_int32(0) };
- LLVMValueRef signal = LLVMBuildGEP(builder, LLVMGetParam(fn, 0),
- dst_index, ARRAY_LEN(dst_index),
- "signal");
-
- LLVMValueRef src_index[] = { llvm_int32(0) };
- LLVMValueRef p_src = LLVMBuildGEP(builder, LLVMGetParam(fn, 1),
- src_index, ARRAY_LEN(src_index),
+ LLVMValueRef src_index[] = { llvm_int32(0) };
+ LLVMValueRef p_src = LLVMBuildGEP(builder, LLVMGetParam(fn, 1),
+ src_index, ARRAY_LEN(src_index),
"p_src");
- LLVMValueRef args[] = {
- llvm_void_cast(signal),
- llvm_int32(0 /* source, TODO */),
- llvm_void_cast(p_src),
- LLVMGetParam(fn, 2), // Number of element
- llvm_sizeof(ll_elem_type),
- llvm_int64(0 /* after, TODO */)
- };
- LLVMBuildCall(builder, llvm_fn("_sched_waveform_vec"),
- args, ARRAY_LEN(args), "");
- }
+ LLVMValueRef args[] = {
+ llvm_void_cast(signal),
+ llvm_int32(0 /* source, TODO */),
+ llvm_void_cast(p_src),
+ LLVMGetParam(fn, 2), // Number of element
+ llvm_sizeof(ll_elem_type),
+ llvm_int64(0 /* after, TODO */)
+ };
+ LLVMBuildCall(builder, llvm_fn("_sched_waveform_vec"),
+ args, ARRAY_LEN(args), "");
LLVMBuildRetVoid(builder);
@@ -3064,8 +2994,7 @@ void cgen(tree_t top)
if (LLVMVerifyModule(module, LLVMPrintMessageAction, NULL))
fatal("LLVM verification failed");
- if (opt_get_int("optimise"))
- optimise();
+ optimise();
char fname[256];
snprintf(fname, sizeof(fname), "_%s.bc", istr(tree_ident(top)));
View
6 src/nvc.c
@@ -411,9 +411,13 @@ static void version(void)
int main(int argc, char **argv)
{
term_init();
- register_trace_signal_handlers();
set_default_opts();
+ if (getenv("NVC_GDB") != NULL)
+ register_gdb_signal_handlers();
+ else
+ register_trace_signal_handlers();
+
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
View
8 src/rt/rtkern.c
@@ -993,11 +993,9 @@ static void rt_cleanup(tree_t top)
struct signal *sig = tree_attr_ptr(d, i_signal);
type_t type = tree_type(d);
- if (type_kind(type) == T_CARRAY) {
- int64_t low, high;
- range_bounds(type_dim(type, 0), &low, &high);
-
- for (unsigned i = 0; i < high - low + 1; i++)
+ if (type_is_array(type)) {
+ int size = array_size(type);
+ for (unsigned i = 0; i < size; i++)
rt_cleanup_signal(&sig[i]);
}
else
View
48 src/util.c
@@ -417,6 +417,8 @@ static void bt_sighandler(int sig, siginfo_t *info, void *secret)
exit(EXIT_FAILURE);
}
+#endif // NO_STACK_TRACE
+
static bool is_debugger_running(void)
{
#if defined __APPLE__
@@ -491,7 +493,29 @@ static bool is_debugger_running(void)
#endif
}
-#endif // NO_STACK_TRACE
+static void gdb_sighandler(int sig, siginfo_t *info)
+{
+ char exe[256];
+ if (readlink("/proc/self/exe", exe, sizeof(exe)) < 0)
+ fatal_errno("readlink");
+
+ char pid[16];
+ snprintf(pid, sizeof(pid), "%d", getpid());
+
+ pid_t p = fork();
+ if (p == 0) {
+ execl("/usr/bin/gdb", "gdb", "-ex", "cont", exe, pid, NULL);
+ fatal_errno("execl");
+ }
+ else if (p < 0)
+ fatal_errno("fork");
+ else {
+ // Allow a little time for GDB to start before dropping
+ // into the default signal handler
+ sleep(1);
+ signal(sig, SIG_DFL);
+ }
+}
void register_trace_signal_handlers(void)
{
@@ -513,6 +537,28 @@ void register_trace_signal_handlers(void)
#endif // NO_STACK_TRACE
}
+void register_gdb_signal_handlers(void)
+{
+#ifdef __linux
+ if (is_debugger_running())
+ return;
+
+ struct sigaction sa;
+ sa.sa_sigaction = (void*)gdb_sighandler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART | SA_SIGINFO;
+
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGUSR1, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+ sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGABRT, &sa, NULL);
+#else // __linux
+ register_trace_signal_handlers();
+#endif // __linux
+}
+
void write_u32(uint32_t u, FILE *f)
{
if (fwrite(&u, sizeof(uint32_t), 1, f) != 1)
View
1  src/util.h
@@ -67,6 +67,7 @@ void fmt_loc(FILE *f, const loc_t *loc);
void show_stacktrace(void);
void register_trace_signal_handlers(void);
+void register_gdb_signal_handlers(void);
void term_init(void);
View
2  test/regress/signal8.vhd
@@ -11,7 +11,7 @@ begin
process is
begin
- -- a(1)(2) <= 2;
+ a(1)(2) <= 2;
--assert a(1)(2) = 2;
-- a := ( others => ( 1, 2, 3, 4 ) );
-- b := a(1);
View
1  test/regress/testlist.txt
@@ -68,3 +68,4 @@ case3 normal
wait6 normal,gold
elab4 normal
elab5 normal
+signal8 normal
View
2  test/run_regr.rb
@@ -58,7 +58,7 @@ def analyse(t)
end
def elaborate(t)
- run_cmd "#{nvc} -e #{t[:name]}"
+ run_cmd "#{nvc} -e #{t[:name]} --disable-opt"
end
def run(t)

No commit comments for this range

Something went wrong with that request. Please try again.