mirror of
https://github.com/espressif/esp-idf.git
synced 2025-09-23 17:17:14 +00:00
feat: BitScrambler: Add support for addcti instruction as found in ESP32-C5
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import argparse
|
||||
import copy
|
||||
import json
|
||||
import math
|
||||
import re
|
||||
import struct
|
||||
@@ -66,6 +67,12 @@ class Inst(TypedDict, total=False):
|
||||
read: int
|
||||
|
||||
|
||||
class Chipcfg(TypedDict, total=False):
|
||||
chipname: str
|
||||
extra_instruction_groups: List[str]
|
||||
support_all: bool
|
||||
|
||||
|
||||
# Parser.
|
||||
# A bsasm file consists of labels, instruction bundles, meta-instructions
|
||||
# and comments. Comments start at a # and run to a newline and will be
|
||||
@@ -104,6 +111,7 @@ class Inst(TypedDict, total=False):
|
||||
# soul tasked with fixing up this code, feel free to create an issue to
|
||||
# rewrite this and assign it to me - Jeroen)
|
||||
|
||||
|
||||
def bsasm_parse(src: str) -> List[Element]:
|
||||
# Small hack: we trigger processing things on a newline. If a file is read without
|
||||
# a newline at the end of the last instruction, we'd erroneously ignore the last element.
|
||||
@@ -548,6 +556,18 @@ OP_IF = 0x0010000
|
||||
OP_IFN = 0x0020000
|
||||
OP_LDCTD = 0x0030000
|
||||
OP_LDCTI = 0x0040000
|
||||
OP_ADDCTI = 0x0050000
|
||||
|
||||
|
||||
def check_chip_supports_inst(chipcfg: Chipcfg, instgroup: str, ele: Element) -> None:
|
||||
if 'support_all' in chipcfg and chipcfg['support_all']:
|
||||
return
|
||||
|
||||
if instgroup not in chipcfg['extra_instruction_groups']:
|
||||
name = chipcfg['chipname']
|
||||
raise bsasm_syntax_error(
|
||||
ele, f'Chip {name} does not support this instruction'
|
||||
)
|
||||
|
||||
|
||||
def add_op_to_inst(inst: Inst, op: Opcode, ele: Element) -> None:
|
||||
@@ -561,7 +581,7 @@ def add_op_to_inst(inst: Inst, op: Opcode, ele: Element) -> None:
|
||||
|
||||
# Takes the elements generated by the parse routine and converts it to a
|
||||
# representation of the bits in the Bitscrambler program.
|
||||
def bsasm_assemble(elements: List[Element]) -> Tuple[List[Inst], Dict[str, int], List[int]]:
|
||||
def bsasm_assemble(elements: List[Element], chipcfg: Chipcfg) -> Tuple[List[Inst], Dict[str, int], List[int]]:
|
||||
# This assembler uses two passes: the first finds and resolves global
|
||||
# stuff, the second one encodes the actual instructions.
|
||||
|
||||
@@ -739,6 +759,19 @@ def bsasm_assemble(elements: List[Element]) -> Tuple[List[Inst], Dict[str, int],
|
||||
op['h'] = 1 if words[0][6] == 'h' else 0
|
||||
op['l'] = 1 if words[0][6] == 'l' else 0
|
||||
add_op_to_inst(inst, op, ele)
|
||||
elif re.match('addcti[ab]([hl])?$', words[0]):
|
||||
# ADDCTIc[h|l]
|
||||
check_chip_supports_inst(chipcfg, 'addcti', ele)
|
||||
check_arg_ct(ele, words, 1)
|
||||
op = {'op': OP_ADDCTI}
|
||||
op['c'] = 1 if words[0][6] == 'b' else 0
|
||||
if len(words[0]) == 7:
|
||||
op['h'] = 1
|
||||
op['l'] = 1
|
||||
else:
|
||||
op['h'] = 1 if words[0][7] == 'h' else 0
|
||||
op['l'] = 1 if words[0][7] == 'l' else 0
|
||||
add_op_to_inst(inst, op, ele)
|
||||
elif re.match('jmp', words[0]):
|
||||
# JMP tgt. Pseudo-op, translates to 'IF h tgt'
|
||||
check_arg_ct(ele, words, 2)
|
||||
@@ -955,15 +988,24 @@ if __name__ == '__main__':
|
||||
description='BitScrambler program assembler')
|
||||
parser.add_argument('infile', help='File name of assembly source to be assembled into a binary')
|
||||
parser.add_argument('outfile', help='File name of output binary', nargs='?', default=argparse.SUPPRESS)
|
||||
parser.add_argument('-c', help='Set chip capabilities json file; if set, returns an error when \
|
||||
an unsupported instruction is assembled', default=argparse.SUPPRESS)
|
||||
args = parser.parse_args()
|
||||
|
||||
chipcfg = Chipcfg()
|
||||
if 'c' in args:
|
||||
with open(args.c) as chipcfg_json:
|
||||
chipcfg = json.load(chipcfg_json)
|
||||
else:
|
||||
chipcfg = {'chipname': 'chip', 'extra_instruction_groups': [], 'support_all': True}
|
||||
|
||||
if 'outfile' in args:
|
||||
outfile = args.outfile
|
||||
else:
|
||||
outfile = re.sub('.bsasm', '', args.infile) + '.bsbin'
|
||||
asm = read_file(args.infile)
|
||||
tokens = bsasm_parse(asm)
|
||||
insts, meta, lut = bsasm_assemble(tokens)
|
||||
insts, meta, lut = bsasm_assemble(tokens, chipcfg)
|
||||
out_data = insts_to_binary(insts, meta, lut)
|
||||
write_file(outfile, out_data)
|
||||
print(f'Written {len(insts)} instructions and {len(lut)} 32-bit words of LUT.')
|
||||
|
Reference in New Issue
Block a user