mirror of
https://github.com/saymrwulf/pulp-runtime.git
synced 2026-05-27 22:46:05 +00:00
Target LLVM instead of GCC
Only for CV32E40X, at least for now. This commit also adds a script
objdump2itb.py from core-v-verif:
4e6e8604fa/bin/objdump2itb
This is used to generate an instruction table file that is, in turn,
used to populate instruction traces.
The script is lightly patched to support llvm-objdump's output.
This commit is contained in:
parent
fcca7032d4
commit
7b50643266
3 changed files with 203 additions and 10 deletions
186
bin/objdump2itb.py
Executable file
186
bin/objdump2itb.py
Executable file
|
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Copyright 2021 OpenHW Group
|
||||
# Copyright 2021 Silicon Labs
|
||||
#
|
||||
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://solderpad.org/licenses/
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier:Apache-2.0 WITH SHL-2.0
|
||||
#
|
||||
################################################################################
|
||||
#
|
||||
# dump2itb: python script to parse a GNU binutils objdump output file
|
||||
# into an instruction table format, which is a custom
|
||||
# text file more suitable for parsing using the standard IEEE 1800
|
||||
# text parsing functions
|
||||
#
|
||||
# The objdump should set the following flags to ensure that the regexps will
|
||||
# parse the expected text properly
|
||||
# % objdump -d -l -s program.elf > program.objdump
|
||||
#
|
||||
# The instruction table file format for a single instruction is:
|
||||
#
|
||||
# #<num_of_src_lines>
|
||||
# #<stc_line_0>
|
||||
# #<stc_line_1>
|
||||
# #...
|
||||
# #<src_line_n>
|
||||
# <instr_addr> <instr_func> <basename of instr_src> <line_num> <opcode> <num of asm words> <asm_word_0> <asm_word_1> <...> <asm_word_n>
|
||||
#
|
||||
# An esample: Note that the pound signs are part of the format
|
||||
# #6
|
||||
# # // Expect DCSR
|
||||
# # // 31:28 XDEBUGER Version = 4
|
||||
# # // 8:6 Cause = 2 Trigger
|
||||
# # // 1:0 Privelege = 3 Machine
|
||||
# # // TBD FIXME BUG documentation update needed
|
||||
# # li t1, 4<<28 | 2<<6 | 3<<0 | 1<<15
|
||||
# 437324064 _debugger_trigger_match_ebreak debugger.S 171 40008337 2 lui x6,0x40008
|
||||
#
|
||||
#
|
||||
# Author: Steve Richmond
|
||||
# email: steve.richmond@silabs.com
|
||||
#
|
||||
# Written with Python 3.5.1 on RHEL 7.7. Your python mileage may vary.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
import string
|
||||
import sys
|
||||
import re
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class CFunction:
|
||||
def __init__(self, addr, name):
|
||||
self.addr = addr
|
||||
self.name = name
|
||||
|
||||
# Regular expression to extract a function from objdump
|
||||
# Example:
|
||||
# 00000256 <end_handler_incr_mepc>:
|
||||
FUNC_PATTERN = "(?P<addr>[0-9a-f]{8}) <(?P<name>\S*)>:"
|
||||
FUNC_RE = re.compile(FUNC_PATTERN)
|
||||
|
||||
# Regular expression to extract an individual instruction
|
||||
# Example:
|
||||
# 264: 00a31363 bne t1,a0,26a <end_handler_incr_mepc2>
|
||||
INST_PATTERN = "(?P<addr>[0-9a-f]{1,8}):[\t\s]*(?P<mcode>[0-9a-f]{2}\s*[0-9a-f]{2}\s*([0-9a-f]{2}\s*[0-9a-f]{2})?)\s{2,}(?P<asm>[a-z].*)$"
|
||||
INST_RE = re.compile(INST_PATTERN)
|
||||
|
||||
# Regular expression to extract a source annotation for each instruction
|
||||
# Example:
|
||||
# /work/strichmo/core-v-verif/cv32e40x/tests/programs/custom/debug_test_trigger/debugger.S:47
|
||||
SRC_FILE_PATTERN = "^(?P<dir>/\S+)/(?P<file>[^/\s]+):(?P<line>[0-9]*)$"
|
||||
SRC_FILE_RE = re.compile(SRC_FILE_PATTERN)
|
||||
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument('objdump', help='Required objdump file for parsing. Use - to read STDIN')
|
||||
parser.add_argument('--debug', action='store_true', help='Enable more debug messages')
|
||||
|
||||
# Main function
|
||||
def objdump2itb():
|
||||
'''Parse an objdump file'''
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
if args.debug:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
parse(args.objdump)
|
||||
|
||||
def parse(objdump):
|
||||
'''Parse the file'''
|
||||
|
||||
if objdump == '-':
|
||||
fp = sys.stdin
|
||||
else:
|
||||
fp = open(objdump)
|
||||
|
||||
current_cfunction = None
|
||||
current_src_file = None
|
||||
current_src_line = 0
|
||||
current_src_code = ""
|
||||
used_src = 0
|
||||
|
||||
for line in fp:
|
||||
line_orig = line.strip('\n')
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# Parse function
|
||||
func = FUNC_RE.match(line)
|
||||
if func:
|
||||
d = func.groupdict()
|
||||
current_cfunction = CFunction(d["addr"], d["name"])
|
||||
current_src_code = "" # reset the source code lines
|
||||
used_src = 0
|
||||
continue
|
||||
|
||||
# Parse source file
|
||||
src_file = SRC_FILE_RE.match(line)
|
||||
if src_file:
|
||||
d = src_file.groupdict()
|
||||
current_src_file = d["file"]
|
||||
current_src_line = d["line"]
|
||||
current_src_code = "" # reset the source code lines
|
||||
used_src = 0
|
||||
continue
|
||||
|
||||
# Parse instruction
|
||||
inst = INST_RE.match(line)
|
||||
if inst:
|
||||
d = inst.groupdict()
|
||||
addr = d["addr"]
|
||||
mcode = d["mcode"]
|
||||
asm = d["asm"]
|
||||
mcode = mcode.replace(" ", "")
|
||||
asm = asm.replace("\t", " ").strip()
|
||||
addr = int("0x{}".format(addr), 0)
|
||||
fname = current_cfunction.name
|
||||
asm_len = len(asm.split())
|
||||
|
||||
used_src = 1
|
||||
if current_src_code == "":
|
||||
src_len = 0
|
||||
print("#{}".format(src_len))
|
||||
else:
|
||||
src_len = len(current_src_code.split('\n'));
|
||||
print("#{}\n{}".format(src_len, current_src_code))
|
||||
|
||||
print("{} {} {} {} {} {} {}".format(addr, fname, current_src_file, current_src_line, mcode, asm_len, asm))
|
||||
|
||||
logger.debug("Addr: '{:x}' Func: '{}' Source File: '{}' Source lineno: '{}' mcode: '{}' Asm: '{}'".format(
|
||||
int(addr), fname, current_src_file, current_src_line, mcode, asm))
|
||||
continue
|
||||
|
||||
# no match on filters
|
||||
if current_src_code:
|
||||
src_len = len(current_src_code.split('\n'));
|
||||
if (src_len < 10): # keep src from getting too long, also good if filenames are missing
|
||||
current_src_code += "\n#" + line_orig
|
||||
else:
|
||||
if current_src_file: # don't start adding source before first src file
|
||||
# first src line no newline before
|
||||
current_src_code = "#" + line_orig
|
||||
|
||||
logger.debug("Unmatched (treating as source line): '{}'".format(line))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
objdump2itb()
|
||||
|
||||
|
|
@ -15,10 +15,12 @@ VSIM ?= vsim
|
|||
ifdef PULP_RUNTIME_GCC_TOOLCHAIN
|
||||
PULP_CC := $(PULP_RUNTIME_GCC_TOOLCHAIN)/bin/$(PULP_CC)
|
||||
PULP_LD := $(PULP_RUNTIME_GCC_TOOLCHAIN)/bin/$(PULP_LD)
|
||||
PULP_OBJDUMP := $(PULP_RUNTIME_GCC_TOOLCHAIN)/bin/$(PULP_OBJDUMP)
|
||||
else
|
||||
ifdef PULP_RISCV_GCC_TOOLCHAIN
|
||||
PULP_CC := $(PULP_RISCV_GCC_TOOLCHAIN)/bin/$(PULP_CC)
|
||||
PULP_LD := $(PULP_RISCV_GCC_TOOLCHAIN)/bin/$(PULP_LD)
|
||||
PULP_OBJDUMP := $(PULP_RISCV_GCC_TOOLCHAIN)/bin/$(PULP_OBJDUMP)
|
||||
else
|
||||
$(warning "Warning: Neither PULP_RUNTIME_GCC_TOOLCHAIN nor PULP_RISCV_GCC_TOOLCHAIN is set.\
|
||||
Using defaults.")
|
||||
|
|
@ -41,7 +43,7 @@ VPATH = $(PULPRT_HOME)
|
|||
include $(PULPRT_HOME)/rules/pulpos/src.mk
|
||||
|
||||
PULP_CFLAGS += $(PULPRT_CONFIG_CFLAGS)
|
||||
PULP_CFLAGS += -fno-jump-tables -fno-tree-loop-distribute-patterns
|
||||
PULP_CFLAGS += -fno-jump-tables
|
||||
|
||||
ifeq '$(CONFIG_LIBC_MINIMAL)' '1'
|
||||
PULP_APP_CFLAGS += -I$(PULPRT_HOME)/lib/libc/minimal/include
|
||||
|
|
@ -167,6 +169,7 @@ else
|
|||
# default bootmode
|
||||
vsim_flags += +bootmode=jtag
|
||||
endif
|
||||
vsim_flags += +log_file=trace_core.log +itb_file=$(TARGETS).itb
|
||||
|
||||
else
|
||||
|
||||
|
|
@ -312,8 +315,12 @@ $(TARGET_BUILD_DIR)/stdout:
|
|||
$(TARGET_BUILD_DIR)/fs:
|
||||
mkdir -p $@
|
||||
|
||||
# ITB file needed by CV32E40X tracer
|
||||
$(TARGETS).itb:
|
||||
$(PULP_OBJDUMP) -d -l -s $(disopt) $(TARGETS) > $(TARGETS).dis
|
||||
$(PULPRT_HOME)/bin/objdump2itb.py $(TARGETS).dis > $(TARGETS).itb
|
||||
|
||||
run: $(TARGET_BUILD_DIR)/modelsim.ini $(TARGET_BUILD_DIR)/work $(TARGET_BUILD_DIR)/boot $(TARGET_BUILD_DIR)/tcl_files $(TARGET_BUILD_DIR)/stdout $(TARGET_BUILD_DIR)/fs $(TARGET_BUILD_DIR)/waves
|
||||
run: $(TARGET_BUILD_DIR)/modelsim.ini $(TARGET_BUILD_DIR)/work $(TARGET_BUILD_DIR)/boot $(TARGET_BUILD_DIR)/tcl_files $(TARGET_BUILD_DIR)/stdout $(TARGET_BUILD_DIR)/fs $(TARGET_BUILD_DIR)/waves $(TARGETS).itb
|
||||
$(PULPRT_HOME)/bin/stim_utils.py --binary=$(TARGETS) --vectors=$(TARGET_BUILD_DIR)/vectors/stim.txt
|
||||
$(PULPRT_HOME)/bin/plp_mkflash --flash-boot-binary=$(TARGETS) --stimuli=$(TARGET_BUILD_DIR)/vectors/qspi_stim.slm --flash-type=spi --qpi
|
||||
$(PULPRT_HOME)/bin/slm_hyper.py --input=$(TARGET_BUILD_DIR)/vectors/qspi_stim.slm --output=$(TARGET_BUILD_DIR)/vectors/hyper_stim.slm
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ PULP_ARCH_OBJDFLAGS ?=
|
|||
else ifdef USE_CV32E40X
|
||||
PULP_LDFLAGS +=
|
||||
PULP_CFLAGS += -D__riscv__ -UARCHI_CORE_HAS_PULPV2 -DRV_ISA_RV32
|
||||
PULP_ARCH_CFLAGS ?= -march=rv32imc -mnohwloop
|
||||
PULP_ARCH_LDFLAGS ?= -march=rv32imc -mnohwloop
|
||||
PULP_ARCH_OBJDFLAGS ?= -Mmarch=rv32imc -mnohwloop
|
||||
PULP_ARCH_CFLAGS ?= -march=rv32imc --target=riscv32
|
||||
PULP_ARCH_LDFLAGS ?= -march=rv32imc --target=riscv32
|
||||
PULP_ARCH_OBJDFLAGS ?= -D
|
||||
else
|
||||
PULP_LDFLAGS +=
|
||||
PULP_CFLAGS += -D__riscv__
|
||||
|
|
@ -31,12 +31,12 @@ endif
|
|||
|
||||
PULP_CFLAGS += -fdata-sections -ffunction-sections -include chips/pulpissimo/config.h -I$(PULPRT_HOME)/include/chips/pulpissimo
|
||||
PULP_OMP_CFLAGS += -fopenmp -mnativeomp
|
||||
PULP_LDFLAGS += -nostartfiles -nostdlib -Wl,--gc-sections -L$(PULPRT_HOME)/kernel -Tchips/pulpissimo/link.ld -lgcc
|
||||
PULP_LDFLAGS += -nostartfiles -nostdlib -Wl,--gc-sections -L$(PULPRT_HOME)/kernel -Tchips/pulpissimo/link.ld
|
||||
|
||||
PULP_CC = riscv32-unknown-elf-gcc
|
||||
PULP_AR ?= riscv32-unknown-elf-ar
|
||||
PULP_LD ?= riscv32-unknown-elf-gcc
|
||||
PULP_OBJDUMP ?= riscv32-unknown-elf-objdump
|
||||
PULP_CC = clang
|
||||
PULP_AR ?= llvm-ar
|
||||
PULP_LD ?= clang
|
||||
PULP_OBJDUMP ?= llvm-objdump
|
||||
|
||||
fc/archi=riscv
|
||||
pe/archi=riscv
|
||||
|
|
|
|||
Loading…
Reference in a new issue