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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * 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 "vvp_priv.h"
# include <string.h> # include <string.h>
@ -114,7 +111,7 @@ struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
res.base = allocate_vector(wid); res.base = allocate_vector(wid);
res.wid = wid; res.wid = wid;
{ unsigned load_wid = swid; unsigned load_wid = swid;
if (load_wid > ivl_signal_width(retval)) if (load_wid > ivl_signal_width(retval))
load_wid = ivl_signal_width(retval); load_wid = ivl_signal_width(retval);
@ -122,15 +119,9 @@ struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid)
fprintf(vvp_out, " %%load/v %u, v%p_0, %u;\n", fprintf(vvp_out, " %%load/v %u, v%p_0, %u;\n",
res.base, retval, load_wid); res.base, retval, load_wid);
if (load_wid < swid)
fprintf(vvp_out, " %%mov %u, 0, %u;\n",
res.base+load_wid, swid-load_wid);
}
/* Pad the signal value with zeros. */ /* Pad the signal value with zeros. */
if (swid < wid) if (load_wid < wid)
fprintf(vvp_out, " %%mov %u, 0, %u;\n", pad_expr_in_place(exp, res, swid);
res.base+swid, wid-swid);
return res; 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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 vector. This function just calculates the pad to fill out
* the res area. * 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) if (res.wid <= swid)
return; return;

View File

@ -29,6 +29,11 @@
*/ */
extern FILE* vvp_out; extern FILE* vvp_out;
struct vector_info {
unsigned base;
unsigned wid;
};
/* /*
* Mangle all non-symbol characters in an identifier, quotes in names * 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 struct vector_info draw_ufunc_expr(ivl_expr_t exp, unsigned wid);
extern int draw_ufunc_real(ivl_expr_t exp); 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. * 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 * if the expression might be found in the lookaside table, and
* therefore might be multiply allocated if allowed. * 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(ivl_expr_t exp, int stuff_ok_flag);
extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w, extern struct vector_info draw_eval_expr_wid(ivl_expr_t exp, unsigned w,