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.
base: 1212c0abe2
...
compare: 7d50e70ab9
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.