Cleanup of templates
This commit is contained in:
parent
dd7b0f380a
commit
a576fdf8e5
|
@ -1,8 +1,6 @@
|
||||||
InsructionSet RV32IBase {
|
InsructionSet RV32IBase {
|
||||||
constants {
|
constants {
|
||||||
XLEN,
|
XLEN,
|
||||||
PCLEN,
|
|
||||||
XLEN_BIT_MASK:=0x1f,
|
|
||||||
fence:=0,
|
fence:=0,
|
||||||
fencei:=1,
|
fencei:=1,
|
||||||
fencevmal:=2,
|
fencevmal:=2,
|
||||||
|
@ -16,7 +14,7 @@ InsructionSet RV32IBase {
|
||||||
registers {
|
registers {
|
||||||
[31:0] X[XLEN],
|
[31:0] X[XLEN],
|
||||||
PC[XLEN](is_pc),
|
PC[XLEN](is_pc),
|
||||||
alias ZERO[XLEN] is X[0]
|
alias ZERO[XLEN] is X[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
instructions {
|
instructions {
|
||||||
|
@ -197,7 +195,7 @@ InsructionSet RV32IBase {
|
||||||
SLL {
|
SLL {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b0110011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&XLEN_BIT_MASK);
|
if(rd != 0) X[rd] <= shll(X[rs1], X[rs2]&(XLEN-1));
|
||||||
}
|
}
|
||||||
SLT {
|
SLT {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0110011;
|
||||||
|
@ -217,12 +215,12 @@ InsructionSet RV32IBase {
|
||||||
SRL {
|
SRL {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&XLEN_BIT_MASK);
|
if(rd != 0) X[rd] <= shrl(X[rs1], X[rs2]&(XLEN-1));
|
||||||
}
|
}
|
||||||
SRA {
|
SRA {
|
||||||
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011;
|
encoding: b0100000 | rs2[4:0] | rs1[4:0] | b101 | rd[4:0] | b0110011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&XLEN_BIT_MASK);
|
if(rd != 0) X[rd] <= shra(X[rs1], X[rs2]&(XLEN-1));
|
||||||
}
|
}
|
||||||
OR {
|
OR {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011;
|
||||||
|
@ -279,8 +277,8 @@ InsructionSet RV32IBase {
|
||||||
val csr_val[XLEN] <= CSR[csr];
|
val csr_val[XLEN] <= CSR[csr];
|
||||||
CSR[csr] <= rs_val;
|
CSR[csr] <= rs_val;
|
||||||
// make sure Xrd is updated once CSR write succeeds
|
// make sure Xrd is updated once CSR write succeeds
|
||||||
X[rd] <= csr_val;
|
X[rd] <= csr_val;
|
||||||
} else {
|
} else {
|
||||||
CSR[csr] <= rs_val;
|
CSR[csr] <= rs_val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import "RV64IBase.core_desc"
|
||||||
import "RV64A.core_desc"
|
import "RV64A.core_desc"
|
||||||
|
|
||||||
Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC {
|
Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC {
|
||||||
template:"vm_riscv.in.cpp";
|
|
||||||
constants {
|
constants {
|
||||||
XLEN:=32;
|
XLEN:=32;
|
||||||
PCLEN:=32;
|
PCLEN:=32;
|
||||||
|
@ -36,7 +35,6 @@ Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC, RV32D, RV32
|
||||||
|
|
||||||
|
|
||||||
Core RV64IA provides RV64IBase, RV64A, RV32A {
|
Core RV64IA provides RV64IBase, RV64A, RV32A {
|
||||||
template:"vm_riscv.in.cpp";
|
|
||||||
constants {
|
constants {
|
||||||
XLEN:=64;
|
XLEN:=64;
|
||||||
PCLEN:=64;
|
PCLEN:=64;
|
||||||
|
|
|
@ -1,34 +1,35 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
/*******************************************************************************
|
||||||
// Copyright (C) 2017, MINRES Technologies GmbH
|
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
//
|
*
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
//
|
*
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
*******************************************************************************/
|
||||||
|
|
||||||
<%
|
<%
|
||||||
import com.minres.coredsl.coreDsl.Register
|
import com.minres.coredsl.coreDsl.Register
|
||||||
import com.minres.coredsl.coreDsl.RegisterFile
|
import com.minres.coredsl.coreDsl.RegisterFile
|
||||||
|
@ -39,18 +40,17 @@ def getTypeSize(size){
|
||||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||||
#define _${coreDef.name.toUpperCase()}_H_
|
#define _${coreDef.name.toUpperCase()}_H_
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
#include <iss/vm_if.h>
|
#include <iss/vm_if.h>
|
||||||
#include <iss/arch/traits.h>
|
|
||||||
#include <array>
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace arch {
|
namespace arch {
|
||||||
|
|
||||||
struct ${coreDef.name.toLowerCase()};
|
struct ${coreDef.name.toLowerCase()};
|
||||||
|
|
||||||
template<>
|
template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||||
struct traits<${coreDef.name.toLowerCase()}> {
|
|
||||||
|
|
||||||
constexpr static char const* const core_type = "${coreDef.name}";
|
constexpr static char const* const core_type = "${coreDef.name}";
|
||||||
|
|
||||||
|
@ -87,21 +87,21 @@ struct traits<${coreDef.name.toLowerCase()}> {
|
||||||
|
|
||||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||||
|
|
||||||
constexpr static unsigned reg_bit_width(unsigned r) {
|
static constexpr std::array<const uint32_t, ${regSizes.size}> ${coreDef.name}_reg_size{
|
||||||
constexpr std::array<const uint32_t, ${regSizes.size}> ${coreDef.name}_reg_size{{${regSizes.join(",")}}};
|
{${regSizes.join(",")}}};
|
||||||
return ${coreDef.name}_reg_size[r];
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr static unsigned reg_byte_offset(unsigned r) {
|
static constexpr unsigned reg_bit_width(unsigned r) { return ${coreDef.name}_reg_size[r]; }
|
||||||
constexpr std::array<const uint32_t, ${regOffsets.size}> ${coreDef.name}_reg_byte_offset{{${regOffsets.join(",")}}};
|
|
||||||
return ${coreDef.name}_reg_byte_offset[r];
|
static constexpr std::array<const uint32_t, ${regOffsets.size}> ${coreDef.name}_reg_byte_offset{
|
||||||
}
|
{${regOffsets.join(",")}}};
|
||||||
|
|
||||||
|
constexpr static unsigned reg_byte_offset(unsigned r) { return ${coreDef.name}_reg_byte_offset[r]; }
|
||||||
|
|
||||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||||
|
|
||||||
enum sreg_flag_e {FLAGS};
|
enum sreg_flag_e { FLAGS };
|
||||||
|
|
||||||
enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}};
|
enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
|
@ -126,12 +126,13 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
/// deprecated
|
/// deprecated
|
||||||
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||||
|
|
||||||
uint64_t get_icount() { return reg.icount;}
|
inline uint64_t get_icount() { return reg.icount; }
|
||||||
|
|
||||||
|
inline bool should_stop() { return interrupt_sim; }
|
||||||
|
|
||||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
if(addr.space != traits<${coreDef.name.toLowerCase()}>::MEM ||
|
if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
||||||
addr.type == iss::address_type::PHYSICAL ||
|
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
||||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){
|
|
||||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask);
|
return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask);
|
||||||
} else
|
} else
|
||||||
return virt2phys(addr);
|
return virt2phys(addr);
|
||||||
|
@ -141,8 +142,7 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
|
|
||||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||||
|
|
||||||
inline
|
inline uint32_t get_last_branch() { return reg.last_branch; }
|
||||||
uint32_t get_last_branch(){return reg.last_branch;}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct ${coreDef.name}_regs {<%
|
struct ${coreDef.name}_regs {<%
|
||||||
|
|
|
@ -1,34 +1,34 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
/*******************************************************************************
|
||||||
// Copyright (C) 2017,2018 MINRES Technologies GmbH
|
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
//
|
*
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
//
|
*
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
*******************************************************************************/
|
||||||
|
|
||||||
#include "util/ities.h"
|
#include "util/ities.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
|
@ -43,30 +43,33 @@ extern "C" {
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#include <fstream>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace iss::arch;
|
using namespace iss::arch;
|
||||||
|
|
||||||
|
constexpr std::array<const uint32_t, 39> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::${coreDef.name}_reg_size;
|
||||||
|
constexpr std::array<const uint32_t, 40> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::${coreDef.name}_reg_byte_offset;
|
||||||
|
|
||||||
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() {
|
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() {
|
||||||
reg.icount=0;
|
reg.icount = 0;
|
||||||
|
reg.machine_state = 0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}(){
|
${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ${coreDef.name.toLowerCase()}::reset(uint64_t address) {
|
void ${coreDef.name.toLowerCase()}::reset(uint64_t address) {
|
||||||
for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0));
|
for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i)
|
||||||
|
set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0));
|
||||||
reg.PC=address;
|
reg.PC=address;
|
||||||
reg.NEXT_PC=reg.PC;
|
reg.NEXT_PC=reg.PC;
|
||||||
reg.trap_state=0;
|
reg.trap_state=0;
|
||||||
reg.machine_state=0x0;
|
reg.machine_state=0x3;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* ${coreDef.name.toLowerCase()}::get_regs_base_ptr(){
|
uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() { return reinterpret_cast<uint8_t*>(®); }
|
||||||
return reinterpret_cast<uint8_t*>(®);
|
|
||||||
}
|
|
||||||
|
|
||||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) {
|
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) {
|
||||||
return phys_addr_t(pc); // change logical address to physical address
|
return phys_addr_t(pc); // change logical address to physical address
|
||||||
|
|
|
@ -1,38 +1,34 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
/*******************************************************************************
|
||||||
// Copyright (C) 2017, MINRES Technologies GmbH
|
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
//
|
*
|
||||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
//
|
*
|
||||||
// 3. Neither the name of the copyright holder nor the names of its contributors
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
// POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
// Contributors:
|
*******************************************************************************/
|
||||||
// eyck@minres.com - initial API and implementation
|
|
||||||
//
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/arch/riscv_hart_msu_vp.h>
|
#include <iss/arch/riscv_hart_msu_vp.h>
|
||||||
|
@ -44,12 +40,12 @@
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
|
|
||||||
#include <iss/debugger/riscv_target_adapter.h>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <iss/debugger/riscv_target_adapter.h>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace vm {
|
namespace vm {
|
||||||
namespace fp_impl{
|
namespace fp_impl {
|
||||||
void add_fp_functions_2_module(llvm::Module *, unsigned);
|
void add_fp_functions_2_module(llvm::Module *, unsigned);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +69,7 @@ public:
|
||||||
|
|
||||||
void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; }
|
void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; }
|
||||||
|
|
||||||
target_adapter_if *accquire_target_adapter(server_if *srv) {
|
target_adapter_if *accquire_target_adapter(server_if *srv) override {
|
||||||
debugger_if::dbg_enabled = true;
|
debugger_if::dbg_enabled = true;
|
||||||
if (vm::vm_base<ARCH>::tgt_adapter == nullptr)
|
if (vm::vm_base<ARCH>::tgt_adapter == nullptr)
|
||||||
vm::vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
|
vm::vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
|
||||||
|
@ -87,7 +83,7 @@ protected:
|
||||||
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_module(llvm::Module* m) override {
|
void setup_module(llvm::Module *m) override {
|
||||||
super::setup_module(m);
|
super::setup_module(m);
|
||||||
vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
|
vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -117,7 +113,7 @@ protected:
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
||||||
llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
||||||
this->get_type(traits<ARCH>::XLEN));
|
this->get_type(traits<ARCH>::XLEN));
|
||||||
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,9 +132,9 @@ protected:
|
||||||
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
||||||
std::array<compile_func, LUT_SIZE> lut_11;
|
std::array<compile_func, LUT_SIZE> lut_11;
|
||||||
|
|
||||||
std::array<compile_func*, 4> qlut;
|
std::array<compile_func *, 4> qlut;
|
||||||
|
|
||||||
std::array<const uint32_t, 4> lutmasks = { { EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32 } };
|
std::array<const uint32_t, 4> lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}};
|
||||||
|
|
||||||
void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
|
void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
|
||||||
compile_func f) {
|
compile_func f) {
|
||||||
|
@ -248,7 +244,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
||||||
phys_addr_t paddr(pc);
|
phys_addr_t paddr(pc);
|
||||||
try {
|
try {
|
||||||
uint8_t *const data = (uint8_t *)&insn;
|
auto *const data = (uint8_t *)&insn;
|
||||||
paddr = this->core.v2p(pc);
|
paddr = this->core.v2p(pc);
|
||||||
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
||||||
auto res = this->core.read(paddr, 2, data);
|
auto res = this->core.read(paddr, 2, data);
|
||||||
|
@ -282,7 +278,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(llvm::BasicBlock
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
||||||
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||||
|
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
|
@ -292,7 +289,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
||||||
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8);
|
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8);
|
||||||
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||||
|
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||||
|
@ -305,11 +303,10 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) {
|
||||||
this->builder.SetInsertPoint(trap_blk);
|
this->builder.SetInsertPoint(trap_blk);
|
||||||
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||||
std::vector<llvm::Value *> args{
|
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||||
this->core_ptr,
|
std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
|
||||||
this->adj_to64(trap_state_val),
|
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
|
||||||
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
|
|
||||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
||||||
auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||||
this->builder.CreateRet(trap_addr_val);
|
this->builder.CreateRet(trap_addr_val);
|
||||||
|
@ -327,10 +324,9 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) {
|
std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) {
|
||||||
std::unique_ptr<${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>> ret =
|
auto ret = new ${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*core, dump);
|
||||||
std::make_unique<${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>>(*core, dump);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port);
|
return std::unique_ptr<vm_if>(ret);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
|
@ -44,6 +44,12 @@
|
||||||
#include <iss/debugger/riscv_target_adapter.h>
|
#include <iss/debugger/riscv_target_adapter.h>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
|
namespace vm {
|
||||||
|
namespace fp_impl {
|
||||||
|
void add_fp_functions_2_module(llvm::Module *, unsigned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace CORE_DEF_NAME {
|
namespace CORE_DEF_NAME {
|
||||||
using namespace iss::arch;
|
using namespace iss::arch;
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -63,7 +69,7 @@ public:
|
||||||
|
|
||||||
void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; }
|
void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; }
|
||||||
|
|
||||||
target_adapter_if *accquire_target_adapter(server_if *srv) {
|
target_adapter_if *accquire_target_adapter(server_if *srv) override {
|
||||||
debugger_if::dbg_enabled = true;
|
debugger_if::dbg_enabled = true;
|
||||||
if (vm::vm_base<ARCH>::tgt_adapter == nullptr)
|
if (vm::vm_base<ARCH>::tgt_adapter == nullptr)
|
||||||
vm::vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
|
vm::vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
|
||||||
|
@ -77,8 +83,12 @@ protected:
|
||||||
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
void setup_module(llvm::Module *m) override {
|
||||||
unsigned size) const {
|
super::setup_module(m);
|
||||||
|
vm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal, unsigned size) {
|
||||||
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +235,7 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
||||||
phys_addr_t paddr(pc);
|
phys_addr_t paddr(pc);
|
||||||
try {
|
try {
|
||||||
uint8_t *const data = (uint8_t *)&insn;
|
auto *const data = (uint8_t *)&insn;
|
||||||
paddr = this->core.v2p(pc);
|
paddr = this->core.v2p(pc);
|
||||||
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
||||||
auto res = this->core.read(paddr, 2, data);
|
auto res = this->core.read(paddr, 2, data);
|
||||||
|
@ -242,7 +252,6 @@ vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt,
|
||||||
}
|
}
|
||||||
if (insn == 0x0000006f || (insn & 0xffff) == 0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
if (insn == 0x0000006f || (insn & 0xffff) == 0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||||
// curr pc on stack
|
// curr pc on stack
|
||||||
typename vm_impl<ARCH>::processing_pc_entry addr(*this, pc, paddr);
|
|
||||||
++inst_cnt;
|
++inst_cnt;
|
||||||
auto lut_val = extract_fields(insn);
|
auto lut_val = extract_fields(insn);
|
||||||
auto f = qlut[insn & 0x3][lut_val];
|
auto f = qlut[insn & 0x3][lut_val];
|
||||||
|
@ -260,6 +269,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(llvm::BasicBlock
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
||||||
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||||
|
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||||
|
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
|
@ -269,6 +280,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
||||||
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8);
|
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8);
|
||||||
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||||
|
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||||
|
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||||
|
@ -281,6 +294,8 @@ template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(llvm::BasicBlock *trap_blk) {
|
||||||
this->builder.SetInsertPoint(trap_blk);
|
this->builder.SetInsertPoint(trap_blk);
|
||||||
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||||
|
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||||
|
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||||
std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
|
std::vector<llvm::Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
|
||||||
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
|
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
|
||||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
||||||
|
@ -298,12 +313,10 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl
|
||||||
|
|
||||||
} // namespace CORE_DEF_NAME
|
} // namespace CORE_DEF_NAME
|
||||||
|
|
||||||
template <>
|
template <> std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) {
|
||||||
std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) {
|
auto ret = new CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>(*core, dump);
|
||||||
std::unique_ptr<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>> ret =
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
|
||||||
std::make_unique<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>>(*core, dump);
|
return std::unique_ptr<vm_if>(ret);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
Loading…
Reference in New Issue