reg_t sv_proc_t::FN(processor_t* p, insn_t s_insn, reg_t pc)
{
int xlen = ISASZ;
- reg_t npc = sext_xlen(pc + insn_length(INSNCODE));
+ reg_t npc = _sext_xlen(pc + insn_length(INSNCODE));
// messy way to do it: insn_t is used elsewhere in a union,
// so cannot create virtual functions.
// a workaround is to grab the bits from the insn_t
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs + RS2; }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return lhs + rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs + RS2; })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs) { return lhs + rhs; })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs & RS2; }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return lhs & rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs & RS2; })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs) { return lhs & rhs; })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](int64_t lhs) { return std::max(lhs, int64_t(RS2)); }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](int64_t lhs, uint64_t rhs) { return std::max(lhs, int64_t(rhs)); }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](int32_t lhs) { return std::max(lhs, int32_t(RS2)); })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](int32_t lhs, int32_t rhs) { return std::max(lhs, int32_t(rhs)); })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return std::max(lhs, RS2); }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return (lhs > rhs) ? lhs : rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return std::max(lhs, uint32_t(RS2)); })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs)
+ { return std::max(lhs, uint32_t(rhs)); })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](int64_t lhs) { return std::min(lhs, int64_t(RS2)); }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](int64_t lhs, uint64_t rhs)
+ { return std::min(lhs, int64_t(rhs)); }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](int32_t lhs) { return std::min(lhs, int32_t(RS2)); })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](int32_t lhs, int32_t rhs)
+ { return std::min(lhs, int32_t(rhs)); })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return std::min(lhs, RS2); }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return (lhs < rhs) ? lhs : rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return std::min(lhs, uint32_t(RS2)); })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs)
+ { return std::min(lhs, uint32_t(rhs)); })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs | RS2; }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return lhs | rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs | RS2; })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs) { return lhs | rhs; })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return RS2; }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return RS2; })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs) { return rhs; })));
require_extension('A');
require_rv64;
-WRITE_RD(MMU.amo_uint64(RS1, [&](uint64_t lhs) { return lhs ^ RS2; }));
+WRITE_RD(MMU.amo_uint64(RS1, RS2,
+ [&](uint64_t lhs, uint64_t rhs) { return lhs ^ rhs; }));
require_extension('A');
-WRITE_RD(sext32(MMU.amo_uint32(RS1, [&](uint32_t lhs) { return lhs ^ RS2; })));
+WRITE_RD(sext32(MMU.amo_uint32(RS1, RS2,
+ [&](uint32_t lhs, uint32_t rhs) { return lhs ^ rhs; })));
// template for functions that perform an atomic memory operation
#define amo_func(type) \
template<typename op> \
- type##_t amo_##type(reg_t addr, op f) { \
+ type##_t amo_##type(reg_t addr, reg_t rhs, op f) { \
if (addr & (sizeof(type##_t)-1)) \
throw trap_store_address_misaligned(addr); \
try { \
auto lhs = load_##type(addr); \
- store_##type(addr, f(lhs)); \
+ store_##type(addr, f(lhs, rhs)); \
return lhs; \
} catch (trap_load_page_fault& t) { \
/* AMO faults should be reported as store faults */ \
#include <map>
#include "debug_rom_defines.h"
#ifdef SPIKE_SIMPLEV
-#include "sv_decode.h"
#include "sv_insn_redirect.h"
+#include "sv_decode.h"
#endif
class processor_t;
#include "sv.h"
#include "decode.h"
+//#include "sv_reg.h"
//#include "processor.h"
#define REG_RD 0x1
prd(p_rd), prs1(p_rs1), prs2(p_rs2), prs3(p_rs3),
save_branch_addr(0) {}
+ uint64_t rvc_imm() { return (insn_t::rvc_imm()); }
+ uint64_t u_imm() { return (insn_t::u_imm()); }
+ uint64_t i_imm() { return (insn_t::i_imm()); }
+ uint64_t s_imm() { return (insn_t::s_imm()); }
uint64_t _rvc_spoffs_imm(uint64_t elwidth, uint64_t baseoffs);
uint64_t rvc_lwsp_imm() { return _rvc_spoffs_imm(4, insn_t::rvc_lwsp_imm()); }
uint64_t rvc_ldsp_imm() { return _rvc_spoffs_imm(8, insn_t::rvc_ldsp_imm()); }
DO_WRITE_FREG( _insn->rd(), freg(value) );
}
+/*
void (sv_proc_t::WRITE_RD)(bool value)
{
WRITE_REG( _insn->rd(), value ? 1 : 0);
}
-
void (sv_proc_t::WRITE_RD)(sv_reg_t value)
{
WRITE_REG( _insn->rd(), value.get_data() );
}
+*/
+
+void (sv_proc_t::WRITE_RD)(uint64_t value)
+{
+ WRITE_REG( _insn->rd(), value ); // XXX TODO: replace properly
+}
+/*
void (sv_proc_t::WRITE_RD)(int_fast64_t value)
{
WRITE_REG( _insn->rd(), value ); // XXX TODO: replace properly
{
WRITE_REG( _insn->rd(), value ); // XXX TODO: replace properly
}
+*/
/*
reg_t (sv_proc_t::READ_REG)(uint64_t i)
}
*/
-sv_reg_t sv_proc_t::get_rs1()
+reg_t sv_proc_t::get_rs1()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rs1()]);
+ return (_insn->p->get_state()->XPR[_insn->rs1()]);
}
-sv_reg_t sv_proc_t::get_rs2()
+reg_t sv_proc_t::get_rs2()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rs2()]);
+ return (_insn->p->get_state()->XPR[_insn->rs2()]);
}
-sv_reg_t sv_proc_t::get_rvc_rs1s()
+reg_t sv_proc_t::get_rvc_rs1s()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rvc_rs1s()]);
+ return (_insn->p->get_state()->XPR[_insn->rvc_rs1s()]);
}
-sv_reg_t sv_proc_t::get_rvc_rs2s()
+reg_t sv_proc_t::get_rvc_rs2s()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rvc_rs2s()]);
+ return (_insn->p->get_state()->XPR[_insn->rvc_rs2s()]);
}
-sv_reg_t sv_proc_t::get_rvc_rs1()
+reg_t sv_proc_t::get_rvc_rs1()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rvc_rs1()]);
+ return (_insn->p->get_state()->XPR[_insn->rvc_rs1()]);
}
-sv_reg_t sv_proc_t::get_rvc_rs2()
+reg_t sv_proc_t::get_rvc_rs2()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rvc_rs2()]);
+ return (_insn->p->get_state()->XPR[_insn->rvc_rs2()]);
}
-sv_reg_t sv_proc_t::get_rs3()
+reg_t sv_proc_t::get_rs3()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[_insn->rs3()]);
+ return (_insn->p->get_state()->XPR[_insn->rs3()]);
}
-sv_reg_t sv_proc_t::get_rvc_sp()
+reg_t sv_proc_t::get_rvc_sp()
{
- return sv_uint64_t(_insn->p->get_state()->XPR[X_SP]);
+ return (_insn->p->get_state()->XPR[X_SP]);
}
-sv_reg_t sv_proc_t::uint64_max()
+reg_t sv_proc_t::uint64_max()
{
- return sv_uint64_t((UINT64_C(18446744073709551615)));
+ return ((UINT64_C(18446744073709551615)));
}
-sv_reg_t (sv_proc_t::sext_xlen)(sv_reg_t v)
+/*
+reg_t (sv_proc_t::sext_xlen)(uint64_t x)
{
- uint64_t x = v.as_uint64();
x = (((sreg_t)(x) << (64-xlen)) >> (64-xlen));
return sv_uint64_t(x);
}
+*/
+reg_t (sv_proc_t::sext_xlen)(reg_t x)
+{
+ //uint64_t x = v.as_uint64();
+ x = (((sreg_t)(x) << (64-xlen)) >> (64-xlen));
+ return x;
+ //return sv_uint64_t(x);
+}
-sv_reg_t (sv_proc_t::zext_xlen)(sv_reg_t v)
+reg_t (sv_proc_t::zext_xlen)(reg_t x)
{
- uint64_t x = v.as_uint64();
+ //uint64_t x = v.as_uint64();
x = (((reg_t)(x) << (64-xlen)) >> (64-xlen));
- return sv_uint64_t(x);
+ return x;
+ //return sv_uint64_t(x);
}
-sv_reg_t (sv_proc_t::sext32)(uint_fast32_t v)
+/*
+reg_t (sv_proc_t::sext32)(uint_fast32_t v)
{
return sext32((uint64_t)v); // XXX TODO do properly
}
-
-sv_reg_t (sv_proc_t::sext32)(sv_reg_t v)
+*/
+reg_t (sv_proc_t::sext32)(reg_t x)
{
- uint64_t x = v.as_uint64();
+ //uint64_t x = v.as_uint64();
x = ((sreg_t)(int32_t)(x));
- return sv_uint64_t(x);
+ return x;
+ //return sv_uint64_t(x);
}
-sv_reg_t (sv_proc_t::zext32)(sv_reg_t v)
+reg_t (sv_proc_t::zext32)(reg_t x)
{
- uint64_t x = v.as_uint64();
+ //uint64_t x = v.as_uint64();
x = ((reg_t)(uint32_t)(x));
- return sv_uint64_t(x);
+ return x;
+ //return sv_uint64_t(x);
}
freg_t sv_proc_t::get_frs1()
return READ_FREG(_insn->rs2());
}
+/*
sv_reg_t sv_reg_t::make_sv_int64_t (int64_t v) const
{
return sv_sreg_t(v);
}
-sv_reg_t::operator sv_sreg_t () const
+sv_reg_t::operator sv_sreg_t ()
{
return sv_sreg_t ( as_uint64() );
}
+sv_reg_t::operator int32_t ()
+{
+ uint64_t x = get_data();
+ sreg_t _x = (sreg_t) x;
+ sv_sreg_t y = sv_sreg_t ( _x );
+ return y;
+}
+
+
+sv_reg_t::operator uint16_t ()
+{
+ uint64_t x = get_data();
+ uint16_t _x = (uint16_t) x;
+ sv_uint16_t y = sv_uint16_t ( _x );
+ return y;
+}
+
+
+sv_reg_t::operator uint8_t () // XXX TODO, make_sv_char_t
+{
+ uint64_t x = get_data();
+ uint8_t _x = (uint8_t) x;
+ sv_uint64_t y = sv_uint64_t ( _x );
+ return y;
+}
+
+sv_reg_t::operator char () // XXX TODO, make_sv_char_t
+{
+ uint64_t x = get_data();
+ char _x = (char) x;
+ sv_sreg_t y = sv_sreg_t ( _x );
+ return y;
+}
+
+sv_reg_t::operator uint32_t () // TODO, make_sv_uint32_t
+ { return make_sv_uint64_t( (sreg_t) (as_uint64()) ); }
+sv_reg_t::operator sreg_t ()
+ { return make_sv_int64_t( (sreg_t) (as_uint64()) ); }
+
+sv_reg_t::operator reg_t ()
+{
+ uint64_t x = get_data();
+ sv_uint64_t y = sv_uint64_t ( x );
+ return y;
+}
+*/
#include <stdio.h>
#include "decode.h"
#include "sv_decode.h"
-#include "sv_reg.h"
+//#include "sv_reg.h"
#undef RS1
#undef RS2
{
public:
sv_proc_t(processor_t *_p) : p(_p), _insn(NULL), xlen(0) {}
- void (WRITE_RD)(bool value); // f32_eq calls this: XXX TODO investigate
- void (WRITE_RD)(sv_reg_t value);
- void (WRITE_RD)(int_fast64_t value); // XXX TODO investigate
- void (WRITE_RD)(uint_fast64_t value); // XXX TODO investigate
+ //void (WRITE_RD)(bool value); // f32_eq calls this: XXX TODO investigate
+ //void (WRITE_RD)(sv_reg_t &value);
+ //void (WRITE_RD)(int_fast64_t value); // XXX TODO investigate
+ //void (WRITE_RD)(uint_fast64_t value); // XXX TODO investigate
+ void (WRITE_RD)(uint64_t value); // XXX TODO investigate
void (WRITE_FRD)(freg_t value);
void (WRITE_FRD)(float64_t value);
void (WRITE_FRD)(float32_t value);
this->insn._insn = i;
}
- sv_reg_t get_rs1();
- sv_reg_t get_rs2();
- sv_reg_t get_rs3();
+ reg_t get_rs1();
+ reg_t get_rs2();
+ reg_t get_rs3();
- sv_reg_t get_rvc_sp();
- sv_reg_t get_rvc_rs1();
- sv_reg_t get_rvc_rs2();
- sv_reg_t get_rvc_rs1s();
- sv_reg_t get_rvc_rs2s();
+ reg_t get_rvc_sp();
+ reg_t get_rvc_rs1();
+ reg_t get_rvc_rs2();
+ reg_t get_rvc_rs1s();
+ reg_t get_rvc_rs2s();
- sv_reg_t uint64_max();
+ reg_t uint64_max();
freg_t get_frs1();
freg_t get_frs2();
- //sv_reg_t (sext_xlen)(reg_t &v); // WARNING...
- sv_reg_t (zext_xlen)(sv_reg_t v);
- sv_reg_t (sext_xlen)(sv_reg_t v);
- sv_reg_t (sext32)(uint_fast32_t v); // XXX TODO
- sv_reg_t (sext32)(sv_reg_t v);
- sv_reg_t (zext32)(sv_reg_t v);
+ reg_t (sext_xlen)(reg_t v); // WARNING...
+ reg_t (zext_xlen)(reg_t v);
+ //reg_t (sext_xlen)(sv_reg_t &v);
+ //reg_t (sext32)(uint_fast32_t v); // XXX TODO
+ reg_t (sext32)(reg_t v);
+ //reg_t (sext32)(sv_reg_t &v);
+ reg_t (zext32)(reg_t v);
#include "sv_insn_decl.h"
};
#define DECL_1OP( op ) \
bool operator op () const { \
- return op (this->as_uint64()); }
+ return op (this->as_uint64()); }
#define DECL_BOP( op ) \
bool operator op (const sv_reg_t& rhs) const { \
- return this->as_uint64() op rhs.as_uint64(); }
+ return this->as_uint64() op rhs.as_uint64(); } \
+ bool operator op (reg_t rhs) const { \
+ return this->as_uint64() op rhs; }
#define DECL_BOPE( op ) \
bool operator op (int rhs) const { \
sv_reg_t operator op (const sreg_t& rhs) const { \
return make_##type( (this->as_uint64() op rhs) ); } \
sv_reg_t operator op (int rhs) const { \
- return make_##type( (this->as_uint64() op rhs) ); }
+ return make_##type( (this->as_uint64() op rhs) ); } \
+ sv_reg_t operator op (uint32_t rhs) const { \
+ return make_##type( (this->as_uint64() op rhs) ); }
#define op_bneg ~
#define op_xor ^
public:
virtual ~sv_reg_t() {}
// using a type which accommodates all values
- virtual uint64_t as_uint64() const { return 0; };
+ virtual uint64_t as_uint64() const = 0;
public:
DECL_BOP( op_ge )
DECL_OP( sv_uint64_t, op_sl )
DECL_OP( sv_uint64_t, op_sr )
- operator char () const // XXX TODO, make_sv_char_t
- { return make_sv_int64_t( (sreg_t) (as_uint64()) ); }
- operator int32_t () // XXX TODO, make_sv_char_t
- { return make_sv_int64_t( (sreg_t) (as_uint64()) ); }
- operator uint32_t () const // TODO, make_sv_uint32_t
- { return make_sv_uint64_t( (sreg_t) (as_uint64()) ); }
- operator sv_sreg_t () const;
- operator sreg_t () const
- { return make_sv_int64_t( (sreg_t) (as_uint64()) ); }
- operator reg_t () const
- { return make_sv_uint64_t( (reg_t) (as_uint64()) ); }
- //operator uint_fast64_t () const
+ operator uint8_t ();
+ operator char ();
+ operator uint32_t ();
+ operator int32_t ();
+ operator uint16_t ();
+ operator sv_sreg_t () ;
+ operator sreg_t () ;
+ operator reg_t () ;
+ //operator uint_fast64_t () const
// { return make_sv_uint64_t( (reg_t) (as_uint64()) ); }
- //operator int_fast64_t () const
+ //operator int_fast64_t () const
//{ return make_sv_int64_t( (sreg_t) (as_uint64()) ); }
// ...
public:
class sv_uint16_t : public sv_reg_t {
// ...
+public:
+ sv_uint16_t(uint16_t v) : data(v) {}
private:
virtual uint64_t as_uint64() const { return this->data; }
private: