Compare commits
	
		
			16 Commits
		
	
	
		
			a123beb301
			...
			feature/is
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a6c7b1427e | |||
| 250ea3c980 | |||
| 7b31b8ca8e | |||
| 91a23a4a18 | |||
| 21d3250e1a | |||
| 2b094c3162 | |||
| a32c83e1be | |||
| 7e45a25218 | |||
| 87b4082633 | |||
| 4dbc7433a5 | |||
| 99a9970ddd | |||
| 0b5de90fb1 | |||
| 15cd36dcd4 | |||
| 2281ec4144 | |||
| 11c481cec2 | |||
| 60d07f2eb6 | 
							
								
								
									
										1
									
								
								.project
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								.project
									
									
									
									
									
								
							@@ -23,6 +23,5 @@
 | 
			
		||||
		<nature>org.eclipse.cdt.core.ccnature</nature>
 | 
			
		||||
		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
 | 
			
		||||
		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
 | 
			
		||||
		<nature>org.eclipse.linuxtools.tmf.project.nature</nature>
 | 
			
		||||
	</natures>
 | 
			
		||||
</projectDescription>
 | 
			
		||||
 
 | 
			
		||||
@@ -40,11 +40,15 @@ set(LIB_SOURCES
 | 
			
		||||
if(TARGET ${CORE_NAME}_cpp)
 | 
			
		||||
    list(APPEND LIB_SOURCES ${${CORE_NAME}_OUTPUT_FILES})
 | 
			
		||||
else()
 | 
			
		||||
    FILE(GLOB GEN_SOURCES
 | 
			
		||||
        ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp
 | 
			
		||||
        ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp
 | 
			
		||||
    )
 | 
			
		||||
    list(APPEND LIB_SOURCES ${GEN_SOURCES})
 | 
			
		||||
    FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp)
 | 
			
		||||
    FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp)
 | 
			
		||||
    list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES})
 | 
			
		||||
    foreach(FILEPATH ${GEN_ISS_SOURCES})
 | 
			
		||||
        get_filename_component(CORE ${FILEPATH} NAME_WE)
 | 
			
		||||
        string(TOUPPER ${CORE} CORE)
 | 
			
		||||
        list(APPEND LIB_DEFINES CORE_${CORE})
 | 
			
		||||
    endforeach()
 | 
			
		||||
    message("Defines are ${LIB_DEFINES}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(TARGET RapidJSON OR TARGET RapidJSON::RapidJSON)
 | 
			
		||||
@@ -182,7 +186,10 @@ install(TARGETS tgc-sim
 | 
			
		||||
###############################################################################
 | 
			
		||||
if(TARGET scc-sysc)
 | 
			
		||||
	project(dbt-rise-tgc_sc VERSION 1.0.0)
 | 
			
		||||
    add_library(${PROJECT_NAME} src/sysc/core_complex.cpp)
 | 
			
		||||
    add_library(${PROJECT_NAME} 
 | 
			
		||||
    	src/sysc/core_complex.cpp
 | 
			
		||||
    	src/sysc/register_tgc_c.cpp
 | 
			
		||||
    )
 | 
			
		||||
    target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC)
 | 
			
		||||
    target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
 | 
			
		||||
    foreach(F IN LISTS TGC_SOURCES)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										537
									
								
								TGC_C_instr.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										537
									
								
								TGC_C_instr.yaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,537 @@
 | 
			
		||||
 | 
			
		||||
RV32I: 
 | 
			
		||||
  - LUI:
 | 
			
		||||
    encoding: 0b00000000000000000000000000110111
 | 
			
		||||
    mask: 0b00000000000000000000000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - AUIPC:
 | 
			
		||||
    encoding: 0b00000000000000000000000000010111
 | 
			
		||||
    mask: 0b00000000000000000000000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - JAL:
 | 
			
		||||
    encoding: 0b00000000000000000000000001101111
 | 
			
		||||
    mask: 0b00000000000000000000000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - JALR:
 | 
			
		||||
    encoding: 0b00000000000000000000000001100111
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - BEQ:
 | 
			
		||||
    encoding: 0b00000000000000000000000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - BNE:
 | 
			
		||||
    encoding: 0b00000000000000000001000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - BLT:
 | 
			
		||||
    encoding: 0b00000000000000000100000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - BGE:
 | 
			
		||||
    encoding: 0b00000000000000000101000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - BLTU:
 | 
			
		||||
    encoding: 0b00000000000000000110000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - BGEU:
 | 
			
		||||
    encoding: 0b00000000000000000111000001100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - LB:
 | 
			
		||||
    encoding: 0b00000000000000000000000000000011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - LH:
 | 
			
		||||
    encoding: 0b00000000000000000001000000000011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - LW:
 | 
			
		||||
    encoding: 0b00000000000000000010000000000011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - LBU:
 | 
			
		||||
    encoding: 0b00000000000000000100000000000011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - LHU:
 | 
			
		||||
    encoding: 0b00000000000000000101000000000011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SB:
 | 
			
		||||
    encoding: 0b00000000000000000000000000100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SH:
 | 
			
		||||
    encoding: 0b00000000000000000001000000100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SW:
 | 
			
		||||
    encoding: 0b00000000000000000010000000100011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - ADDI:
 | 
			
		||||
    encoding: 0b00000000000000000000000000010011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SLTI:
 | 
			
		||||
    encoding: 0b00000000000000000010000000010011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SLTIU:
 | 
			
		||||
    encoding: 0b00000000000000000011000000010011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - XORI:
 | 
			
		||||
    encoding: 0b00000000000000000100000000010011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - ORI:
 | 
			
		||||
    encoding: 0b00000000000000000110000000010011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - ANDI:
 | 
			
		||||
    encoding: 0b00000000000000000111000000010011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SLLI:
 | 
			
		||||
    encoding: 0b00000000000000000001000000010011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SRLI:
 | 
			
		||||
    encoding: 0b00000000000000000101000000010011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SRAI:
 | 
			
		||||
    encoding: 0b01000000000000000101000000010011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - ADD:
 | 
			
		||||
    encoding: 0b00000000000000000000000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SUB:
 | 
			
		||||
    encoding: 0b01000000000000000000000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SLL:
 | 
			
		||||
    encoding: 0b00000000000000000001000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SLT:
 | 
			
		||||
    encoding: 0b00000000000000000010000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SLTU:
 | 
			
		||||
    encoding: 0b00000000000000000011000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - XOR:
 | 
			
		||||
    encoding: 0b00000000000000000100000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SRL:
 | 
			
		||||
    encoding: 0b00000000000000000101000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - SRA:
 | 
			
		||||
    encoding: 0b01000000000000000101000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - OR:
 | 
			
		||||
    encoding: 0b00000000000000000110000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - AND:
 | 
			
		||||
    encoding: 0b00000000000000000111000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - FENCE:
 | 
			
		||||
    encoding: 0b00000000000000000000000000001111
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - ECALL:
 | 
			
		||||
    encoding: 0b00000000000000000000000001110011
 | 
			
		||||
    mask: 0b11111111111111111111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - EBREAK:
 | 
			
		||||
    encoding: 0b00000000000100000000000001110011
 | 
			
		||||
    mask: 0b11111111111111111111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - MRET:
 | 
			
		||||
    encoding: 0b00110000001000000000000001110011
 | 
			
		||||
    mask: 0b11111111111111111111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - WFI:
 | 
			
		||||
    encoding: 0b00010000010100000000000001110011
 | 
			
		||||
    mask: 0b11111111111111111111111111111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
Zicsr: 
 | 
			
		||||
  - CSRRW:
 | 
			
		||||
    encoding: 0b00000000000000000001000001110011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRRS:
 | 
			
		||||
    encoding: 0b00000000000000000010000001110011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRRC:
 | 
			
		||||
    encoding: 0b00000000000000000011000001110011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRRWI:
 | 
			
		||||
    encoding: 0b00000000000000000101000001110011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRRSI:
 | 
			
		||||
    encoding: 0b00000000000000000110000001110011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRRCI:
 | 
			
		||||
    encoding: 0b00000000000000000111000001110011
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
Zifencei: 
 | 
			
		||||
  - FENCE_I:
 | 
			
		||||
    encoding: 0b00000000000000000001000000001111
 | 
			
		||||
    mask: 0b00000000000000000111000001111111
 | 
			
		||||
    attributes: [[name:flush]]
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
RV32M: 
 | 
			
		||||
  - MUL:
 | 
			
		||||
    encoding: 0b00000010000000000000000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - MULH:
 | 
			
		||||
    encoding: 0b00000010000000000001000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - MULHSU:
 | 
			
		||||
    encoding: 0b00000010000000000010000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - MULHU:
 | 
			
		||||
    encoding: 0b00000010000000000011000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - DIV:
 | 
			
		||||
    encoding: 0b00000010000000000100000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - DIVU:
 | 
			
		||||
    encoding: 0b00000010000000000101000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - REM:
 | 
			
		||||
    encoding: 0b00000010000000000110000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - REMU:
 | 
			
		||||
    encoding: 0b00000010000000000111000000110011
 | 
			
		||||
    mask: 0b11111110000000000111000001111111
 | 
			
		||||
    size:   32
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
RV32IC: 
 | 
			
		||||
  - CADDI4SPN:
 | 
			
		||||
    encoding: 0b0000000000000000
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CLW:
 | 
			
		||||
    encoding: 0b0100000000000000
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSW:
 | 
			
		||||
    encoding: 0b1100000000000000
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CADDI:
 | 
			
		||||
    encoding: 0b0000000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CNOP:
 | 
			
		||||
    encoding: 0b0000000000000001
 | 
			
		||||
    mask: 0b1110111110000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CJAL:
 | 
			
		||||
    encoding: 0b0010000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CLI:
 | 
			
		||||
    encoding: 0b0100000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CLUI:
 | 
			
		||||
    encoding: 0b0110000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CADDI16SP:
 | 
			
		||||
    encoding: 0b0110000100000001
 | 
			
		||||
    mask: 0b1110111110000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRLI:
 | 
			
		||||
    encoding: 0b1000000000000001
 | 
			
		||||
    mask: 0b1111110000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSRAI:
 | 
			
		||||
    encoding: 0b1000010000000001
 | 
			
		||||
    mask: 0b1111110000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CANDI:
 | 
			
		||||
    encoding: 0b1000100000000001
 | 
			
		||||
    mask: 0b1110110000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSUB:
 | 
			
		||||
    encoding: 0b1000110000000001
 | 
			
		||||
    mask: 0b1111110001100011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CXOR:
 | 
			
		||||
    encoding: 0b1000110000100001
 | 
			
		||||
    mask: 0b1111110001100011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - COR:
 | 
			
		||||
    encoding: 0b1000110001000001
 | 
			
		||||
    mask: 0b1111110001100011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CAND:
 | 
			
		||||
    encoding: 0b1000110001100001
 | 
			
		||||
    mask: 0b1111110001100011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CJ:
 | 
			
		||||
    encoding: 0b1010000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CBEQZ:
 | 
			
		||||
    encoding: 0b1100000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - CBNEZ:
 | 
			
		||||
    encoding: 0b1110000000000001
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    attributes: [[name:no_cont], [name:cond]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   [1,1]
 | 
			
		||||
  - CSLLI:
 | 
			
		||||
    encoding: 0b0000000000000010
 | 
			
		||||
    mask: 0b1111000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CLWSP:
 | 
			
		||||
    encoding: 0b0100000000000010
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CMV:
 | 
			
		||||
    encoding: 0b1000000000000010
 | 
			
		||||
    mask: 0b1111000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CJR:
 | 
			
		||||
    encoding: 0b1000000000000010
 | 
			
		||||
    mask: 0b1111000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CADD:
 | 
			
		||||
    encoding: 0b1001000000000010
 | 
			
		||||
    mask: 0b1111000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CJALR:
 | 
			
		||||
    encoding: 0b1001000000000010
 | 
			
		||||
    mask: 0b1111000001111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   true
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CEBREAK:
 | 
			
		||||
    encoding: 0b1001000000000010
 | 
			
		||||
    mask: 0b1111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - CSWSP:
 | 
			
		||||
    encoding: 0b1100000000000010
 | 
			
		||||
    mask: 0b1110000000000011
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
  - DII:
 | 
			
		||||
    encoding: 0b0000000000000000
 | 
			
		||||
    mask: 0b1111111111111111
 | 
			
		||||
    attributes: [[name:no_cont]]
 | 
			
		||||
    size:   16
 | 
			
		||||
    branch:   false
 | 
			
		||||
    delay:   1
 | 
			
		||||
 | 
			
		||||
@@ -30,8 +30,6 @@
 | 
			
		||||
 *
 | 
			
		||||
 *******************************************************************************/
 | 
			
		||||
<%
 | 
			
		||||
import com.minres.coredsl.util.BigIntegerWithRadix
 | 
			
		||||
 | 
			
		||||
def nativeTypeSize(int size){
 | 
			
		||||
    if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
 | 
			
		||||
}
 | 
			
		||||
@@ -57,10 +55,7 @@ def byteSize(int size){
 | 
			
		||||
    return 128;
 | 
			
		||||
}
 | 
			
		||||
def getCString(def val){
 | 
			
		||||
    if(val instanceof BigIntegerWithRadix)
 | 
			
		||||
        return ((BigIntegerWithRadix)val).toCString()
 | 
			
		||||
    else
 | 
			
		||||
        return val.toString()
 | 
			
		||||
    return val.toString()
 | 
			
		||||
}
 | 
			
		||||
%>
 | 
			
		||||
#ifndef _${coreDef.name.toUpperCase()}_H_
 | 
			
		||||
@@ -116,7 +111,7 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
 | 
			
		||||
 | 
			
		||||
    enum mem_type_e { ${spaces.collect{it.name}.join(', ')} };
 | 
			
		||||
    
 | 
			
		||||
    enum class opcode_e : unsigned short {<%instructions.eachWithIndex{instr, index -> %>
 | 
			
		||||
    enum class opcode_e {<%instructions.eachWithIndex{instr, index -> %>
 | 
			
		||||
        ${instr.instruction.name} = ${index},<%}%>
 | 
			
		||||
        MAX_OPCODE
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ ${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %>
 | 
			
		||||
    encoding: ${it.encoding}
 | 
			
		||||
    mask: ${it.mask}<%if(it.attributes.size) {%>
 | 
			
		||||
    attributes: ${it.attributes}<%}%>
 | 
			
		||||
	size:   ${it.length}
 | 
			
		||||
	branch:   ${it.modifiesPC}
 | 
			
		||||
	delay:   ${it.isConditional?"[1,1]":"1"}<%}}%>
 | 
			
		||||
    size:   ${it.length}
 | 
			
		||||
    branch:   ${it.modifiesPC}
 | 
			
		||||
    delay:   ${it.isConditional?"[1,1]":"1"}<%}}%>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,16 +30,13 @@
 | 
			
		||||
 *
 | 
			
		||||
 *******************************************************************************/
 | 
			
		||||
<%
 | 
			
		||||
import com.minres.coredsl.util.BigIntegerWithRadix
 | 
			
		||||
 | 
			
		||||
def nativeTypeSize(int size){
 | 
			
		||||
    if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
 | 
			
		||||
}
 | 
			
		||||
%>
 | 
			
		||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
 | 
			
		||||
#include <iss/debugger/gdb_session.h>
 | 
			
		||||
#include <iss/debugger/server.h>
 | 
			
		||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/iss.h>
 | 
			
		||||
#include <iss/interp/vm_base.h>
 | 
			
		||||
#include <util/logging.h>
 | 
			
		||||
@@ -317,3 +314,30 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
 | 
			
		||||
}
 | 
			
		||||
} // namespace interp
 | 
			
		||||
} // namespace iss
 | 
			
		||||
 | 
			
		||||
#include <iss/factory.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_mu_p.h>
 | 
			
		||||
namespace iss {
 | 
			
		||||
namespace {
 | 
			
		||||
std::array<bool, 2> dummy = {
 | 
			
		||||
        core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
 | 
			
		||||
		    auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
 | 
			
		||||
		    if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
 | 
			
		||||
            return {cpu_ptr{cpu}, vm_ptr{vm}};
 | 
			
		||||
        }),
 | 
			
		||||
        core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
 | 
			
		||||
		    auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
 | 
			
		||||
		    if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
 | 
			
		||||
            return {cpu_ptr{cpu}, vm_ptr{vm}};
 | 
			
		||||
        })
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
extern "C" {
 | 
			
		||||
	bool* get_${coreDef.name.toLowerCase()}_interp_creators() {
 | 
			
		||||
		return iss::dummy.data();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -31,7 +31,6 @@
 | 
			
		||||
 *******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/debugger/gdb_session.h>
 | 
			
		||||
#include <iss/debugger/server.h>
 | 
			
		||||
#include <iss/iss.h>
 | 
			
		||||
@@ -207,7 +206,7 @@ private:
 | 
			
		||||
            ${it}<%}%>
 | 
			
		||||
        }
 | 
			
		||||
        auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
 | 
			
		||||
        pc=pc+4;
 | 
			
		||||
        pc=pc+ ${instr.length/8};
 | 
			
		||||
        gen_set_pc(tu, pc, traits::NEXT_PC);
 | 
			
		||||
        tu.open_scope();<%instr.behavior.eachLine{%>
 | 
			
		||||
        ${it}<%}%>
 | 
			
		||||
@@ -310,5 +309,32 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
 | 
			
		||||
    if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
 | 
			
		||||
    return std::unique_ptr<vm_if>(ret);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
} // namesapce tcc
 | 
			
		||||
} // namespace iss
 | 
			
		||||
 | 
			
		||||
#include <iss/factory.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_mu_p.h>
 | 
			
		||||
namespace iss {
 | 
			
		||||
namespace {
 | 
			
		||||
std::array<bool, 2> dummy = {
 | 
			
		||||
        core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
 | 
			
		||||
		    auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
 | 
			
		||||
		    if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
 | 
			
		||||
            return {cpu_ptr{cpu}, vm_ptr{vm}};
 | 
			
		||||
        }),
 | 
			
		||||
        core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
 | 
			
		||||
		    auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
 | 
			
		||||
		    if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
 | 
			
		||||
            return {cpu_ptr{cpu}, vm_ptr{vm}};
 | 
			
		||||
        })
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
extern "C" {
 | 
			
		||||
	bool* get_${coreDef.name.toLowerCase()}_tcc_creators() {
 | 
			
		||||
		return iss::dummy.data();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -419,7 +419,7 @@ protected:
 | 
			
		||||
    std::vector<std::function<mem_write_f>> memfn_write;
 | 
			
		||||
    void insert_mem_range(uint64_t, uint64_t, std::function<mem_read_f>, std::function<mem_write_f>);
 | 
			
		||||
    feature_config cfg;
 | 
			
		||||
    unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16};
 | 
			
		||||
    uint64_t mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16};
 | 
			
		||||
    inline bool debug_mode_active() {return this->reg.PRIV&0x4;}
 | 
			
		||||
    std::pair<std::function<mem_read_f>, std::function<mem_write_f>>
 | 
			
		||||
    replace_mem_access(std::function<mem_read_f> rd, std::function<mem_write_f> wr){
 | 
			
		||||
@@ -619,9 +619,9 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
 | 
			
		||||
            }
 | 
			
		||||
            return std::make_pair(entry, true);
 | 
			
		||||
        }
 | 
			
		||||
        throw std::runtime_error("memory load file is not a valid elf file");
 | 
			
		||||
        throw std::runtime_error(fmt::format("memory load file {} is not a valid elf file",name));
 | 
			
		||||
    }
 | 
			
		||||
    throw std::runtime_error("memory load file not found");
 | 
			
		||||
    throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename BASE, features_e FEAT>
 | 
			
		||||
@@ -959,7 +959,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_cause(unsigned addr, reg_t &val) {
 | 
			
		||||
    auto res = csr[addr];
 | 
			
		||||
    if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) {
 | 
			
		||||
        val = csr[addr] & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1) | (0xfUL<<16));
 | 
			
		||||
        val |= clic_mprev_lvl<<16;
 | 
			
		||||
@@ -971,7 +970,6 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_cause(unsigned addr, reg_t val) {
 | 
			
		||||
    csr[addr] = val & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1));
 | 
			
		||||
    if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) {
 | 
			
		||||
        auto mask = ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1) | (0xfUL<<16));
 | 
			
		||||
        csr[addr] = (val & mask) | (csr[addr] & ~mask);
 | 
			
		||||
 
 | 
			
		||||
@@ -316,6 +316,9 @@ public:
 | 
			
		||||
        csr[addr & csr.page_addr_mask] = val;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_irq_num(unsigned i) {
 | 
			
		||||
        mcause_max_irq=1<<util::ilog2(i);
 | 
			
		||||
    }
 | 
			
		||||
protected:
 | 
			
		||||
    struct riscv_instrumentation_if : public iss::instrumentation_if {
 | 
			
		||||
 | 
			
		||||
@@ -328,21 +331,21 @@ protected:
 | 
			
		||||
         */
 | 
			
		||||
        const std::string core_type_name() const override { return traits<BASE>::core_type; }
 | 
			
		||||
 | 
			
		||||
        virtual uint64_t get_pc() { return arch.get_pc(); };
 | 
			
		||||
        uint64_t get_pc() override { return arch.reg.PC; };
 | 
			
		||||
 | 
			
		||||
        virtual uint64_t get_next_pc() { return arch.get_next_pc(); };
 | 
			
		||||
        uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
 | 
			
		||||
 | 
			
		||||
        uint64_t get_instr_word() override { return arch.instruction; }
 | 
			
		||||
        uint64_t get_instr_word() override { return arch.reg.instruction; }
 | 
			
		||||
 | 
			
		||||
        uint64_t get_instr_count() { return arch.icount; }
 | 
			
		||||
        uint64_t get_instr_count() override { return arch.reg.icount; }
 | 
			
		||||
 | 
			
		||||
        uint64_t get_pendig_traps() override { return arch.trap_state; }
 | 
			
		||||
        uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
 | 
			
		||||
 | 
			
		||||
        uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
 | 
			
		||||
        uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
 | 
			
		||||
 | 
			
		||||
        void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
 | 
			
		||||
 | 
			
		||||
        bool is_branch_taken() override { return arch.last_branch; };
 | 
			
		||||
        bool is_branch_taken() override { return arch.reg.last_branch; };
 | 
			
		||||
 | 
			
		||||
        riscv_hart_msu_vp<BASE> &arch;
 | 
			
		||||
    };
 | 
			
		||||
