Permalink
Browse files

Fix code generation for constrained array parameters

  • Loading branch information...
1 parent 65993e9 commit 8a3c76b58613443e3fe62b337fb0777a1175ef46 @nickg committed Apr 8, 2012
Showing with 40 additions and 4 deletions.
  1. +12 −4 src/cgen.c
  2. +27 −0 test/regress/func6.vhd
  3. +1 −0 test/regress/testlist.txt
View
@@ -547,10 +547,13 @@ static void cgen_prototype(tree_t t, LLVMTypeRef *args, bool procedure)
{
type_t type = tree_type(p);
port_mode_t mode = tree_port_mode(p);
+ bool array = type_is_array(type);
bool need_ptr = ((mode == PORT_OUT || mode == PORT_INOUT)
- && !type_is_array(type));
+ && !array);
if (need_ptr)
args[i] = LLVMPointerType(llvm_type(type), 0);
+ else if (array && (type_kind(type) != T_UARRAY))
+ args[i] = LLVMPointerType(llvm_type(type), 0);
else
args[i] = llvm_type(type);
}
@@ -738,17 +741,22 @@ static void cgen_call_args(tree_t t, LLVMValueRef *args, struct cgen_ctx *ctx)
else {
args[i] = NULL;
- type_t type = tree_type(p.value);
+ type_t type = tree_type(p.value), formal_type;
// If this is a scalar out or inout parameter then we need
// to pass a pointer rather than the value
if (builtin == NULL) {
- port_mode_t mode = tree_port_mode(tree_port(decl, i));
+ tree_t port = tree_port(decl, i);
+ port_mode_t mode = tree_port_mode(port);
bool need_ptr = ((mode == PORT_OUT || mode == PORT_INOUT)
&& !type_is_array(type));
if (need_ptr)
args[i] = cgen_get_var(tree_ref(p.value), ctx);
+
+ formal_type = tree_type(port);
}
+ else
+ formal_type = type;
if (args[i] == NULL)
args[i] = cgen_expr(p.value, ctx);
@@ -757,7 +765,7 @@ static void cgen_call_args(tree_t t, LLVMValueRef *args, struct cgen_ctx *ctx)
// a structure with its metadata. Note we don't need to do
// this for unconstrained arrays as they are already wrapped.
bool need_wrap =
- type_is_array(type)
+ (type_kind(formal_type) == T_UARRAY)
&& cgen_const_bounds(type)
&& (builtin == NULL);
View
@@ -0,0 +1,27 @@
+entity func6 is
+end entity;
+
+architecture test of func6 is
+
+ function flip(x : bit_vector(3 downto 0)) return bit_vector is
+ variable r : bit_vector(3 downto 0);
+ begin
+ r(0) := x(3);
+ r(1) := x(2);
+ r(2) := x(1);
+ r(3) := x(0);
+ return r;
+ end function;
+
+begin
+
+ process is
+ variable b : bit_vector(3 downto 0);
+ begin
+ assert flip("1010") = "0101";
+ b := "1100";
+ assert flip(b) = "0011";
+ wait;
+ end process;
+
+end architecture;
@@ -62,3 +62,4 @@ signal7 normal
synopsys1 normal
block1 normal
elab3 normal,gold
+func6 normal

0 comments on commit 8a3c76b

Please sign in to comment.