[Libre-soc-bugs] [Bug 665] very basic nmigen-to-c compiler needed
bugzilla-daemon at libre-soc.org
bugzilla-daemon at libre-soc.org
Tue Aug 31 21:48:22 BST 2021
https://bugs.libre-soc.org/show_bug.cgi?id=665
--- Comment #7 from Jacob Lifshay <programmerjake at gmail.com> ---
(In reply to Luke Kenneth Casson Leighton from comment #5)
> (In reply to Jacob Lifshay from comment #4)
>
> > I'd expect that it'll work better for the C to be completely
> > de-generic-ified, and not use a mountain of undecipherable macros to make
> > everything work, being able to read the generated code would be nice :)
>
> signals unfortunately are not limited in length in any way, shape or form.
> there is no such concept in c as a basic integer type capable of adding
> 4,096 bits.
>
> consequently, macros (or macros hiding functions) are unavoidable.
there's an easy solution: use arrays when signals are more than 64-bits:
typedef uint32_t signal_word_t;
typedef uint64_t signal_dword_t;
#define SIGNAL_WORD_BITS 32
#define SIGNAL_ARRAY_SIZE(bits) \
(((size_t)(bits) + (SIGNAL_WORD_BITS - 1)) / SIGNAL_WORD_BITS)
static inline size_t saturating_sub(size_t a, size_t b)
{
return a >= b ? a - b : 0;
}
static inline void add_signal(
signal_word_t *restrict out,
const signal_word_t *in0,
const signal_word_t *in1,
size_t bits)
{
size_t i;
signal_dword_t carry = 0;
for(i = 0; bits > 0; i++)
{
signal_dword_t sum = (signal_dword_t)in0[i];
sum += (signal_dword_t)in1[i] + carry;
carry = sum >> SIGNAL_WORD_BITS;
if(bits < SIGNAL_WORD_BITS)
sum &= (1ULL << bits) - 1;
out[i] = (signal_word_t)sum;
bits = saturating_sub(bits, SIGNAL_WORD_BITS);
}
}
void cast_unsigned_signal(
signal_word_t *restrict out,
size_t out_bits,
const signal_word_t *in,
size_t in_bits)
{
size_t i;
for(i = 0; out_bits > 0; i++)
{
signal_word_t v = in_bits > 0 ? in[i] : 0;
// assumption: `in` is already padded with zero bits
// to fill out the last word
if(out_bits < SIGNAL_WORD_BITS)
v &= (1ULL << out_bits) - 1;
out[i] = v;
out_bits = saturating_sub(out_bits, SIGNAL_WORD_BITS);
in_bits = saturating_sub(in_bits, SIGNAL_WORD_BITS);
}
}
void openpower_add(openpower_regs *regs) {
// replace with actual code:
signal_word_t ra[SIGNAL_ARRAY_SIZE(64)];
signal_word_t rb[SIGNAL_ARRAY_SIZE(64)];
signal_word_t rt[SIGNAL_ARRAY_SIZE(64)];
signal_word_t lhs[SIGNAL_ARRAY_SIZE(256)];
signal_word_t rhs[SIGNAL_ARRAY_SIZE(256)];
signal_word_t sum[SIGNAL_ARRAY_SIZE(256)];
ra[0] = (signal_word_t)regs.ra;
ra[1] = regs.ra >> SIGNAL_WORD_BITS;
rb[0] = (signal_word_t)regs.rb;
rb[1] = regs.rb >> SIGNAL_WORD_BITS;
cast_unsigned_signal(lhs, 256, ra, 64);
cast_unsigned_signal(rhs, 256, rb, 64);
add_signal(sum, lhs, rhs, 256);
cast_unsigned_signal(rt, 64, sum, 256);
regs.rt = ((signal_dword_t)rt[1] << SIGNAL_WORD_BITS) | rt[0];
}
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-soc-bugs
mailing list