Pad type-punned user functions properly

When user defined function calls are withing a $signed, the result
needs to be properly padded. To make this work, handle padding of
a function result exactly type the padding of a signal vector. this
is natural in that the function return value *is* in a signal vector.

This fixes pr1841300.
This commit is contained in:
Stephen Williams 2007-12-15 22:05:56 -08:00
parent fa2712a3ee
commit 1506a0bf8c
3 changed files with 18 additions and 24 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005 Stephen Williams (steve@icarus.com)
* Copyright (c) 2005-2007 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -16,9 +16,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CVS_IDENT
#ident "$Id: draw_ufunc.c,v 1.2 2007/01/16 05:44:16 steve Exp $"
#endif
# include "vvp_priv.h"
# include <string.h>
@ -114,23 +111,17 @@ struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
res.base = allocate_vector(wid);
res.wid = wid;
{ unsigned load_wid = swid;
if (load_wid > ivl_signal_width(retval))
load_wid = ivl_signal_width(retval);
unsigned load_wid = swid;
if (load_wid > ivl_signal_width(retval))
load_wid = ivl_signal_width(retval);
assert(ivl_signal_array_count(retval) == 1);
fprintf(vvp_out, " %%load/v %u, v%p_0, %u;\n",
res.base, retval, load_wid);
if (load_wid < swid)
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
res.base+load_wid, swid-load_wid);
}
assert(ivl_signal_array_count(retval) == 1);
fprintf(vvp_out, " %%load/v %u, v%p_0, %u;\n",
res.base, retval, load_wid);
/* Pad the signal value with zeros. */
if (swid < wid)
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
res.base+swid, wid-swid);
if (load_wid < wid)
pad_expr_in_place(exp, res, swid);
return res;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2002 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2007 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -1697,7 +1697,7 @@ static struct vector_info draw_string_expr(ivl_expr_t exp, unsigned wid)
* the res vector. This function just calculates the pad to fill out
* the res area.
*/
static void pad_expr_in_place(ivl_expr_t exp, struct vector_info res, unsigned swid)
void pad_expr_in_place(ivl_expr_t exp, struct vector_info res, unsigned swid)
{
if (res.wid <= swid)
return;

View File

@ -29,6 +29,11 @@
*/
extern FILE* vvp_out;
struct vector_info {
unsigned base;
unsigned wid;
};
/*
* Mangle all non-symbol characters in an identifier, quotes in names
*/
@ -66,6 +71,8 @@ extern void draw_lpm_mux(ivl_lpm_t net);
extern struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid);
extern int draw_ufunc_real(ivl_expr_t exp);
extern void pad_expr_in_place(ivl_expr_t exp, struct vector_info res, unsigned swid);
/*
* modpath.c symbols.
*
@ -141,10 +148,6 @@ extern const char*draw_input_from_net(ivl_nexus_t nex);
* if the expression might be found in the lookaside table, and
* therefore might be multiply allocated if allowed.
*/
struct vector_info {
unsigned base;
unsigned wid;
};
extern struct vector_info draw_eval_expr(ivl_expr_t exp, int stuff_ok_flag);
extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w,