@@ -381,16 +384,17 @@ protected:
 | 
			
		||||
    std::unordered_map<unsigned, rd_csr_f> csr_rd_cb;
 | 
			
		||||
    std::unordered_map<unsigned, wr_csr_f> csr_wr_cb;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    iss::status read_reg(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_reg(unsigned addr, reg_t val);
 | 
			
		||||
    std::vector<uint8_t> tcm;
 | 
			
		||||
 | 
			
		||||
    iss::status read_csr_reg(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_csr_reg(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status read_null(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_null(unsigned addr, reg_t val){return iss::status::Ok;}
 | 
			
		||||
    iss::status read_cycle(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_cycle(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status read_instret(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_instret(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status read_mtvec(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status read_tvec(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status read_time(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status read_status(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_status(unsigned addr, reg_t val);
 | 
			
		||||
@@ -398,6 +402,8 @@ private:
 | 
			
		||||
    iss::status read_ie(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_ie(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status read_ip(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_ideleg(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status write_edeleg(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status read_hartid(unsigned addr, reg_t &val);
 | 
			
		||||
    iss::status write_epc(unsigned addr, reg_t val);
 | 
			
		||||
    iss::status read_satp(unsigned addr, reg_t &val);
 | 
			
		||||
@@ -417,7 +423,6 @@ private:
 | 
			
		||||
 | 
			
		||||
    reg_t mhartid_reg{0x0};
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void check_interrupt();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -434,22 +439,22 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
 | 
			
		||||
    uart_buf.str("");
 | 
			
		||||
    for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_null;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_reg;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_csr_reg;
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_null;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_reg;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_csr_reg;
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr){
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_null;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_reg;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_csr_reg;
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_null;
 | 
			
		||||
    }
 | 
			
		||||
    for (unsigned addr = cycleh; addr <= hpmcounter31h; ++addr){
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_null;
 | 
			
		||||
        //csr_wr_cb[addr] = &this_class::write_reg;
 | 
			
		||||
        //csr_wr_cb[addr] = &this_class::write_csr_reg;
 | 
			
		||||
    }
 | 
			
		||||
    // common regs
 | 
			
		||||
    const std::array<unsigned, 22> addrs{{
 | 
			
		||||
@@ -459,25 +464,25 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
 | 
			
		||||
        uepc, utvec, uscratch, ucause, utval, uscratch
 | 
			
		||||
    }};
 | 
			
		||||
    for(auto addr: addrs) {
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_reg;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_reg;
 | 
			
		||||
        csr_rd_cb[addr] = &this_class::read_csr_reg;
 | 
			
		||||
        csr_wr_cb[addr] = &this_class::write_csr_reg;
 | 
			
		||||
    }
 | 
			
		||||
    // special handling & overrides
 | 
			
		||||
    csr_rd_cb[time] = &this_class::read_time;
 | 
			
		||||
    csr_rd_cb[timeh] = &this_class::read_time;
 | 
			
		||||
    if(traits<BASE>::XLEN==32)  csr_rd_cb[timeh] = &this_class::read_time;
 | 
			
		||||
    csr_rd_cb[cycle] = &this_class::read_cycle;
 | 
			
		||||
    csr_rd_cb[cycleh] = &this_class::read_cycle;
 | 
			
		||||
    if(traits<BASE>::XLEN==32) csr_rd_cb[cycleh] = &this_class::read_cycle;
 | 
			
		||||
    csr_rd_cb[instret] = &this_class::read_instret;
 | 
			
		||||
    csr_rd_cb[instreth] = &this_class::read_instret;
 | 
			
		||||
    if(traits<BASE>::XLEN==32) csr_rd_cb[instreth] = &this_class::read_instret;
 | 
			
		||||
 | 
			
		||||
    csr_rd_cb[mcycle] = &this_class::read_cycle;
 | 
			
		||||
    csr_wr_cb[mcycle] = &this_class::write_cycle;
 | 
			
		||||
    csr_rd_cb[mcycleh] = &this_class::read_cycle;
 | 
			
		||||
    csr_wr_cb[mcycleh] = &this_class::write_cycle;
 | 
			
		||||
    if(traits<BASE>::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle;
 | 
			
		||||
    if(traits<BASE>::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle;
 | 
			
		||||
    csr_rd_cb[minstret] = &this_class::read_instret;
 | 
			
		||||
    csr_wr_cb[minstret] = &this_class::write_instret;
 | 
			
		||||
    csr_rd_cb[minstreth] = &this_class::read_instret;
 | 
			
		||||
    csr_wr_cb[minstreth] = &this_class::write_instret;
 | 
			
		||||
    if(traits<BASE>::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret;
 | 
			
		||||
    if(traits<BASE>::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret;
 | 
			
		||||
    csr_rd_cb[mstatus] = &this_class::read_status;
 | 
			
		||||
    csr_wr_cb[mstatus] = &this_class::write_status;
 | 
			
		||||
    csr_wr_cb[mcause] = &this_class::write_cause;
 | 
			
		||||
@@ -527,10 +532,10 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
 | 
			
		||||
    if (fp) {
 | 
			
		||||
        std::array<char, 5> buf;
 | 
			
		||||
        auto n = fread(buf.data(), 1, 4, fp);
 | 
			
		||||
        fclose(fp);
 | 
			
		||||
        if (n != 4) throw std::runtime_error("input file has insufficient size");
 | 
			
		||||
        buf[4] = 0;
 | 
			
		||||
        if (strcmp(buf.data() + 1, "ELF") == 0) {
 | 
			
		||||
            fclose(fp);
 | 
			
		||||
            // Create elfio reader
 | 
			
		||||
            ELFIO::elfio reader;
 | 
			
		||||
            // Load ELF data
 | 
			
		||||
@@ -549,7 +554,7 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
 | 
			
		||||
                            traits<BASE>::MEM, pseg->get_physical_address(),
 | 
			
		||||
                            fsize, reinterpret_cast<const uint8_t *const>(seg_data));
 | 
			
		||||
                    if (res != iss::Ok)
 | 
			
		||||
                        LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex
 | 
			
		||||
                        LOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex
 | 
			
		||||
                                   << pseg->get_physical_address();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -583,9 +588,9 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
 | 
			
		||||
            }
 | 
			
		||||
            return std::make_pair(entry, true);
 | 
			
		||||
        }
 | 
			
		||||
        throw std::runtime_error("memory load file is not a valid elf file");
 | 
			
		||||
        throw std::runtime_error(fmt::format("memory load file {} is not a valid elf file",name));
 | 
			
		||||
    }
 | 
			
		||||
    throw std::runtime_error("memory load file not found");
 | 
			
		||||
    throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename BASE>
 | 
			
		||||
@@ -673,7 +678,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
 | 
			
		||||
        }
 | 
			
		||||
        return iss::Ok;
 | 
			
		||||
    } catch (trap_access &ta) {
 | 
			
		||||
        this->reg.trap_state = (1 << 31) | ta.id;
 | 
			
		||||
        this->reg.trap_state = (1UL << 31) | ta.id;
 | 
			
		||||
        fault_data=ta.addr;
 | 
			
		||||
        return iss::Err;
 | 
			
		||||
    }
 | 
			
		||||
@@ -730,12 +735,12 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
 | 
			
		||||
                        write_mem(phys_addr_t{access, space, addr}, length, data):
 | 
			
		||||
                        write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data);
 | 
			
		||||
                if (unlikely(res != iss::Ok)) {
 | 
			
		||||
                    this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
 | 
			
		||||
                    this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault)
 | 
			
		||||
                    fault_data=addr;
 | 
			
		||||
                }
 | 
			
		||||
                return res;
 | 
			
		||||
            } catch (trap_access &ta) {
 | 
			
		||||
                this->reg.trap_state = (1 << 31) | ta.id;
 | 
			
		||||
                this->reg.trap_state = (1UL << 31) | ta.id;
 | 
			
		||||
                fault_data=ta.addr;
 | 
			
		||||
                return iss::Err;
 | 
			
		||||
            }
 | 
			
		||||
@@ -800,7 +805,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
 | 
			
		||||
        }
 | 
			
		||||
        return iss::Ok;
 | 
			
		||||
    } catch (trap_access &ta) {
 | 
			
		||||
        this->reg.trap_state = (1 << 31) | ta.id;
 | 
			
		||||
        this->reg.trap_state = (1UL << 31) | ta.id;
 | 
			
		||||
        fault_data=ta.addr;
 | 
			
		||||
        return iss::Err;
 | 
			
		||||
    }
 | 
			
		||||
@@ -858,8 +863,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne
 | 
			
		||||
 | 
			
		||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_cycle(unsigned addr, reg_t val) {
 | 
			
		||||
    if (sizeof(typename traits<BASE>::reg_t) != 4) {
 | 
			
		||||
        if (addr == mcycleh)
 | 
			
		||||
            return iss::Err;
 | 
			
		||||
        mcycle_csr = static_cast<uint64_t>(val);
 | 
			
		||||
    } else {
 | 
			
		||||
        if (addr == mcycle) {
 | 
			
		||||
@@ -876,7 +879,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_instret(unsig
 | 
			
		||||
    if ((addr&0xff) == (minstret&0xff)) {
 | 
			
		||||
        val = static_cast<reg_t>(this->reg.instret);
 | 
			
		||||
    } else if ((addr&0xff) == (minstreth&0xff)) {
 | 
			
		||||
        if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
 | 
			
		||||
        val = static_cast<reg_t>(this->reg.instret >> 32);
 | 
			
		||||
    }
 | 
			
		||||
    return iss::Ok;
 | 
			
		||||
@@ -884,8 +886,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_instret(unsig
 | 
			
		||||
 | 
			
		||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_instret(unsigned addr, reg_t val) {
 | 
			
		||||
    if (sizeof(typename traits<BASE>::reg_t) != 4) {
 | 
			
		||||
        if ((addr&0xff) == (minstreth&0xff))
 | 
			
		||||
            return iss::Err;
 | 
			
		||||
        this->reg.instret = static_cast<uint64_t>(val);
 | 
			
		||||
    } else {
 | 
			
		||||
        if ((addr&0xff) == (minstret&0xff)) {
 | 
			
		||||
@@ -1234,6 +1234,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
 | 
			
		||||
    auto cur_priv = this->reg.PRIV;
 | 
			
		||||
    // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
 | 
			
		||||
    // calculate and write mcause val
 | 
			
		||||
    if(flags==std::numeric_limits<uint64_t>::max()) flags=this->reg.trap_state;
 | 
			
		||||
    auto trap_id = bit_sub<0, 16>(flags);
 | 
			
		||||
    auto cause = bit_sub<16, 15>(flags);
 | 
			
		||||
    if (trap_id == 0 && cause == 11) cause = 0x8 + cur_priv; // adjust environment call cause
 | 
			
		||||
 
 | 
			
		||||
@@ -284,6 +284,7 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    riscv_hart_mu_p(feature_config cfg = feature_config{});
 | 
			
		||||
    
 | 
			
		||||
    virtual ~riscv_hart_mu_p() = default;
 | 
			
		||||
 | 
			
		||||
    void reset(uint64_t address) override;
 | 
			
		||||
@@ -332,17 +333,17 @@ protected:
 | 
			
		||||
 | 
			
		||||
        uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
 | 
			
		||||
 | 
			
		||||
        uint64_t get_instr_word() override { return arch.instruction; }
 | 
			
		||||
        uint64_t get_instr_word() override { return arch.reg.instruction; }
 | 
			
		||||
 | 
			
		||||
        uint64_t get_instr_count() override { return arch.icount; }
 | 
			
		||||
        uint64_t get_instr_count() override { return arch.reg.icount; }
 | 
			
		||||
 | 
			
		||||
        uint64_t get_pendig_traps() override { return arch.trap_state; }
 | 
			
		||||
        uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
 | 
			
		||||
 | 
			
		||||
        uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
 | 
			
		||||
        uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
 | 
			
		||||
 | 
			
		||||
        void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
 | 
			
		||||
 | 
			
		||||
        bool is_branch_taken() override { return arch.last_branch; };
 | 
			
		||||
        bool is_branch_taken() override { return arch.reg.last_branch; };
 | 
			
		||||
 | 
			
		||||
        riscv_hart_mu_p<BASE, FEAT> &arch;
 | 
			
		||||
    };
 | 
			
		||||
@@ -446,7 +447,7 @@ protected:
 | 
			
		||||
    std::vector<std::function<mem_write_f>> memfn_write;
 | 
			
		||||
    void insert_mem_range(uint64_t, uint64_t, std::function<mem_read_f>, std::function<mem_write_f>);
 | 
			
		||||
    feature_config cfg;
 | 
			
		||||
    unsigned mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16};
 | 
			
		||||
    uint64_t mcause_max_irq{(FEAT&features_e::FEAT_CLIC)?4096:16};
 | 
			
		||||
    inline bool debug_mode_active() {return this->reg.PRIV&0x4;}
 | 
			
		||||
 | 
			
		||||
    std::pair<std::function<mem_read_f>, std::function<mem_write_f>>
 | 
			
		||||
@@ -689,9 +690,9 @@ template <typename BASE, features_e FEAT> std::pair<uint64_t, bool> riscv_hart_m
 | 
			
		||||
            }
 | 
			
		||||
            return std::make_pair(entry, true);
 | 
			
		||||
        }
 | 
			
		||||
        throw std::runtime_error("memory load file is not a valid elf file");
 | 
			
		||||
        throw std::runtime_error(fmt::format("memory load file {} is not a valid elf file",name));
 | 
			
		||||
    }
 | 
			
		||||
    throw std::runtime_error("memory load file not found");
 | 
			
		||||
    throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename BASE, features_e FEAT>
 | 
			
		||||
@@ -949,7 +950,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
 | 
			
		||||
                    res = hart_mem_wr_delegate( phys_addr, length, data);
 | 
			
		||||
                }
 | 
			
		||||
                if (unlikely(res != iss::Ok)) {
 | 
			
		||||
                    this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
 | 
			
		||||
                    this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault)
 | 
			
		||||
                    fault_data=addr;
 | 
			
		||||
                }
 | 
			
		||||
                return res;
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ template <> struct traits<tgc_c> {
 | 
			
		||||
    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", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}};
 | 
			
		||||
 | 
			
		||||
    enum constants {MISA_VAL=0b01000000000000000001000100000100, MARCHID_VAL=0x80000003, XLEN=32, INSTR_ALIGNMENT=2, RFS=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, CSR_SIZE=4096, MUL_LEN=64};
 | 
			
		||||
    enum constants {MISA_VAL=1073746180, MARCHID_VAL=2147483651, XLEN=32, INSTR_ALIGNMENT=2, RFS=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, CSR_SIZE=4096, MUL_LEN=64};
 | 
			
		||||
 | 
			
		||||
    constexpr static unsigned FP_REGS_SIZE = 0;
 | 
			
		||||
 | 
			
		||||
@@ -83,7 +83,7 @@ template <> struct traits<tgc_c> {
 | 
			
		||||
 | 
			
		||||
    enum mem_type_e { MEM, FENCE, RES, CSR };
 | 
			
		||||
    
 | 
			
		||||
    enum class opcode_e : unsigned short {
 | 
			
		||||
    enum class opcode_e {
 | 
			
		||||
        LUI = 0,
 | 
			
		||||
        AUIPC = 1,
 | 
			
		||||
        JAL = 2,
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,12 @@
 | 
			
		||||
#define _ISS_FACTORY_H_
 | 
			
		||||
 | 
			
		||||
#include <iss/iss.h>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
namespace iss {
 | 
			
		||||
 | 
			
		||||
@@ -57,6 +63,48 @@ std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_
 | 
			
		||||
    return {nullptr, nullptr};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class core_factory {
 | 
			
		||||
    using cpu_ptr = std::unique_ptr<iss::arch_if>;
 | 
			
		||||
    using vm_ptr= std::unique_ptr<iss::vm_if>;
 | 
			
		||||
    using base_t = std::tuple<cpu_ptr, vm_ptr>;
 | 
			
		||||
    using create_fn = std::function<base_t(unsigned, void*) >;
 | 
			
		||||
    using registry_t = std::unordered_map<std::string, create_fn> ;
 | 
			
		||||
 | 
			
		||||
    registry_t registry;
 | 
			
		||||
 | 
			
		||||
    core_factory() = default;
 | 
			
		||||
    core_factory(const core_factory &) = delete;
 | 
			
		||||
    core_factory & operator=(const core_factory &) = delete;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static core_factory & instance() { static core_factory bf; return bf; }
 | 
			
		||||
 | 
			
		||||
    bool register_creator(const std::string &, create_fn const&);
 | 
			
		||||
 | 
			
		||||
    base_t create(const std::string &, unsigned gdb_port=0, void* init_data=nullptr) const;
 | 
			
		||||
 | 
			
		||||
    std::vector<std::string> get_names() {
 | 
			
		||||
        std::vector<std::string> keys{registry.size()};
 | 
			
		||||
        std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair<std::string, create_fn> const& p){
 | 
			
		||||
            return p.first;
 | 
			
		||||
        });
 | 
			
		||||
        return keys;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline bool core_factory::register_creator(const std::string & className, create_fn const& fn) {
 | 
			
		||||
    registry[className] = fn;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline core_factory::base_t core_factory::create(const std::string &className, unsigned gdb_port, void* data) const {
 | 
			
		||||
    registry_t::const_iterator regEntry = registry.find(className);
 | 
			
		||||
    if (regEntry != registry.end())
 | 
			
		||||
        return regEntry->second(gdb_port, data);
 | 
			
		||||
    return {nullptr, nullptr};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* _ISS_FACTORY_H_ */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										85
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -31,7 +31,9 @@
 | 
			
		||||
 *******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include "iss/factory.h"
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <iss/factory.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/lexical_cast.hpp>
 | 
			
		||||
#include <boost/program_options.hpp>
 | 
			
		||||
@@ -61,7 +63,7 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
    // clang-format off
 | 
			
		||||
    desc.add_options()
 | 
			
		||||
        ("help,h", "Print help message")
 | 
			
		||||
        ("verbose,v", po::value<int>()->implicit_value(0), "Sets logging verbosity")
 | 
			
		||||
        ("verbose,v", po::value<int>()->default_value(4), "Sets logging verbosity")
 | 
			
		||||
        ("logfile,l", po::value<std::string>(), "Sets default log file.")
 | 
			
		||||
        ("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly")
 | 
			
		||||
        ("gdb-port,g", po::value<unsigned>()->default_value(0), "enable gdb server and specify port to use")
 | 
			
		||||
@@ -93,11 +95,9 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
 | 
			
		||||
    LOGGER(DEFAULT)::print_time() = false;
 | 
			
		||||
    LOGGER(connection)::print_time() = false;
 | 
			
		||||
    if (clim.count("verbose")) {
 | 
			
		||||
        auto l = logging::as_log_level(clim["verbose"].as<int>());
 | 
			
		||||
        LOGGER(DEFAULT)::reporting_level() = l;
 | 
			
		||||
        LOGGER(connection)::reporting_level() = l;
 | 
			
		||||
    }
 | 
			
		||||
    auto l = logging::as_log_level(clim["verbose"].as<int>());
 | 
			
		||||
    LOGGER(DEFAULT)::reporting_level() = l;
 | 
			
		||||
    LOGGER(connection)::reporting_level() = l;
 | 
			
		||||
    if (clim.count("logfile")) {
 | 
			
		||||
        // configure the connection logger
 | 
			
		||||
        auto f = fopen(clim["logfile"].as<std::string>().c_str(), "w");
 | 
			
		||||
@@ -113,53 +113,24 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
        iss::init_jit_debug(argc, argv);
 | 
			
		||||
#endif
 | 
			
		||||
        bool dump = clim.count("dump-ir");
 | 
			
		||||
        auto & f = iss::core_factory::instance();
 | 
			
		||||
        // instantiate the simulator
 | 
			
		||||
        iss::vm_ptr vm{nullptr};
 | 
			
		||||
        iss::cpu_ptr cpu{nullptr};
 | 
			
		||||
        std::string isa_opt(clim["isa"].as<std::string>());
 | 
			
		||||
        if (isa_opt == "tgc_c") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_c_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#ifdef CORE_TGC_B
 | 
			
		||||
        if (isa_opt == "tgc_b") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_b_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CORE_TGC_C_XRB_NN
 | 
			
		||||
        if (isa_opt == "tgc_c_xrb_nn") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_c_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CORE_TGC_D
 | 
			
		||||
        if (isa_opt == "tgc_d") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_d_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CORE_TGC_D_XRB_MAC
 | 
			
		||||
        if (isa_opt == "tgc_d_xrb_mac") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_d_xrb_mac_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CORE_TGC_D_XRB_NN
 | 
			
		||||
        if (isa_opt == "tgc_d_xrb_nn") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_d_xrb_nn_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef CORE_TGC_E
 | 
			
		||||
        if (isa_opt == "tgc_e") {
 | 
			
		||||
            std::tie(cpu, vm) =
 | 
			
		||||
                iss::create_cpu<tgc_e_plat_type>(clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else
 | 
			
		||||
#endif
 | 
			
		||||
        {
 | 
			
		||||
            LOG(ERR) << "Illegal argument value for '--isa': " << isa_opt << std::endl;
 | 
			
		||||
            return 127;
 | 
			
		||||
        if(isa_opt.size()==0 || isa_opt == "?") {
 | 
			
		||||
            std::cout<<"Available cores: "<<util::join(f.get_names(), ", ")<<std::endl;
 | 
			
		||||
            return 0;
 | 
			
		||||
        } else if (isa_opt.find('|') != std::string::npos) {
 | 
			
		||||
            std::tie(cpu, vm) = f.create(isa_opt+"|"+clim["backend"].as<std::string>(), clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        } else {
 | 
			
		||||
            auto base_isa = isa_opt.substr(0, 5);
 | 
			
		||||
            if(base_isa=="tgc_d" || base_isa=="tgc_e") {
 | 
			
		||||
                isa_opt += "|mu_p_clic_pmp|"+clim["backend"].as<std::string>();
 | 
			
		||||
            } else {
 | 
			
		||||
                isa_opt += "|m_p|"+clim["backend"].as<std::string>();
 | 
			
		||||
            }
 | 
			
		||||
            std::tie(cpu, vm) = f.create(isa_opt, clim["gdb-port"].as<unsigned>());
 | 
			
		||||
        }
 | 
			
		||||
        if(!cpu ){
 | 
			
		||||
            LOG(ERR) << "Could not create cpu for isa " << isa_opt << " and backend " <<clim["backend"].as<std::string>()<< std::endl;
 | 
			
		||||
@@ -172,27 +143,29 @@ int main(int argc, char *argv[]) {
 | 
			
		||||
        if (clim.count("plugin")) {
 | 
			
		||||
            for (std::string const& opt_val : clim["plugin"].as<std::vector<std::string>>()) {
 | 
			
		||||
                std::string plugin_name=opt_val;
 | 
			
		||||
                std::string filename{"cycles.txt"};
 | 
			
		||||
                std::string arg{""};
 | 
			
		||||
                std::size_t found = opt_val.find('=');
 | 
			
		||||
                if (found != std::string::npos) {
 | 
			
		||||
                    plugin_name = opt_val.substr(0, found);
 | 
			
		||||
                    filename = opt_val.substr(found + 1, opt_val.size());
 | 
			
		||||
                    arg = opt_val.substr(found + 1, opt_val.size());
 | 
			
		||||
                }
 | 
			
		||||
                if (plugin_name == "ic") {
 | 
			
		||||
                    auto *ic_plugin = new iss::plugin::instruction_count(filename);
 | 
			
		||||
                    auto *ic_plugin = new iss::plugin::instruction_count(arg);
 | 
			
		||||
                    vm->register_plugin(*ic_plugin);
 | 
			
		||||
                    plugin_list.push_back(ic_plugin);
 | 
			
		||||
                } else if (plugin_name == "ce") {
 | 
			
		||||
                    auto *ce_plugin = new iss::plugin::cycle_estimate(filename);
 | 
			
		||||
                    auto *ce_plugin = new iss::plugin::cycle_estimate(arg);
 | 
			
		||||
                    vm->register_plugin(*ce_plugin);
 | 
			
		||||
                    plugin_list.push_back(ce_plugin);
 | 
			
		||||
                } else if (plugin_name == "pctrace") {
 | 
			
		||||
                    auto *plugin = new iss::plugin::pctrace(filename);
 | 
			
		||||
                    auto *plugin = new iss::plugin::pctrace(arg);
 | 
			
		||||
                    vm->register_plugin(*plugin);
 | 
			
		||||
                    plugin_list.push_back(plugin);
 | 
			
		||||
               } else {
 | 
			
		||||
#ifndef WIN32
 | 
			
		||||
                    std::array<char const*, 1> a{{filename.c_str()}};
 | 
			
		||||
                    std::vector<char const*> a{};
 | 
			
		||||
                    if(arg.length())
 | 
			
		||||
                        a.push_back({arg.c_str()});
 | 
			
		||||
                    iss::plugin::loader l(plugin_name, {{"initPlugin"}});
 | 
			
		||||
                    auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data());
 | 
			
		||||
                    if(plugin){
 | 
			
		||||
 
 | 
			
		||||
@@ -118,7 +118,7 @@ public:
 | 
			
		||||
            std::stringstream s;
 | 
			
		||||
            s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0')
 | 
			
		||||
              << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:"
 | 
			
		||||
              << this->icount + this->cycle_offset << "]";
 | 
			
		||||
              << this->reg.icount + this->cycle_offset << "]";
 | 
			
		||||
            SCCDEBUG(owner->name())<<"disass: "
 | 
			
		||||
                << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)
 | 
			
		||||
                << std::setfill(' ') << std::left << instr << s.str();
 | 
			
		||||
@@ -178,7 +178,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    void wait_until(uint64_t flags) override {
 | 
			
		||||
        SCCDEBUG(owner->name()) << "Sleeping until interrupt";
 | 
			
		||||
        while(this->pending_trap == 0 && (this->csr[arch::mip] & this->csr[arch::mie]) == 0) {
 | 
			
		||||
        while(this->reg.pending_trap == 0 && (this->csr[arch::mip] & this->csr[arch::mie]) == 0) {
 | 
			
		||||
            sc_core::wait(wfi_evt);
 | 
			
		||||
        }
 | 
			
		||||
        PLAT::wait_until(flags);
 | 
			
		||||
@@ -207,7 +207,7 @@ public:
 | 
			
		||||
            this->csr[arch::mip] &= ~mask;
 | 
			
		||||
        this->check_interrupt();
 | 
			
		||||
        if(value)
 | 
			
		||||
            SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->pending_trap;
 | 
			
		||||
            SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->reg.pending_trap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								src/sysc/register_tgc_c.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/sysc/register_tgc_c.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
 * register_tgc_c.cpp
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Jul 5, 2023
 | 
			
		||||
 *      Author: eyck
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <iss/factory.h>
 | 
			
		||||
#include <iss/arch/tgc_c.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_mu_p.h>
 | 
			
		||||
#include "sc_core_adapter.h"
 | 
			
		||||
#include "core_complex.h"
 | 
			
		||||
 | 
			
		||||
namespace iss {
 | 
			
		||||
namespace {
 | 
			
		||||
volatile std::array<bool, 2> dummy = {
 | 
			
		||||
        core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
 | 
			
		||||
            arch::tgc_c* lcpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::tgc_c>>(cc);
 | 
			
		||||
            return {cpu_ptr{lcpu}, vm_ptr{interp::create(lcpu, gdb_port)}};
 | 
			
		||||
        }),
 | 
			
		||||
        core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned gdb_port, void* data) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
 | 
			
		||||
            arch::tgc_c* lcpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::tgc_c>>(cc);
 | 
			
		||||
            return {cpu_ptr{lcpu}, vm_ptr{interp::create(lcpu, gdb_port)}};
 | 
			
		||||
        })
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										148
									
								
								src/sysc/sc_core_adapter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								src/sysc/sc_core_adapter.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
/*
 | 
			
		||||
 * sc_core_adapter.h
 | 
			
		||||
 *
 | 
			
		||||
 *  Created on: Jul 5, 2023
 | 
			
		||||
 *      Author: eyck
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _SYSC_SC_CORE_ADAPTER_H_
 | 
			
		||||
#define _SYSC_SC_CORE_ADAPTER_H_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <scc/report.h>
 | 
			
		||||
#include <util/ities.h>
 | 
			
		||||
#include "core_complex.h"
 | 
			
		||||
#include <iss/iss.h>
 | 
			
		||||
#include <iss/vm_types.h>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename PLAT>
 | 
			
		||||
class sc_core_adapter : public PLAT {
 | 
			
		||||
public:
 | 
			
		||||
    using reg_t       = typename iss::arch::traits<typename PLAT::core>::reg_t;
 | 
			
		||||
    using phys_addr_t = typename iss::arch::traits<typename PLAT::core>::phys_addr_t;
 | 
			
		||||
    using heart_state_t = typename PLAT::hart_state_type;
 | 
			
		||||
    sc_core_adapter(sysc::tgfs::core_complex *owner)
 | 
			
		||||
    : owner(owner) { }
 | 
			
		||||
 | 
			
		||||
    uint32_t get_mode() { return this->reg.PRIV; }
 | 
			
		||||
 | 
			
		||||
    inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; }
 | 
			
		||||
 | 
			
		||||
    inline bool get_interrupt_execution() { return this->interrupt_sim; }
 | 
			
		||||
 | 
			
		||||
    heart_state_t &get_state() { return this->state; }
 | 
			
		||||
 | 
			
		||||
    void notify_phase(iss::arch_if::exec_phase p) override {
 | 
			
		||||
        if (p == iss::arch_if::ISTART)
 | 
			
		||||
            owner->sync(this->instr_if.get_total_cycles());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iss::sync_type needed_sync() const override { return iss::PRE_SYNC; }
 | 
			
		||||
 | 
			
		||||
    void disass_output(uint64_t pc, const std::string instr) override {
 | 
			
		||||
        static constexpr std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
 | 
			
		||||
        if (!owner->disass_output(pc, instr)) {
 | 
			
		||||
            std::stringstream s;
 | 
			
		||||
            s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0')
 | 
			
		||||
              << std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:"
 | 
			
		||||
              << this->reg.icount + this->cycle_offset << "]";
 | 
			
		||||
            SCCDEBUG(owner->name())<<"disass: "
 | 
			
		||||
                << "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)
 | 
			
		||||
                << std::setfill(' ') << std::left << instr << s.str();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) override {
 | 
			
		||||
        if (addr.access && iss::access_type::DEBUG)
 | 
			
		||||
            return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
 | 
			
		||||
        else {
 | 
			
		||||
            return owner->read_mem(addr.val, length, data, is_fetch(addr.access)) ? iss::Ok : iss::Err;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) override {
 | 
			
		||||
        if (addr.access && iss::access_type::DEBUG)
 | 
			
		||||
            return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err;
 | 
			
		||||
        else {
 | 
			
		||||
            auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err;
 | 
			
		||||
            // clear MTIP on mtimecmp write
 | 
			
		||||
            if (addr.val == 0x2004000) {
 | 
			
		||||
                reg_t val;
 | 
			
		||||
                this->read_csr(iss::arch::mip, val);
 | 
			
		||||
                if (val & (1ULL << 7)) this->write_csr(iss::arch::mip, val & ~(1ULL << 7));
 | 
			
		||||
            }
 | 
			
		||||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    iss::status read_csr(unsigned addr, reg_t &val) override {
 | 
			
		||||
#ifndef CWR_SYSTEMC
 | 
			
		||||
        if((addr==iss::arch::time || addr==iss::arch::timeh) && owner->mtime_o.get_interface(0)){
 | 
			
		||||
            uint64_t time_val;
 | 
			
		||||
            bool ret = owner->mtime_o->nb_peek(time_val);
 | 
			
		||||
            if (addr == iss::arch::time) {
 | 
			
		||||
                val = static_cast<reg_t>(time_val);
 | 
			
		||||
            } else if (addr == iss::arch::timeh) {
 | 
			
		||||
                if (sizeof(reg_t) != 4) return iss::Err;
 | 
			
		||||
                val = static_cast<reg_t>(time_val >> 32);
 | 
			
		||||
            }
 | 
			
		||||
            return ret?iss::Ok:iss::Err;
 | 
			
		||||
#else
 | 
			
		||||
        if((addr==iss::arch::time || addr==iss::arch::timeh)){
 | 
			
		||||
            uint64_t time_val = owner->mtime_i.read();
 | 
			
		||||
            if (addr == iss::arch::time) {
 | 
			
		||||
                val = static_cast<reg_t>(time_val);
 | 
			
		||||
            } else if (addr == iss::arch::timeh) {
 | 
			
		||||
                if (sizeof(reg_t) != 4) return iss::Err;
 | 
			
		||||
                val = static_cast<reg_t>(time_val >> 32);
 | 
			
		||||
            }
 | 
			
		||||
            return iss::Ok;
 | 
			
		||||
#endif
 | 
			
		||||
        } else {
 | 
			
		||||
            return PLAT::read_csr(addr, val);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void wait_until(uint64_t flags) override {
 | 
			
		||||
        SCCDEBUG(owner->name()) << "Sleeping until interrupt";
 | 
			
		||||
        while(this->reg.pending_trap == 0 && (this->csr[iss::arch::mip] & this->csr[iss::arch::mie]) == 0) {
 | 
			
		||||
            sc_core::wait(wfi_evt);
 | 
			
		||||
        }
 | 
			
		||||
        PLAT::wait_until(flags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void local_irq(short id, bool value) {
 | 
			
		||||
        reg_t mask = 0;
 | 
			
		||||
        switch (id) {
 | 
			
		||||
        case 3: // SW
 | 
			
		||||
            mask = 1 << 3;
 | 
			
		||||
            break;
 | 
			
		||||
        case 7: // timer
 | 
			
		||||
            mask = 1 << 7;
 | 
			
		||||
            break;
 | 
			
		||||
        case 11: // external
 | 
			
		||||
            mask = 1 << 11;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            if(id>15) mask = 1 << id;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        if (value) {
 | 
			
		||||
            this->csr[iss::arch::mip] |= mask;
 | 
			
		||||
            wfi_evt.notify();
 | 
			
		||||
        } else
 | 
			
		||||
            this->csr[iss::arch::mip] &= ~mask;
 | 
			
		||||
        this->check_interrupt();
 | 
			
		||||
        if(value)
 | 
			
		||||
            SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->reg.pending_trap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    sysc::tgfs::core_complex *const owner;
 | 
			
		||||
    sc_core::sc_event wfi_evt;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* _SYSC_SC_CORE_ADAPTER_H_ */
 | 
			
		||||
@@ -30,10 +30,9 @@
 | 
			
		||||
 *
 | 
			
		||||
 *******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <iss/arch/tgc_c.h>
 | 
			
		||||
#include <iss/debugger/gdb_session.h>
 | 
			
		||||
#include <iss/debugger/server.h>
 | 
			
		||||
#include <iss/arch/tgc_c.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/iss.h>
 | 
			
		||||
#include <iss/interp/vm_base.h>
 | 
			
		||||
#include <util/logging.h>
 | 
			
		||||
@@ -389,7 +388,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = *PC + (int32_t)imm;
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(*PC + (int32_t)imm);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -419,9 +418,9 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = *PC +  4;
 | 
			
		||||
                                            *(X+rd) = (uint32_t)(*PC +  4);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        *NEXT_PC = *PC + (int32_t)sext<21>(imm);
 | 
			
		||||
                                        *NEXT_PC = (uint32_t)(*PC + (int32_t)sext<21>(imm));
 | 
			
		||||
                                        this->core.reg.last_branch = 1;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
@@ -448,13 +447,13 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t new_pc = (*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 0x1;
 | 
			
		||||
                                    uint32_t new_pc = (uint32_t)((*(X+rs1) + (int16_t)sext<12>(imm)) & ~ 0x1);
 | 
			
		||||
                                    if(new_pc % traits::INSTR_ALIGNMENT) {
 | 
			
		||||
                                        raise(0,  0);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        if(rd !=  0) {
 | 
			
		||||
                                            *(X+rd) = *PC +  4;
 | 
			
		||||
                                            *(X+rd) = (uint32_t)(*PC +  4);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        *NEXT_PC = new_pc & ~ 0x1;
 | 
			
		||||
                                        this->core.reg.last_branch = 1;
 | 
			
		||||
@@ -488,7 +487,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                            raise(0,  0);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *NEXT_PC = *PC + (int16_t)sext<13>(imm);
 | 
			
		||||
                                            *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<13>(imm));
 | 
			
		||||
                                            this->core.reg.last_branch = 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -521,7 +520,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                            raise(0,  0);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *NEXT_PC = *PC + (int16_t)sext<13>(imm);
 | 
			
		||||
                                            *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<13>(imm));
 | 
			
		||||
                                            this->core.reg.last_branch = 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -554,7 +553,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                            raise(0,  0);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *NEXT_PC = *PC + (int16_t)sext<13>(imm);
 | 
			
		||||
                                            *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<13>(imm));
 | 
			
		||||
                                            this->core.reg.last_branch = 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -587,7 +586,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                            raise(0,  0);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *NEXT_PC = *PC + (int16_t)sext<13>(imm);
 | 
			
		||||
                                            *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<13>(imm));
 | 
			
		||||
                                            this->core.reg.last_branch = 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -620,7 +619,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                            raise(0,  0);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *NEXT_PC = *PC + (int16_t)sext<13>(imm);
 | 
			
		||||
                                            *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<13>(imm));
 | 
			
		||||
                                            this->core.reg.last_branch = 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -653,7 +652,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                            raise(0,  0);
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *NEXT_PC = *PC + (int16_t)sext<13>(imm);
 | 
			
		||||
                                            *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<13>(imm));
 | 
			
		||||
                                            this->core.reg.last_branch = 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -681,7 +680,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    int8_t read_res = super::template read_mem<int8_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LB;
 | 
			
		||||
                                    int8_t res = (int8_t)read_res;
 | 
			
		||||
@@ -712,7 +711,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    int16_t read_res = super::template read_mem<int16_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LH;
 | 
			
		||||
                                    int16_t res = (int16_t)read_res;
 | 
			
		||||
@@ -743,7 +742,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LW;
 | 
			
		||||
                                    int32_t res = (int32_t)read_res;
 | 
			
		||||
@@ -774,10 +773,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    uint8_t read_res = super::template read_mem<uint8_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LBU;
 | 
			
		||||
                                    uint8_t res = (uint8_t)read_res;
 | 
			
		||||
                                    uint8_t res = read_res;
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -805,10 +804,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t load_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    uint32_t load_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    uint16_t read_res = super::template read_mem<uint16_t>(traits::MEM, load_address);
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_LHU;
 | 
			
		||||
                                    uint16_t res = (uint16_t)read_res;
 | 
			
		||||
                                    uint16_t res = read_res;
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -836,8 +835,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    super::template write_mem<uint8_t>(traits::MEM, store_address, (int8_t)*(X+rs2));
 | 
			
		||||
                                    uint32_t store_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    super::template write_mem<uint8_t>(traits::MEM, store_address, (uint8_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SB;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -863,8 +862,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    super::template write_mem<uint16_t>(traits::MEM, store_address, (int16_t)*(X+rs2));
 | 
			
		||||
                                    uint32_t store_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    super::template write_mem<uint16_t>(traits::MEM, store_address, (uint16_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SH;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -890,8 +889,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t store_address = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                    super::template write_mem<uint32_t>(traits::MEM, store_address, (int32_t)*(X+rs2));
 | 
			
		||||
                                    uint32_t store_address = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    super::template write_mem<uint32_t>(traits::MEM, store_address, (uint32_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_SW;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -918,7 +917,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = *(X+rs1) + (int16_t)sext<12>(imm);
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(*(X+rs1) + (int16_t)sext<12>(imm));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -1134,7 +1133,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = (int32_t)*(X+rs1) >> shamt;
 | 
			
		||||
                                        *(X+rd) = (uint32_t)((int32_t)*(X+rs1) >> shamt);
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -1161,7 +1160,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = *(X+rs1) + *(X+rs2);
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(*(X+rs1) + *(X+rs2));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -1188,7 +1187,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = *(X+rs1) - *(X+rs2);
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(*(X+rs1) - *(X+rs2));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -1350,7 +1349,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = (int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN -  1));
 | 
			
		||||
                                        *(X+rd) = (uint32_t)((int32_t)*(X+rs1) >> (*(X+rs2) & (traits::XLEN -  1)));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -1427,7 +1426,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 4;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                super::template write_mem<uint8_t>(traits::FENCE, traits::fence, pred <<  4 | succ);
 | 
			
		||||
                                super::template write_mem<uint32_t>(traits::FENCE, traits::fence, (uint8_t)pred <<  4 | succ);
 | 
			
		||||
                                if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE;
 | 
			
		||||
                            }
 | 
			
		||||
                TRAP_FENCE:break;
 | 
			
		||||
@@ -1706,7 +1705,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 4;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                super::template write_mem<uint16_t>(traits::FENCE, traits::fencei, imm);
 | 
			
		||||
                                super::template write_mem<uint32_t>(traits::FENCE, traits::fencei, imm);
 | 
			
		||||
                                if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_FENCE_I;
 | 
			
		||||
                            }
 | 
			
		||||
                TRAP_FENCE_I:break;
 | 
			
		||||
@@ -1731,7 +1730,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2);
 | 
			
		||||
                                    int64_t res = (int64_t)((int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2));
 | 
			
		||||
                                    if(rd != 0) {
 | 
			
		||||
                                        *(X+rd) = (uint32_t)res;
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -1759,7 +1758,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    int64_t res = (int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2);
 | 
			
		||||
                                    int64_t res = (int64_t)((int64_t)(int32_t)*(X+rs1) * (int64_t)(int32_t)*(X+rs2));
 | 
			
		||||
                                    if(rd != 0) {
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(res >> traits::XLEN);
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -1787,7 +1786,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    int64_t res = (int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2);
 | 
			
		||||
                                    int64_t res = (int64_t)((int64_t)(int32_t)*(X+rs1) * (uint64_t)*(X+rs2));
 | 
			
		||||
                                    if(rd != 0) {
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(res >> traits::XLEN);
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -1815,7 +1814,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint64_t res = (uint64_t)*(X+rs1) * (uint64_t)*(X+rs2);
 | 
			
		||||
                                    uint64_t res = (uint64_t)((uint64_t)*(X+rs1) * (uint64_t)*(X+rs2));
 | 
			
		||||
                                    if(rd != 0) {
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(res >> traits::XLEN);
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -1852,11 +1851,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                                *(X+rd) = MMIN;
 | 
			
		||||
                                            }
 | 
			
		||||
                                            else {
 | 
			
		||||
                                                *(X+rd) = dividend / divisor;
 | 
			
		||||
                                                *(X+rd) = (uint32_t)(dividend / divisor);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            *(X+rd) = (int32_t)- 1;
 | 
			
		||||
                                            *(X+rd) = (uint32_t)- 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
@@ -1885,12 +1884,12 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(*(X+rs2) !=  0) {
 | 
			
		||||
                                        if(rd != 0) {
 | 
			
		||||
                                            *(X+rd) = *(X+rs1) / *(X+rs2);
 | 
			
		||||
                                            *(X+rd) = (uint32_t)(*(X+rs1) / *(X+rs2));
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                    else {
 | 
			
		||||
                                        if(rd != 0) {
 | 
			
		||||
                                            *(X+rd) = (int32_t)- 1;
 | 
			
		||||
                                            *(X+rd) = (uint32_t)- 1;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
@@ -1926,7 +1925,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                        }
 | 
			
		||||
                                        else {
 | 
			
		||||
                                            if(rd != 0) {
 | 
			
		||||
                                                *(X+rd) = (int32_t)*(X+rs1) % (int32_t)*(X+rs2);
 | 
			
		||||
                                                *(X+rd) = (uint32_t)((int32_t)*(X+rs1) % (int32_t)*(X+rs2));
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -1980,7 +1979,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                    /* generate console output when executing the command */
 | 
			
		||||
                    auto mnemonic = fmt::format(
 | 
			
		||||
                        "{mnemonic:10} {rd}, {imm:#05x}", fmt::arg("mnemonic", "caddi4spn"),
 | 
			
		||||
                        fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
 | 
			
		||||
                        fmt::arg("rd", name(8+rd)), fmt::arg("imm", imm));
 | 
			
		||||
                    this->core.disass_output(pc.val, mnemonic);
 | 
			
		||||
                }
 | 
			
		||||
                // used registers
 | 
			
		||||
@@ -1989,7 +1988,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                if(imm) {
 | 
			
		||||
                                    *(X+rd +  8) = *(X+2) + imm;
 | 
			
		||||
                                    *(X+rd +  8) = (uint32_t)(*(X+2) + imm);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
@@ -2013,10 +2012,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 2;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                    uint32_t load_address = *(X+rs1 +  8) + uimm;
 | 
			
		||||
                    int32_t read_res = super::template read_mem<int32_t>(traits::MEM, load_address);
 | 
			
		||||
                    uint32_t offs = (uint32_t)(*(X+rs1 +  8) + uimm);
 | 
			
		||||
                    int32_t read_res = super::template read_mem<int32_t>(traits::MEM, offs);
 | 
			
		||||
                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLW;
 | 
			
		||||
                    *(X+rd +  8) = (int32_t)read_res;
 | 
			
		||||
                    *(X+rd +  8) = (uint32_t)(int32_t)read_res;
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CLW:break;
 | 
			
		||||
            }// @suppress("No break at end of case")
 | 
			
		||||
@@ -2036,8 +2035,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 2;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                    uint32_t load_address = *(X+rs1 +  8) + uimm;
 | 
			
		||||
                    super::template write_mem<uint32_t>(traits::MEM, load_address, (int32_t)*(X+rs2 +  8));
 | 
			
		||||
                    uint32_t offs = (uint32_t)(*(X+rs1 +  8) + uimm);
 | 
			
		||||
                    super::template write_mem<uint32_t>(traits::MEM, offs, (uint32_t)*(X+rs2 +  8));
 | 
			
		||||
                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSW;
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CSW:break;
 | 
			
		||||
@@ -2062,7 +2061,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rs1 !=  0) {
 | 
			
		||||
                                        *(X+rs1) = *(X+rs1) + (int8_t)sext<6>(imm);
 | 
			
		||||
                                        *(X+rs1) = (uint32_t)(*(X+rs1) + (int8_t)sext<6>(imm));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -2095,8 +2094,8 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 2;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                    *(X+1) = *PC +  2;
 | 
			
		||||
                    *NEXT_PC = *PC + (int16_t)sext<12>(imm);
 | 
			
		||||
                    *(X+1) = (uint32_t)(*PC +  2);
 | 
			
		||||
                    *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<12>(imm));
 | 
			
		||||
                    this->core.reg.last_branch = 1;
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CJAL:break;
 | 
			
		||||
@@ -2121,7 +2120,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = (int8_t)sext<6>(imm);
 | 
			
		||||
                                        *(X+rd) = (uint32_t)((int8_t)sext<6>(imm));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -2146,7 +2145,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                        raise(0,  2);
 | 
			
		||||
                    }
 | 
			
		||||
                    if(rd !=  0) {
 | 
			
		||||
                        *(X+rd) = (int32_t)sext<18>(imm);
 | 
			
		||||
                        *(X+rd) = (uint32_t)((int32_t)sext<18>(imm));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CLUI:break;
 | 
			
		||||
@@ -2166,7 +2165,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                if(nzimm) {
 | 
			
		||||
                                    *(X+2) = *(X+2) + (int16_t)sext<10>(nzimm);
 | 
			
		||||
                                    *(X+2) = (uint32_t)(*(X+2) + (int16_t)sext<10>(nzimm));
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
@@ -2223,11 +2222,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                    if(shamt) {
 | 
			
		||||
                        *(X+rs1 +  8) = ((int32_t)*(X+rs1 +  8)) >> shamt;
 | 
			
		||||
                        *(X+rs1 +  8) = (uint32_t)(((int32_t)*(X+rs1 +  8)) >> shamt);
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        if(traits::XLEN ==  128) {
 | 
			
		||||
                            *(X+rs1 +  8) = ((int32_t)*(X+rs1 +  8)) >>  64;
 | 
			
		||||
                            *(X+rs1 +  8) = (uint32_t)(((int32_t)*(X+rs1 +  8)) >>  64);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -2248,7 +2247,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 2;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                    *(X+rs1 +  8) = *(X+rs1 +  8) & (int8_t)sext<6>(imm);
 | 
			
		||||
                    *(X+rs1 +  8) = (uint32_t)(*(X+rs1 +  8) & (int8_t)sext<6>(imm));
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CANDI:break;
 | 
			
		||||
            }// @suppress("No break at end of case")
 | 
			
		||||
@@ -2267,7 +2266,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 2;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                    *(X+rd +  8) = *(X+rd +  8) - *(X+rs2 +  8);
 | 
			
		||||
                    *(X+rd +  8) = (uint32_t)(*(X+rd +  8) - *(X+rs2 +  8));
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CSUB:break;
 | 
			
		||||
            }// @suppress("No break at end of case")
 | 
			
		||||
@@ -2341,7 +2340,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                *NEXT_PC = *PC + 2;
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                *NEXT_PC = *PC + (int16_t)sext<12>(imm);
 | 
			
		||||
                                *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<12>(imm));
 | 
			
		||||
                                this->core.reg.last_branch = 1;
 | 
			
		||||
                            }
 | 
			
		||||
                TRAP_CJ:break;
 | 
			
		||||
@@ -2362,7 +2361,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                if(*(X+rs1 +  8) ==  0) {
 | 
			
		||||
                                    *NEXT_PC = *PC + (int16_t)sext<9>(imm);
 | 
			
		||||
                                    *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<9>(imm));
 | 
			
		||||
                                    this->core.reg.last_branch = 1;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -2384,7 +2383,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                // execute instruction
 | 
			
		||||
                {
 | 
			
		||||
                                if(*(X+rs1 +  8) !=  0) {
 | 
			
		||||
                                    *NEXT_PC = *PC + (int16_t)sext<9>(imm);
 | 
			
		||||
                                    *NEXT_PC = (uint32_t)(*PC + (int16_t)sext<9>(imm));
 | 
			
		||||
                                    this->core.reg.last_branch = 1;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -2435,10 +2434,10 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                        raise(0,  2);
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        int32_t read_res = super::template read_mem<int32_t>(traits::MEM, *(X+2) + uimm);
 | 
			
		||||
                        uint32_t offs = (uint32_t)(*(X+2) + uimm);
 | 
			
		||||
                        int32_t read_res = super::template read_mem<int32_t>(traits::MEM, offs);
 | 
			
		||||
                        if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CLWSP;
 | 
			
		||||
                        int32_t res = read_res;
 | 
			
		||||
                        *(X+rd) = (int32_t)res;
 | 
			
		||||
                        *(X+rd) = (uint32_t)(int32_t)read_res;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                TRAP_CLWSP:break;
 | 
			
		||||
@@ -2526,7 +2525,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    if(rd !=  0) {
 | 
			
		||||
                                        *(X+rd) = *(X+rd) + *(X+rs2);
 | 
			
		||||
                                        *(X+rd) = (uint32_t)(*(X+rd) + *(X+rs2));
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
@@ -2551,7 +2550,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t new_pc = *(X+rs1);
 | 
			
		||||
                                    *(X+1) = *PC +  2;
 | 
			
		||||
                                    *(X+1) = (uint32_t)(*PC +  2);
 | 
			
		||||
                                    *NEXT_PC = new_pc & ~ 0x1;
 | 
			
		||||
                                    this->core.reg.last_branch = 1;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -2590,7 +2589,7 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
 | 
			
		||||
                                    raise(0,  2);
 | 
			
		||||
                                }
 | 
			
		||||
                                else {
 | 
			
		||||
                                    uint32_t offs = *(X+2) + uimm;
 | 
			
		||||
                                    uint32_t offs = (uint32_t)(*(X+2) + uimm);
 | 
			
		||||
                                    super::template write_mem<uint32_t>(traits::MEM, offs, (uint32_t)*(X+rs2));
 | 
			
		||||
                                    if(this->core.reg.trap_state>=0x80000000UL) goto TRAP_CSWSP;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -2646,3 +2645,30 @@ std::unique_ptr<vm_if> create<arch::tgc_c>(arch::tgc_c *core, unsigned short por
 | 
			
		||||
}
 | 
			
		||||
} // namespace interp
 | 
			
		||||
} // namespace iss
 | 
			
		||||
 | 
			
		||||
#include <iss/factory.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_m_p.h>
 | 
			
		||||
#include <iss/arch/riscv_hart_mu_p.h>
 | 
			
		||||
namespace iss {
 | 
			
		||||
namespace {
 | 
			
		||||
std::array<bool, 2> dummy = {
 | 
			
		||||
        core_factory::instance().register_creator("tgc_c|m_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::tgc_c>();
 | 
			
		||||
		    auto vm = new interp::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
 | 
			
		||||
		    if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
 | 
			
		||||
            return {cpu_ptr{cpu}, vm_ptr{vm}};
 | 
			
		||||
        }),
 | 
			
		||||
        core_factory::instance().register_creator("tgc_c|mu_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
 | 
			
		||||
            auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::tgc_c>();
 | 
			
		||||
		    auto vm = new interp::tgc_c::vm_impl<arch::tgc_c>(*cpu, false);
 | 
			
		||||
		    if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
 | 
			
		||||
            return {cpu_ptr{cpu}, vm_ptr{vm}};
 | 
			
		||||
        })
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
extern "C" {
 | 
			
		||||
	bool* get_tgc_c_interp_creators() {
 | 
			
		||||
		return iss::dummy.data();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user