Compare commits
4 Commits
458c773e19
...
4418fa7e4f
Author | SHA1 | Date | |
---|---|---|---|
4418fa7e4f | |||
adaa7e1c04 | |||
0eb1db0e7e | |||
e48597b2b7 |
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
RV32I:
|
RVI:
|
||||||
LUI:
|
LUI:
|
||||||
index: 0
|
index: 0
|
||||||
encoding: 0b00000000000000000000000000110111
|
encoding: 0b00000000000000000000000000110111
|
||||||
@ -27,84 +27,84 @@ RV32I:
|
|||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
BEQ:
|
BEQ:
|
||||||
index: 4
|
index: 4
|
||||||
encoding: 0b00000000000000000000000001100011
|
encoding: 0b00000000000000000000000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
BNE:
|
BNE:
|
||||||
index: 5
|
index: 5
|
||||||
encoding: 0b00000000000000000001000001100011
|
encoding: 0b00000000000000000001000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
BLT:
|
BLT:
|
||||||
index: 6
|
index: 6
|
||||||
encoding: 0b00000000000000000100000001100011
|
encoding: 0b00000000000000000100000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
BGE:
|
BGE:
|
||||||
index: 7
|
index: 7
|
||||||
encoding: 0b00000000000000000101000001100011
|
encoding: 0b00000000000000000101000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
BLTU:
|
BLTU:
|
||||||
index: 8
|
index: 8
|
||||||
encoding: 0b00000000000000000110000001100011
|
encoding: 0b00000000000000000110000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
BGEU:
|
BGEU:
|
||||||
index: 9
|
index: 9
|
||||||
encoding: 0b00000000000000000111000001100011
|
encoding: 0b00000000000000000111000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
LB:
|
LB:
|
||||||
index: 10
|
index: 10
|
||||||
encoding: 0b00000000000000000000000000000011
|
encoding: 0b00000000000000000000000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
LH:
|
LH:
|
||||||
index: 11
|
index: 11
|
||||||
encoding: 0b00000000000000000001000000000011
|
encoding: 0b00000000000000000001000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
LW:
|
LW:
|
||||||
index: 12
|
index: 12
|
||||||
encoding: 0b00000000000000000010000000000011
|
encoding: 0b00000000000000000010000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
LBU:
|
LBU:
|
||||||
index: 13
|
index: 13
|
||||||
encoding: 0b00000000000000000100000000000011
|
encoding: 0b00000000000000000100000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
LHU:
|
LHU:
|
||||||
index: 14
|
index: 14
|
||||||
encoding: 0b00000000000000000101000000000011
|
encoding: 0b00000000000000000101000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
SB:
|
SB:
|
||||||
index: 15
|
index: 15
|
||||||
encoding: 0b00000000000000000000000000100011
|
encoding: 0b00000000000000000000000000100011
|
||||||
@ -356,56 +356,56 @@ RV32M:
|
|||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
MULH:
|
MULH:
|
||||||
index: 50
|
index: 50
|
||||||
encoding: 0b00000010000000000001000000110011
|
encoding: 0b00000010000000000001000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
MULHSU:
|
MULHSU:
|
||||||
index: 51
|
index: 51
|
||||||
encoding: 0b00000010000000000010000000110011
|
encoding: 0b00000010000000000010000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
MULHU:
|
MULHU:
|
||||||
index: 52
|
index: 52
|
||||||
encoding: 0b00000010000000000011000000110011
|
encoding: 0b00000010000000000011000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
DIV:
|
DIV:
|
||||||
index: 53
|
index: 53
|
||||||
encoding: 0b00000010000000000100000000110011
|
encoding: 0b00000010000000000100000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 17
|
delay: 1
|
||||||
DIVU:
|
DIVU:
|
||||||
index: 54
|
index: 54
|
||||||
encoding: 0b00000010000000000101000000110011
|
encoding: 0b00000010000000000101000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 17
|
delay: 1
|
||||||
REM:
|
REM:
|
||||||
index: 55
|
index: 55
|
||||||
encoding: 0b00000010000000000110000000110011
|
encoding: 0b00000010000000000110000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 17
|
delay: 1
|
||||||
REMU:
|
REMU:
|
||||||
index: 56
|
index: 56
|
||||||
encoding: 0b00000010000000000111000000110011
|
encoding: 0b00000010000000000111000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 17
|
delay: 1
|
||||||
Zca:
|
Zca:
|
||||||
C__ADDI4SPN:
|
C__ADDI4SPN:
|
||||||
index: 57
|
index: 57
|
||||||
@ -420,7 +420,7 @@ Zca:
|
|||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
C__SW:
|
C__SW:
|
||||||
index: 59
|
index: 59
|
||||||
encoding: 0b1100000000000000
|
encoding: 0b1100000000000000
|
||||||
@ -542,14 +542,14 @@ Zca:
|
|||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
C__BNEZ:
|
C__BNEZ:
|
||||||
index: 76
|
index: 76
|
||||||
encoding: 0b1110000000000001
|
encoding: 0b1110000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,2]
|
delay: [1,1]
|
||||||
C__SLLI:
|
C__SLLI:
|
||||||
index: 77
|
index: 77
|
||||||
encoding: 0b0000000000000010
|
encoding: 0b0000000000000010
|
||||||
@ -564,7 +564,7 @@ Zca:
|
|||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 2
|
delay: 1
|
||||||
C__MV:
|
C__MV:
|
||||||
index: 79
|
index: 79
|
||||||
encoding: 0b1000000000000010
|
encoding: 0b1000000000000010
|
||||||
|
@ -37,6 +37,7 @@ def getRegisterSizes(){
|
|||||||
return regs
|
return regs
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
// clang-format off
|
||||||
#include "${coreDef.name.toLowerCase()}.h"
|
#include "${coreDef.name.toLowerCase()}.h"
|
||||||
#include "util/ities.h"
|
#include "util/ities.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
@ -73,4 +74,4 @@ uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() {
|
|||||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &addr) {
|
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &addr) {
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
|
@ -60,7 +60,7 @@ def getCString(def val){
|
|||||||
%>
|
%>
|
||||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||||
#define _${coreDef.name.toUpperCase()}_H_
|
#define _${coreDef.name.toUpperCase()}_H_
|
||||||
|
// clang-format off
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
@ -174,3 +174,4 @@ if(fcsr != null) {%>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
||||||
|
// clang-format on
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include <sysc/iss_factory.h>
|
#include <sysc/iss_factory.h>
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/arch/riscv_hart_m_p.h>
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
@ -128,3 +128,4 @@ volatile std::array<bool, ${array_count}> ${coreDef.name.toLowerCase()}_init = {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
@ -29,7 +29,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
#include <iss/asmjit/vm_base.h>
|
#include <iss/asmjit/vm_base.h>
|
||||||
#include <asmjit/asmjit.h>
|
#include <asmjit/asmjit.h>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <fp_functions.h>
|
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
@ -92,7 +92,7 @@ protected:
|
|||||||
auto sign_mask = 1ULL<<(W-1);
|
auto sign_mask = 1ULL<<(W-1);
|
||||||
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||||
}
|
}
|
||||||
#include "helper_func.h"
|
#include <vm/asmjit/helper_func.h>
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -278,3 +278,4 @@ volatile std::array<bool, 2> dummy = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
@ -34,6 +34,7 @@ def nativeTypeSize(int size){
|
|||||||
if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
|
if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
// clang-format off
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
@ -377,3 +378,4 @@ volatile std::array<bool, 2> dummy = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
@ -29,7 +29,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
@ -380,3 +380,4 @@ volatile std::array<bool, 2> dummy = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
@ -29,7 +29,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
@ -344,3 +344,4 @@ volatile std::array<bool, 2> dummy = {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
@ -320,6 +320,8 @@ protected:
|
|||||||
|
|
||||||
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
||||||
|
|
||||||
|
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||||
|
|
||||||
riscv_hart_m_p<BASE, FEAT>& arch;
|
riscv_hart_m_p<BASE, FEAT>& arch;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -822,7 +824,8 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
|
|||||||
x |= 0x80; // set pll lock upon writing
|
x |= 0x80; // set pll lock upon writing
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} break;
|
} break;
|
||||||
default: {}
|
default: {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::CSR: {
|
case traits<BASE>::CSR: {
|
||||||
|
@ -371,6 +371,8 @@ protected:
|
|||||||
|
|
||||||
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
||||||
|
|
||||||
|
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||||
|
|
||||||
riscv_hart_msu_vp<BASE>& arch;
|
riscv_hart_msu_vp<BASE>& arch;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -802,7 +804,8 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
x |= 0x80; // set pll lock upon writing
|
x |= 0x80; // set pll lock upon writing
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} break;
|
} break;
|
||||||
default: {}
|
default: {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::CSR: {
|
case traits<BASE>::CSR: {
|
||||||
@ -1225,9 +1228,9 @@ template <typename BASE> typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_har
|
|||||||
break;
|
break;
|
||||||
} else if(!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
|
} else if(!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
|
||||||
break;
|
break;
|
||||||
} else if(type == iss::access_type::FETCH ? !(pte & PTE_X)
|
} else if(type == iss::access_type::FETCH ? !(pte & PTE_X)
|
||||||
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
|
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
|
||||||
: !((pte & PTE_R) && (pte & PTE_W))) {
|
: !((pte & PTE_R) && (pte & PTE_W))) {
|
||||||
break;
|
break;
|
||||||
} else if((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
|
} else if((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -347,6 +347,8 @@ protected:
|
|||||||
|
|
||||||
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
||||||
|
|
||||||
|
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||||
|
|
||||||
riscv_hart_mu_p<BASE, FEAT>& arch;
|
riscv_hart_mu_p<BASE, FEAT>& arch;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1005,7 +1007,8 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
|
|||||||
x |= 0x80; // set pll lock upon writing
|
x |= 0x80; // set pll lock upon writing
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} break;
|
} break;
|
||||||
default: {}
|
default: {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::CSR: {
|
case traits<BASE>::CSR: {
|
||||||
|
@ -30,37 +30,41 @@
|
|||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include "tgc5c.h"
|
#include "tgc5c.h"
|
||||||
#include "util/ities.h"
|
#include "util/ities.h"
|
||||||
|
#include <util/logging.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <util/logging.h>
|
|
||||||
|
|
||||||
using namespace iss::arch;
|
using namespace iss::arch;
|
||||||
|
|
||||||
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_names;
|
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_names;
|
||||||
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_aliases;
|
constexpr std::array<const char*, 36> iss::arch::traits<iss::arch::tgc5c>::reg_aliases;
|
||||||
constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_bit_widths;
|
constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_bit_widths;
|
||||||
constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_byte_offsets;
|
constexpr std::array<const uint32_t, 43> iss::arch::traits<iss::arch::tgc5c>::reg_byte_offsets;
|
||||||
|
|
||||||
tgc5c::tgc5c() = default;
|
tgc5c::tgc5c() = default;
|
||||||
|
|
||||||
tgc5c::~tgc5c() = default;
|
tgc5c::~tgc5c() = default;
|
||||||
|
|
||||||
void tgc5c::reset(uint64_t address) {
|
void tgc5c::reset(uint64_t address) {
|
||||||
auto base_ptr = reinterpret_cast<traits<tgc5c>::reg_t*>(get_regs_base_ptr());
|
auto base_ptr = reinterpret_cast<traits<tgc5c>::reg_t*>(get_regs_base_ptr());
|
||||||
for(size_t i = 0; i < traits<tgc5c>::NUM_REGS; ++i)
|
for(size_t i=0; i<traits<tgc5c>::NUM_REGS; ++i)
|
||||||
*(base_ptr + i) = 0;
|
*(base_ptr+i)=0;
|
||||||
reg.PC = address;
|
reg.PC=address;
|
||||||
reg.NEXT_PC = reg.PC;
|
reg.NEXT_PC=reg.PC;
|
||||||
reg.PRIV = 0x3;
|
reg.PRIV=0x3;
|
||||||
reg.trap_state = 0;
|
reg.trap_state=0;
|
||||||
reg.icount = 0;
|
reg.icount=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* tgc5c::get_regs_base_ptr() { return reinterpret_cast<uint8_t*>(®); }
|
uint8_t *tgc5c::get_regs_base_ptr() {
|
||||||
|
return reinterpret_cast<uint8_t*>(®);
|
||||||
tgc5c::phys_addr_t tgc5c::virt2phys(const iss::addr_t& addr) {
|
|
||||||
return phys_addr_t(addr.access, addr.space, addr.val & traits<tgc5c>::addr_mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tgc5c::phys_addr_t tgc5c::virt2phys(const iss::addr_t &addr) {
|
||||||
|
return phys_addr_t(addr.access, addr.space, addr.val&traits<tgc5c>::addr_mask);
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#ifndef _TGC5C_H_
|
#ifndef _TGC5C_H_
|
||||||
#define _TGC5C_H_
|
#define _TGC5C_H_
|
||||||
|
// clang-format off
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
@ -46,103 +46,43 @@ struct tgc5c;
|
|||||||
template <> struct traits<tgc5c> {
|
template <> struct traits<tgc5c> {
|
||||||
|
|
||||||
constexpr static char const* const core_type = "TGC5C";
|
constexpr static char const* const core_type = "TGC5C";
|
||||||
|
|
||||||
static constexpr std::array<const char*, 36> reg_names{{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8",
|
static constexpr std::array<const char*, 36> reg_names{
|
||||||
"x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",
|
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "next_pc", "priv", "dpc"}};
|
||||||
"x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26",
|
|
||||||
"x27", "x28", "x29", "x30", "x31", "pc", "next_pc", "priv", "dpc"}};
|
|
||||||
|
|
||||||
static constexpr std::array<const char*, 36> reg_aliases{
|
static constexpr std::array<const char*, 36> reg_aliases{
|
||||||
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
|
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "next_pc", "priv", "dpc"}};
|
||||||
"s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "next_pc", "priv", "dpc"}};
|
|
||||||
|
|
||||||
enum constants {
|
enum constants {MISA_VAL=1073746180ULL, MARCHID_VAL=2147483651ULL, XLEN=32ULL, INSTR_ALIGNMENT=2ULL, RFS=32ULL, fence=0ULL, fencei=1ULL, fencevmal=2ULL, fencevmau=3ULL, CSR_SIZE=4096ULL, MUL_LEN=64ULL};
|
||||||
MISA_VAL = 1073746180ULL,
|
|
||||||
MARCHID_VAL = 2147483651ULL,
|
|
||||||
XLEN = 32ULL,
|
|
||||||
INSTR_ALIGNMENT = 2ULL,
|
|
||||||
RFS = 32ULL,
|
|
||||||
fence = 0ULL,
|
|
||||||
fencei = 1ULL,
|
|
||||||
fencevmal = 2ULL,
|
|
||||||
fencevmau = 3ULL,
|
|
||||||
CSR_SIZE = 4096ULL,
|
|
||||||
MUL_LEN = 64ULL
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr static unsigned FP_REGS_SIZE = 0;
|
constexpr static unsigned FP_REGS_SIZE = 0;
|
||||||
|
|
||||||
enum reg_e {
|
enum reg_e {
|
||||||
X0,
|
X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, X30, X31, PC, NEXT_PC, PRIV, DPC, NUM_REGS, TRAP_STATE=NUM_REGS, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION, LAST_BRANCH
|
||||||
X1,
|
|
||||||
X2,
|
|
||||||
X3,
|
|
||||||
X4,
|
|
||||||
X5,
|
|
||||||
X6,
|
|
||||||
X7,
|
|
||||||
X8,
|
|
||||||
X9,
|
|
||||||
X10,
|
|
||||||
X11,
|
|
||||||
X12,
|
|
||||||
X13,
|
|
||||||
X14,
|
|
||||||
X15,
|
|
||||||
X16,
|
|
||||||
X17,
|
|
||||||
X18,
|
|
||||||
X19,
|
|
||||||
X20,
|
|
||||||
X21,
|
|
||||||
X22,
|
|
||||||
X23,
|
|
||||||
X24,
|
|
||||||
X25,
|
|
||||||
X26,
|
|
||||||
X27,
|
|
||||||
X28,
|
|
||||||
X29,
|
|
||||||
X30,
|
|
||||||
X31,
|
|
||||||
PC,
|
|
||||||
NEXT_PC,
|
|
||||||
PRIV,
|
|
||||||
DPC,
|
|
||||||
NUM_REGS,
|
|
||||||
TRAP_STATE = NUM_REGS,
|
|
||||||
PENDING_TRAP,
|
|
||||||
ICOUNT,
|
|
||||||
CYCLE,
|
|
||||||
INSTRET,
|
|
||||||
INSTRUCTION,
|
|
||||||
LAST_BRANCH
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using reg_t = uint32_t;
|
using reg_t = uint32_t;
|
||||||
|
|
||||||
using addr_t = uint32_t;
|
using addr_t = uint32_t;
|
||||||
|
|
||||||
using code_word_t = uint32_t; // TODO: check removal
|
using code_word_t = uint32_t; //TODO: check removal
|
||||||
|
|
||||||
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||||
|
|
||||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||||
|
|
||||||
static constexpr std::array<const uint32_t, 43> reg_bit_widths{{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
static constexpr std::array<const uint32_t, 43> reg_bit_widths{
|
||||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,8,32,32,32,64,64,64,32,32}};
|
||||||
32, 32, 32, 32, 8, 32, 32, 32, 64, 64, 64, 32, 32}};
|
|
||||||
|
|
||||||
static constexpr std::array<const uint32_t, 43> reg_byte_offsets{
|
static constexpr std::array<const uint32_t, 43> reg_byte_offsets{
|
||||||
{0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84,
|
{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,137,141,145,149,157,165,173,177}};
|
||||||
88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 137, 141, 145, 149, 157, 165, 173, 177}};
|
|
||||||
|
|
||||||
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 { MEM, FENCE, RES, CSR };
|
enum mem_type_e { MEM, FENCE, RES, CSR };
|
||||||
|
|
||||||
enum class opcode_e {
|
enum class opcode_e {
|
||||||
LUI = 0,
|
LUI = 0,
|
||||||
AUIPC = 1,
|
AUIPC = 1,
|
||||||
@ -235,17 +175,17 @@ template <> struct traits<tgc5c> {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tgc5c : public arch_if {
|
struct tgc5c: public arch_if {
|
||||||
|
|
||||||
using virt_addr_t = typename traits<tgc5c>::virt_addr_t;
|
using virt_addr_t = typename traits<tgc5c>::virt_addr_t;
|
||||||
using phys_addr_t = typename traits<tgc5c>::phys_addr_t;
|
using phys_addr_t = typename traits<tgc5c>::phys_addr_t;
|
||||||
using reg_t = typename traits<tgc5c>::reg_t;
|
using reg_t = typename traits<tgc5c>::reg_t;
|
||||||
using addr_t = typename traits<tgc5c>::addr_t;
|
using addr_t = typename traits<tgc5c>::addr_t;
|
||||||
|
|
||||||
tgc5c();
|
tgc5c();
|
||||||
~tgc5c();
|
~tgc5c();
|
||||||
|
|
||||||
void reset(uint64_t address = 0) override;
|
void reset(uint64_t address=0) override;
|
||||||
|
|
||||||
uint8_t* get_regs_base_ptr() override;
|
uint8_t* get_regs_base_ptr() override;
|
||||||
|
|
||||||
@ -261,43 +201,44 @@ struct tgc5c : public arch_if {
|
|||||||
|
|
||||||
inline uint32_t get_last_branch() { return reg.last_branch; }
|
inline uint32_t get_last_branch() { return reg.last_branch; }
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct TGC5C_regs {
|
struct TGC5C_regs {
|
||||||
uint32_t X0 = 0;
|
uint32_t X0 = 0;
|
||||||
uint32_t X1 = 0;
|
uint32_t X1 = 0;
|
||||||
uint32_t X2 = 0;
|
uint32_t X2 = 0;
|
||||||
uint32_t X3 = 0;
|
uint32_t X3 = 0;
|
||||||
uint32_t X4 = 0;
|
uint32_t X4 = 0;
|
||||||
uint32_t X5 = 0;
|
uint32_t X5 = 0;
|
||||||
uint32_t X6 = 0;
|
uint32_t X6 = 0;
|
||||||
uint32_t X7 = 0;
|
uint32_t X7 = 0;
|
||||||
uint32_t X8 = 0;
|
uint32_t X8 = 0;
|
||||||
uint32_t X9 = 0;
|
uint32_t X9 = 0;
|
||||||
uint32_t X10 = 0;
|
uint32_t X10 = 0;
|
||||||
uint32_t X11 = 0;
|
uint32_t X11 = 0;
|
||||||
uint32_t X12 = 0;
|
uint32_t X12 = 0;
|
||||||
uint32_t X13 = 0;
|
uint32_t X13 = 0;
|
||||||
uint32_t X14 = 0;
|
uint32_t X14 = 0;
|
||||||
uint32_t X15 = 0;
|
uint32_t X15 = 0;
|
||||||
uint32_t X16 = 0;
|
uint32_t X16 = 0;
|
||||||
uint32_t X17 = 0;
|
uint32_t X17 = 0;
|
||||||
uint32_t X18 = 0;
|
uint32_t X18 = 0;
|
||||||
uint32_t X19 = 0;
|
uint32_t X19 = 0;
|
||||||
uint32_t X20 = 0;
|
uint32_t X20 = 0;
|
||||||
uint32_t X21 = 0;
|
uint32_t X21 = 0;
|
||||||
uint32_t X22 = 0;
|
uint32_t X22 = 0;
|
||||||
uint32_t X23 = 0;
|
uint32_t X23 = 0;
|
||||||
uint32_t X24 = 0;
|
uint32_t X24 = 0;
|
||||||
uint32_t X25 = 0;
|
uint32_t X25 = 0;
|
||||||
uint32_t X26 = 0;
|
uint32_t X26 = 0;
|
||||||
uint32_t X27 = 0;
|
uint32_t X27 = 0;
|
||||||
uint32_t X28 = 0;
|
uint32_t X28 = 0;
|
||||||
uint32_t X29 = 0;
|
uint32_t X29 = 0;
|
||||||
uint32_t X30 = 0;
|
uint32_t X30 = 0;
|
||||||
uint32_t X31 = 0;
|
uint32_t X31 = 0;
|
||||||
uint32_t PC = 0;
|
uint32_t PC = 0;
|
||||||
uint32_t NEXT_PC = 0;
|
uint32_t NEXT_PC = 0;
|
||||||
uint8_t PRIV = 0;
|
uint8_t PRIV = 0;
|
||||||
uint32_t DPC = 0;
|
uint32_t DPC = 0;
|
||||||
uint32_t trap_state = 0, pending_trap = 0;
|
uint32_t trap_state = 0, pending_trap = 0;
|
||||||
uint64_t icount = 0;
|
uint64_t icount = 0;
|
||||||
@ -308,13 +249,15 @@ struct tgc5c : public arch_if {
|
|||||||
} reg;
|
} reg;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
|
uint64_t interrupt_sim=0;
|
||||||
|
|
||||||
uint64_t interrupt_sim = 0;
|
uint32_t get_fcsr(){return 0;}
|
||||||
|
void set_fcsr(uint32_t val){}
|
||||||
|
|
||||||
uint32_t get_fcsr() { return 0; }
|
|
||||||
void set_fcsr(uint32_t val) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace arch
|
}
|
||||||
} // namespace iss
|
}
|
||||||
#endif /* _TGC5C_H_ */
|
#endif /* _TGC5C_H_ */
|
||||||
|
// clang-format on
|
||||||
|
@ -19,7 +19,7 @@ x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
x86::Gp get_reg_for(jit_holder& jh, unsigned idx) {
|
x86::Gp get_reg_for(jit_holder& jh, unsigned idx) {
|
||||||
// can check for regs in jh and return them instead of creating new ones
|
// TODO can check for regs in jh and return them instead of creating new ones
|
||||||
switch(traits::reg_bit_widths[idx]) {
|
switch(traits::reg_bit_widths[idx]) {
|
||||||
case 8:
|
case 8:
|
||||||
return jh.cc.newInt8();
|
return jh.cc.newInt8();
|
||||||
@ -82,7 +82,9 @@ void gen_instr_prologue(jit_holder& jh, addr_t pc) {
|
|||||||
cc.mov(get_reg_ptr(jh, traits::PC), jh.next_pc);
|
cc.mov(get_reg_ptr(jh, traits::PC), jh.next_pc);
|
||||||
|
|
||||||
cc.comment("\n//*trap_state=*pending_trap;");
|
cc.comment("\n//*trap_state=*pending_trap;");
|
||||||
cc.mov(get_reg_ptr(jh, traits::PENDING_TRAP), jh.trap_state);
|
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
||||||
|
cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE));
|
||||||
|
cc.mov(get_reg_ptr(jh, traits::PENDING_TRAP), current_trap_state);
|
||||||
|
|
||||||
cc.comment("\n//increment *next_pc");
|
cc.comment("\n//increment *next_pc");
|
||||||
cc.mov(jh.next_pc, pc);
|
cc.mov(jh.next_pc, pc);
|
||||||
@ -91,20 +93,20 @@ void gen_instr_epilogue(jit_holder& jh) {
|
|||||||
auto& cc = jh.cc;
|
auto& cc = jh.cc;
|
||||||
|
|
||||||
cc.comment("\n//if(*trap_state!=0) goto trap_entry;");
|
cc.comment("\n//if(*trap_state!=0) goto trap_entry;");
|
||||||
cc.test(jh.trap_state, jh.trap_state);
|
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
||||||
cc.jnz(jh.trap_entry);
|
cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE));
|
||||||
|
cc.cmp(current_trap_state, 0);
|
||||||
|
cc.jne(jh.trap_entry);
|
||||||
|
|
||||||
// Does this need to be done after every single instruction?
|
// TODO: Does not need to be done for every instruction, only when needed
|
||||||
cc.comment("\n//write back regs to mem");
|
cc.comment("\n//write back regs to mem");
|
||||||
write_reg_to_mem(jh, jh.pc, traits::PC);
|
write_reg_to_mem(jh, jh.pc, traits::PC);
|
||||||
write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC);
|
write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC);
|
||||||
write_reg_to_mem(jh, jh.trap_state, traits::TRAP_STATE);
|
|
||||||
}
|
}
|
||||||
void gen_block_prologue(jit_holder& jh) override {
|
void gen_block_prologue(jit_holder& jh) override {
|
||||||
|
|
||||||
jh.pc = load_reg_from_mem(jh, traits::PC);
|
jh.pc = load_reg_from_mem(jh, traits::PC);
|
||||||
jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC);
|
jh.next_pc = load_reg_from_mem(jh, traits::NEXT_PC);
|
||||||
jh.trap_state = load_reg_from_mem(jh, traits::TRAP_STATE);
|
|
||||||
}
|
}
|
||||||
void gen_block_epilogue(jit_holder& jh) override {
|
void gen_block_epilogue(jit_holder& jh) override {
|
||||||
x86::Compiler& cc = jh.cc;
|
x86::Compiler& cc = jh.cc;
|
||||||
@ -112,7 +114,12 @@ void gen_block_epilogue(jit_holder& jh) override {
|
|||||||
cc.ret(jh.next_pc);
|
cc.ret(jh.next_pc);
|
||||||
|
|
||||||
cc.bind(jh.trap_entry);
|
cc.bind(jh.trap_entry);
|
||||||
cc.comment("\n//enter_trap(core_ptr, *trap_state, *pc, 0);");
|
cc.comment("\n//Prepare for enter_trap;");
|
||||||
|
// Make sure cached values are written back
|
||||||
|
cc.comment("\n//write back regs to mem");
|
||||||
|
write_reg_to_mem(jh, jh.pc, traits::PC);
|
||||||
|
write_reg_to_mem(jh, jh.next_pc, traits::NEXT_PC);
|
||||||
|
this->gen_sync(jh, POST_SYNC, -1);
|
||||||
|
|
||||||
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
x86::Gp current_trap_state = get_reg_for(jh, traits::TRAP_STATE);
|
||||||
cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE));
|
cc.mov(current_trap_state, get_reg_ptr(jh, traits::TRAP_STATE));
|
||||||
@ -121,23 +128,43 @@ void gen_block_epilogue(jit_holder& jh) override {
|
|||||||
cc.mov(current_pc, get_reg_ptr(jh, traits::PC));
|
cc.mov(current_pc, get_reg_ptr(jh, traits::PC));
|
||||||
|
|
||||||
x86::Gp instr = cc.newInt32("instr");
|
x86::Gp instr = cc.newInt32("instr");
|
||||||
cc.mov(instr, 0);
|
cc.mov(instr, 0); // this is not correct
|
||||||
|
cc.comment("\n//enter trap call;");
|
||||||
InvokeNode* call_enter_trap;
|
InvokeNode* call_enter_trap;
|
||||||
cc.invoke(&call_enter_trap, &enter_trap, FuncSignatureT<uint64_t, void*, uint64_t, uint64_t, uint64_t>());
|
cc.invoke(&call_enter_trap, &enter_trap, FuncSignatureT<uint64_t, void*, uint64_t, uint64_t, uint64_t>());
|
||||||
call_enter_trap->setArg(0, jh.arch_if_ptr);
|
call_enter_trap->setArg(0, jh.arch_if_ptr);
|
||||||
call_enter_trap->setArg(1, current_trap_state);
|
call_enter_trap->setArg(1, current_trap_state);
|
||||||
call_enter_trap->setArg(2, current_pc);
|
call_enter_trap->setArg(2, current_pc);
|
||||||
call_enter_trap->setArg(3, instr);
|
call_enter_trap->setArg(3, instr);
|
||||||
|
|
||||||
|
x86::Gp current_next_pc = get_reg_for(jh, traits::NEXT_PC);
|
||||||
|
cc.mov(current_next_pc, get_reg_ptr(jh, traits::NEXT_PC));
|
||||||
|
cc.mov(jh.next_pc, current_next_pc);
|
||||||
|
|
||||||
cc.comment("\n//*last_branch = std::numeric_limits<uint32_t>::max();");
|
cc.comment("\n//*last_branch = std::numeric_limits<uint32_t>::max();");
|
||||||
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max());
|
cc.mov(get_reg_ptr(jh, traits::LAST_BRANCH), std::numeric_limits<uint32_t>::max());
|
||||||
cc.comment("\n//return *next_pc;");
|
cc.comment("\n//return *next_pc;");
|
||||||
cc.ret(jh.next_pc);
|
cc.ret(jh.next_pc);
|
||||||
}
|
}
|
||||||
// TODO implement
|
/*
|
||||||
|
inline void raise(uint16_t trap_id, uint16_t cause){
|
||||||
void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) { jh.cc.comment("//gen_raise"); }
|
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||||
void gen_wait(jit_holder& jh, unsigned type) { jh.cc.comment("//gen_wait"); }
|
this->core.reg.trap_state = trap_val;
|
||||||
void gen_leave(jit_holder& jh, unsigned lvl) { jh.cc.comment("//gen_leave"); }
|
this->template get_reg<uint32_t>(traits::NEXT_PC) = std::numeric_limits<uint32_t>::max();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
inline void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) {
|
||||||
|
auto& cc = jh.cc;
|
||||||
|
cc.comment("//gen_raise");
|
||||||
|
auto tmp1 = get_reg_for(jh, traits::TRAP_STATE);
|
||||||
|
cc.mov(tmp1, 0x80ULL << 24 | (cause << 16) | trap_id);
|
||||||
|
cc.mov(get_reg_ptr(jh, traits::TRAP_STATE), tmp1);
|
||||||
|
auto tmp2 = get_reg_for(jh, traits::NEXT_PC);
|
||||||
|
cc.mov(tmp2, std::numeric_limits<uint32_t>::max());
|
||||||
|
cc.mov(get_reg_ptr(jh, traits::NEXT_PC), tmp2);
|
||||||
|
}
|
||||||
|
inline void gen_wait(jit_holder& jh, unsigned type) { jh.cc.comment("//gen_wait"); }
|
||||||
|
inline void gen_leave(jit_holder& jh, unsigned lvl) { jh.cc.comment("//gen_leave"); }
|
||||||
|
|
||||||
enum operation { add, sub, band, bor, bxor, shl, sar, shr };
|
enum operation { add, sub, band, bor, bxor, shl, sar, shr };
|
||||||
|
|
||||||
@ -342,24 +369,12 @@ x86::Gp gen_operation(jit_holder& jh, binary_operation op, x86::Gp a) {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* template <typename T>
|
|
||||||
inline typename std::enable_if_t<std::is_unsigned<T>::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool
|
|
||||||
is_signed) const { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); jh.cc.mov(val_reg,
|
|
||||||
val); if(is_signed) jh.cc.movsx(tmp, val_reg); else jh.cc.movzx(tmp,val_reg); return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline typename std::enable_if_t<std::is_signed<T>::value, x86::Gp> gen_ext(jit_holder& jh, T val, unsigned size, bool
|
|
||||||
is_signed) const { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); jh.cc.mov(val_reg,
|
|
||||||
val); if(is_signed) jh.cc.movsx(tmp, val_reg); else jh.cc.movzx(tmp,val_reg); return tmp;
|
|
||||||
} */
|
|
||||||
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
|
||||||
inline x86::Gp gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) {
|
inline x86::Gp gen_ext(jit_holder& jh, T val, unsigned size, bool is_signed) {
|
||||||
auto val_reg = get_reg_for(jh, sizeof(val) * 8);
|
auto val_reg = get_reg_for(jh, sizeof(val) * 8, is_signed);
|
||||||
jh.cc.mov(val_reg, val);
|
jh.cc.mov(val_reg, val);
|
||||||
return gen_ext(jh, val_reg, size, is_signed);
|
return gen_ext(jh, val_reg, size, is_signed);
|
||||||
}
|
}
|
||||||
// explicit Gp size cast
|
|
||||||
inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signed) {
|
inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signed) {
|
||||||
auto& cc = jh.cc;
|
auto& cc = jh.cc;
|
||||||
if(is_signed) {
|
if(is_signed) {
|
||||||
@ -398,7 +413,6 @@ inline x86::Gp gen_ext(jit_holder& jh, x86::Gp val, unsigned size, bool is_signe
|
|||||||
throw std::runtime_error("Invalid size in gen_ext");
|
throw std::runtime_error("Invalid size in gen_ext");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint32_t length) {
|
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint32_t length) {
|
||||||
x86::Compiler& cc = jh.cc;
|
x86::Compiler& cc = jh.cc;
|
||||||
auto ret_reg = cc.newInt32();
|
auto ret_reg = cc.newInt32();
|
||||||
@ -447,31 +461,18 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint3
|
|||||||
invokeNode->setArg(2, mem_type_reg);
|
invokeNode->setArg(2, mem_type_reg);
|
||||||
invokeNode->setArg(3, addr);
|
invokeNode->setArg(3, addr);
|
||||||
invokeNode->setArg(4, val_ptr);
|
invokeNode->setArg(4, val_ptr);
|
||||||
|
cc.cmp(ret_reg, 0);
|
||||||
|
cc.jne(jh.trap_entry);
|
||||||
|
|
||||||
cc.mov(val_reg, x86::ptr_64(val_ptr));
|
cc.mov(val_reg, x86::ptr_64(val_ptr));
|
||||||
cc.and_(val_reg, mask);
|
cc.and_(val_reg, mask);
|
||||||
cc.cmp(ret_reg, 0);
|
|
||||||
cc.jne(jh.trap_entry);
|
|
||||||
return val_reg;
|
return val_reg;
|
||||||
}
|
}
|
||||||
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp length) {
|
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp length) {
|
||||||
uint32_t length_val = 0;
|
throw std::runtime_error("Invalid gen_read_mem");
|
||||||
auto length_ptr = jh.cc.newIntPtr();
|
|
||||||
jh.cc.mov(length_ptr, &length_val);
|
|
||||||
jh.cc.mov(x86::ptr_32(length_ptr), length);
|
|
||||||
|
|
||||||
return gen_read_mem(jh, type, addr, length);
|
|
||||||
}
|
}
|
||||||
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp length) {
|
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp length) {
|
||||||
auto addr_reg = jh.cc.newInt64();
|
throw std::runtime_error("Invalid gen_read_mem");
|
||||||
jh.cc.mov(addr_reg, addr);
|
|
||||||
|
|
||||||
uint32_t length_val = 0;
|
|
||||||
auto length_ptr = jh.cc.newIntPtr();
|
|
||||||
jh.cc.mov(length_ptr, &length_val);
|
|
||||||
jh.cc.mov(x86::ptr_32(length_ptr), length);
|
|
||||||
|
|
||||||
return gen_read_mem(jh, type, addr_reg, length_val);
|
|
||||||
}
|
}
|
||||||
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint32_t length) {
|
inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint32_t length) {
|
||||||
auto addr_reg = jh.cc.newInt64();
|
auto addr_reg = jh.cc.newInt64();
|
||||||
@ -479,32 +480,38 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, uint64_t addr, uint
|
|||||||
|
|
||||||
return gen_read_mem(jh, type, addr_reg, length);
|
return gen_read_mem(jh, type, addr_reg, length);
|
||||||
}
|
}
|
||||||
inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, int64_t val) {
|
inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, int64_t val, uint32_t length) {
|
||||||
auto val_reg = jh.cc.newInt64();
|
auto val_reg = get_reg_for(jh, length * 8, true);
|
||||||
jh.cc.mov(val_reg, val);
|
jh.cc.mov(val_reg, val);
|
||||||
gen_write_mem(jh, type, addr, val_reg);
|
gen_write_mem(jh, type, addr, val_reg, length);
|
||||||
}
|
}
|
||||||
inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp val) {
|
inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp val, uint32_t length) {
|
||||||
x86::Compiler& cc = jh.cc;
|
x86::Compiler& cc = jh.cc;
|
||||||
|
assert(val.size() == length);
|
||||||
auto mem_type_reg = cc.newInt32();
|
auto mem_type_reg = cc.newInt32();
|
||||||
jh.cc.mov(mem_type_reg, type);
|
jh.cc.mov(mem_type_reg, type);
|
||||||
auto space_reg = cc.newInt32();
|
auto space_reg = cc.newInt32();
|
||||||
jh.cc.mov(space_reg, static_cast<uint16_t>(iss::address_type::VIRTUAL));
|
jh.cc.mov(space_reg, static_cast<uint16_t>(iss::address_type::VIRTUAL));
|
||||||
auto ret_reg = cc.newInt32();
|
auto ret_reg = cc.newInt32();
|
||||||
InvokeNode* invokeNode;
|
InvokeNode* invokeNode;
|
||||||
|
switch(length) {
|
||||||
if(val.isGpb()) {
|
case 1:
|
||||||
cc.invoke(&invokeNode, &write_mem1, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint8_t>());
|
cc.invoke(&invokeNode, &write_mem1, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint8_t>());
|
||||||
} else if(val.isGpw()) {
|
|
||||||
cc.invoke(&invokeNode, &write_mem2, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint16_t>());
|
|
||||||
} else if(val.isGpd()) {
|
|
||||||
cc.invoke(&invokeNode, &write_mem4, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint32_t>());
|
|
||||||
} else if(val.isGpq()) {
|
|
||||||
cc.invoke(&invokeNode, &write_mem8, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t>());
|
|
||||||
} else
|
|
||||||
throw std::runtime_error("Invalid register size in gen_write_mem");
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cc.invoke(&invokeNode, &write_mem2, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint16_t>());
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
cc.invoke(&invokeNode, &write_mem4, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint32_t>());
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
cc.invoke(&invokeNode, &write_mem8, FuncSignatureT<uint32_t, uint64_t, uint32_t, uint32_t, uint64_t, uint64_t>());
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Invalid register size in gen_ext");
|
||||||
|
}
|
||||||
invokeNode->setRet(0, ret_reg);
|
invokeNode->setRet(0, ret_reg);
|
||||||
invokeNode->setArg(0, jh.arch_if_ptr);
|
invokeNode->setArg(0, jh.arch_if_ptr);
|
||||||
invokeNode->setArg(1, space_reg);
|
invokeNode->setArg(1, space_reg);
|
||||||
@ -515,16 +522,16 @@ inline void gen_write_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, x86::Gp
|
|||||||
cc.cmp(ret_reg, 0);
|
cc.cmp(ret_reg, 0);
|
||||||
cc.jne(jh.trap_entry);
|
cc.jne(jh.trap_entry);
|
||||||
}
|
}
|
||||||
inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp val) {
|
inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, x86::Gp val, uint32_t length) {
|
||||||
auto addr_reg = jh.cc.newInt64();
|
auto addr_reg = jh.cc.newUInt64();
|
||||||
jh.cc.mov(addr_reg, addr);
|
jh.cc.mov(addr_reg, addr);
|
||||||
gen_write_mem(jh, type, addr_reg, val);
|
gen_write_mem(jh, type, addr_reg, val, length);
|
||||||
}
|
}
|
||||||
inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, int64_t val) {
|
inline void gen_write_mem(jit_holder& jh, mem_type_e type, uint64_t addr, int64_t val, uint32_t length) {
|
||||||
auto val_reg = jh.cc.newInt64();
|
auto val_reg = get_reg_for(jh, length * 8, true);
|
||||||
jh.cc.mov(val_reg, val);
|
jh.cc.mov(val_reg, val);
|
||||||
|
|
||||||
auto addr_reg = jh.cc.newInt64();
|
auto addr_reg = jh.cc.newUInt64();
|
||||||
jh.cc.mov(addr_reg, addr);
|
jh.cc.mov(addr_reg, addr);
|
||||||
gen_write_mem(jh, type, addr_reg, val_reg);
|
gen_write_mem(jh, type, addr_reg, val_reg, length);
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user