Skip to content

Comparing changes

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

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
  • 2 commits
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Showing with 54 additions and 29 deletions.
  1. +40 −25 src/cgen.c
  2. +14 −4 test/regress/signal8.vhd
View
65 src/cgen.c
@@ -661,21 +661,21 @@ static LLVMValueRef cgen_literal(tree_t t)
}
}
-static LLVMValueRef cgen_array_signal_ref(tree_t decl, type_t slice_type,
- cgen_ctx_t *ctx, bool last_value)
+static LLVMValueRef cgen_vec_load(LLVMValueRef signal, type_t type,
+ type_t slice_type, bool last_value,
+ cgen_ctx_t *ctx)
{
- type_t type = tree_type(decl);
- assert(type_kind(type) == T_CARRAY);
-
// Copy the resolved signal into a temporary array
+
LLVMValueRef tmp = LLVMBuildAlloca(builder, llvm_type(slice_type),
- istr(tree_ident(decl)));
+ "vec_load_tmp");
char name[256];
snprintf(name, sizeof(name), "%s_vec_load",
- istr(type_ident(type_elem(tree_type(decl)))));
+ istr(type_ident(type_elem(type))));
range_t r = type_dim(slice_type, 0);
+
LLVMValueRef left_off =
cgen_expr(r.kind == RANGE_TO ? r.left : r.right, ctx);
LLVMValueRef right_off =
@@ -684,9 +684,8 @@ static LLVMValueRef cgen_array_signal_ref(tree_t decl, type_t slice_type,
LLVMValueRef left_abs = cgen_array_off(left_off, NULL, type, ctx, 0);
LLVMValueRef right_abs = cgen_array_off(right_off, NULL, type, ctx, 0);
- LLVMValueRef s_signal = tree_attr_ptr(decl, sig_struct_i);
LLVMValueRef indexes[] = { llvm_int32(0), llvm_int32(0) };
- LLVMValueRef p_signal = LLVMBuildGEP(builder, s_signal,
+ LLVMValueRef p_signal = LLVMBuildGEP(builder, signal,
indexes, ARRAY_LEN(indexes), "");
LLVMValueRef p_tmp = LLVMBuildGEP(builder, tmp,
indexes, ARRAY_LEN(indexes), "");
@@ -698,6 +697,12 @@ static LLVMValueRef cgen_array_signal_ref(tree_t decl, type_t slice_type,
return tmp;
}
+static LLVMValueRef cgen_sig_struct(tree_t decl)
+{
+ // Return the signal structure for a signal declaration
+ return tree_attr_ptr(decl, sig_struct_i);
+}
+
static LLVMValueRef cgen_scalar_signal_flag(tree_t signal, int flag)
{
LLVMValueRef signal_struct = tree_attr_ptr(signal, sig_struct_i);
@@ -747,7 +752,7 @@ static LLVMValueRef cgen_last_value(tree_t signal, cgen_ctx_t *ctx)
if (type_kind(tree_type(sig_decl)) == T_CARRAY) {
type_t type = tree_type(sig_decl);
- return cgen_array_signal_ref(sig_decl, type, ctx, true);
+ return cgen_vec_load(cgen_sig_struct(sig_decl), type, type, true, ctx);
}
else {
LLVMValueRef signal = tree_attr_ptr(sig_decl, sig_struct_i);
@@ -1203,10 +1208,9 @@ static LLVMValueRef cgen_ref(tree_t t, cgen_ctx_t *ctx)
case T_PORT_DECL:
case T_SIGNAL_DECL:
if (cgen_get_class(decl) == C_SIGNAL) {
- if (type_kind(tree_type(decl)) == T_CARRAY) {
- type_t type = tree_type(decl);
- return cgen_array_signal_ref(decl, type, ctx, false);
- }
+ type_t type = tree_type(decl);
+ if (type_is_array(type))
+ return cgen_vec_load(cgen_sig_struct(decl), type, type, false, ctx);
else
return cgen_scalar_signal_ref(decl, ctx);
}
@@ -1283,11 +1287,18 @@ static LLVMValueRef cgen_array_ref(tree_t t, cgen_ctx_t *ctx)
LLVMValueRef indexes[] = { llvm_int32(0), idx };
LLVMValueRef signal = LLVMBuildGEP(builder, signal_array,
indexes, ARRAY_LEN(indexes), "");
- LLVMValueRef ptr =
- LLVMBuildStructGEP(builder, signal, SIGNAL_RESOLVED, "");
- LLVMValueRef deref = LLVMBuildLoad(builder, ptr, "");
- return LLVMBuildIntCast(builder, deref,
- llvm_type(tree_type(t)), "");
+ type_t elem_type = type_elem(type);
+ if (type_is_array(elem_type)) {
+ // Load this sub-array into a temporary variable
+ return cgen_vec_load(signal, elem_type, elem_type, false, ctx);
+ }
+ else {
+ LLVMValueRef ptr =
+ LLVMBuildStructGEP(builder, signal, SIGNAL_RESOLVED, "");
+ LLVMValueRef deref = LLVMBuildLoad(builder, ptr, "");
+ return LLVMBuildIntCast(builder, deref,
+ llvm_type(tree_type(t)), "");
+ }
}
default:
@@ -1300,18 +1311,19 @@ static LLVMValueRef cgen_array_slice(tree_t t, cgen_ctx_t *ctx)
assert(tree_kind(tree_value(t)) == T_REF);
tree_t decl = tree_ref(tree_value(t));
+ type_t type = tree_type(decl);
switch (cgen_get_class(decl)) {
case C_VARIABLE:
case C_DEFAULT:
{
- type_t type = tree_type(decl);
LLVMValueRef array = cgen_get_var(decl, ctx);
return cgen_get_slice(array, type, tree_range(t), ctx);
}
case C_SIGNAL:
- return cgen_array_signal_ref(decl, tree_type(t), ctx, false);
+ return cgen_vec_load(cgen_sig_struct(decl), type, tree_type(t),
+ false, ctx);
default:
assert(false);
@@ -1793,20 +1805,23 @@ static LLVMValueRef cgen_signal_lvalue(tree_t t, cgen_ctx_t *ctx)
param_t p = tree_param(t, 0);
assert(p.kind == P_POS);
- LLVMValueRef elem = cgen_expr(p.value, ctx);
+ type_t type = tree_type(tree_value(t));
+
+ LLVMValueRef idx =
+ cgen_array_off(cgen_expr(p.value, ctx), NULL, type, ctx, 0);
if (tree_kind(tree_value(t)) == T_REF) {
tree_t decl = tree_ref(tree_value(t));
assert(type_is_array(tree_type(decl)));
- return cgen_array_signal_ptr(decl, elem);
+ return cgen_array_signal_ptr(decl, idx);
}
else {
LLVMValueRef p_base = cgen_signal_lvalue(tree_value(t), ctx);
- LLVMValueRef indexes[] = { llvm_int32(0), elem };
+ LLVMValueRef indexes[] = { llvm_int32(0), idx };
return LLVMBuildGEP(builder, p_base,
- indexes, ARRAY_LEN(indexes), "foo");
+ indexes, ARRAY_LEN(indexes), "");
}
}
break;
View
18 test/regress/signal8.vhd
@@ -5,14 +5,24 @@ architecture test of signal8 is
type int_array is array (integer range <>) of integer;
type int_array_Nx4 is array (integer range <>) of int_array(1 to 4);
- signal a : int_array_Nx4(1 to 4);
- signal b : int_array(1 to 4);
+ signal a : int_array_Nx4(1 to 4) := (
+ 1 => ( 1, 2, 3, 4 ),
+ 2 => ( 5, 6, 7, 8 ),
+ 3 => ( 9, 10, 11, 12 ),
+ 4 => ( 13, 14, 15, 16 ) );
begin
process is
+ variable b : int_array(1 to 4);
begin
- a(1)(2) <= 2;
- --assert a(1)(2) = 2;
+ a(1)(2) <= 99;
+ wait for 1 ns;
+ b := a(1);
+ --for i in b'range loop
+ -- report "b(" & integer'image(i) & ") = " & integer'image(b(i));
+ --end loop;
+ assert b = ( 1, 99, 3, 4 );
+-- assert a(1)(2) = 2;
-- a := ( others => ( 1, 2, 3, 4 ) );
-- b := a(1);
-- assert b = ( 1, 2, 3, 4);

No commit comments for this range

Something went wrong with that request. Please try again.