remembered that the use of sv registers have to be loop-incremented separately
[riscv-isa-sim.git] / riscv / sv.cc
1 #include "sv.h"
2 #include "sv_decode.h"
3
4 sv_reg_csr_entry sv_csrs[SV_CSR_SZ];
5 sv_reg_entry sv_int_tb[NXPR];
6 sv_reg_entry sv_fp_tb[NFPR];
7 sv_pred_csr_entry sv_pred_csrs[SV_CSR_SZ];
8 sv_pred_entry sv_pred_tb[NXPR];
9
10 bool sv_check_reg(bool intreg, uint64_t reg)
11 {
12 sv_reg_entry *r;
13 if (intreg)
14 {
15 r = &sv_int_tb[reg];
16 }
17 else
18 {
19 r = &sv_fp_tb[reg];
20 }
21 if (r->elwidth != 0)
22 {
23 // XXX raise exception
24 }
25 if (r->active && r->isvec)
26 {
27 return true;
28 }
29 return false;
30 }
31
32 /* this is the "remap" function. note that registers can STILL BE REDIRECTED
33 * yet NOT BE MARKED AS A VECTOR.
34 *
35 * reg 5 -> active=false, regidx=XX, isvec=XX -> returns 5
36 * reg 5 -> active=true , regidx=35, isvec=false -> returns 35
37 * reg 5 -> active=true , regidx=35, isvec=true -> returns 35 *PLUS LOOP*
38 *
39 * so it is possible for example to use the remap system for C instructions
40 * to get access to the *full* range of registers x0..x63 (yes 63 because
41 * SV doubles both the int and fp regfile sizes), by setting
42 * "active=true, isvec=false" for any of x8..x15
43 *
44 * where "active=true, isvec=true" this is the "expected" behaviour
45 * of SV. it's "supposed" to "just" be a vectorisation API. it isn't:
46 * it's quite a bit more.
47 */
48 uint64_t sv_insn_t::remap(uint64_t reg, bool intreg, int &voffs)
49 {
50 // okaay so first determine which map to use. intreg is passed
51 // in (ultimately) from id_regs.py's examination of the use of
52 // FRS1/RS1, WRITE_FRD/WRITE_RD, which in turn gets passed
53 // in from sv_insn_t::fimap...
54 sv_reg_entry *r;
55 if (intreg)
56 {
57 r = &sv_int_tb[reg];
58 }
59 else
60 {
61 r = &sv_fp_tb[reg];
62 }
63 // next we check if this entry is active. if not, the register
64 // is not being "redirected", so just return the actual reg.
65 if (!r->active)
66 {
67 return reg; // not active: return as-is
68 }
69
70 // next we go through the lookup table. *THIS* is why the
71 // sv_reg_entry table is 32 entries (5-bit) *NOT* 6 bits
72 // the *KEY* (reg) is 5-bit, the *VALUE* (actual target reg) is 6-bit
73 // XXX TODO: must actually double NXPR and NXFR in processor.h to cope!!
74 reg = r->regidx;
75
76 // now we determine if this is a scalar/vector: if it's scalar
77 // we return the re-mapped register...
78 if (!r->isvec) // scalar
79 {
80 return reg; // ... remapped at this point...
81 }
82
83 // aaand now, as it's a "vector", FINALLY we can add on the loop-offset
84 // which was passed in to the sv_insn_t constructor (by reference)
85 // and, at last, we have "parallelism" a la contiguous registers.
86 reg += voffs; // wheww :)
87
88 // however... before returning, we increment the loop-offset for
89 // this particular register, so that on the next loop the next
90 // contiguous register will be used.
91 voffs += 1;
92 return reg;
93 }
94