diff --git a/core/.gitignore b/core/.gitignore index 25c2107f2..e7d93b2e5 100644 --- a/core/.gitignore +++ b/core/.gitignore @@ -11,3 +11,5 @@ mypy_report /CMakeLists.txt /cmake-build-debug/ tools/gdb_scripts/*.log +/embed/ble_bootloader/jlink.jdebug.user +/embed/ble_firmware/jlink.jdebug.user diff --git a/core/Makefile b/core/Makefile index 3cbbdccb2..8d2ceb586 100644 --- a/core/Makefile +++ b/core/Makefile @@ -5,6 +5,8 @@ MAKE = make -j $(JOBS) SCONS = scons -Q -j $(JOBS) BUILD_DIR = build +BLE_BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/ble_bootloader +BLE_FIRMWARE_BUILD_DIR = $(BUILD_DIR)/ble_firmware BOARDLOADER_BUILD_DIR = $(BUILD_DIR)/boardloader BOOTLOADER_BUILD_DIR = $(BUILD_DIR)/bootloader BOOTLOADER_CI_BUILD_DIR = $(BUILD_DIR)/bootloader_ci @@ -172,6 +174,13 @@ build: build_boardloader build_bootloader build_firmware build_prodtest build_un build_embed: build_boardloader build_bootloader build_firmware # build boardloader, bootloader, firmware + +build_ble_bootloader: ## build ble_bootloader + $(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" $(BLE_BOOTLOADER_BUILD_DIR)/ble_bootloader.bin + +build_ble_firmware: ## build ble_firmware + $(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" $(BLE_FIRMWARE_BUILD_DIR)/ble_firmware.bin + build_boardloader: ## build boardloader $(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \ CMAKELISTS="$(CMAKELISTS)" $(BOARDLOADER_BUILD_DIR)/boardloader.bin @@ -224,9 +233,16 @@ build_cross: ## build mpy-cross port ## clean commands: -clean: clean_boardloader clean_bootloader clean_bootloader_emu clean_bootloader_ci clean_prodtest clean_reflash clean_firmware clean_unix clean_cross ## clean all +clean: clean_ble_bootloader clean_ble_firmware clean_boardloader clean_bootloader clean_bootloader_emu clean_bootloader_ci clean_prodtest clean_reflash clean_firmware clean_unix clean_cross ## clean all rm -f ".sconsign.dblite" + +clean_ble_bootloader: ## clean ble_bootloader build + rm -rf $(BLE_BOOTLOADER_BUILD_DIR) + +clean_ble_firmware: ## clean ble_bootloader build + rm -rf $(BLE_FIRMWARE_BUILD_DIR) + clean_boardloader: ## clean boardloader build rm -rf $(BOARDLOADER_BUILD_DIR) @@ -258,6 +274,24 @@ clean_cross: ## clean mpy-cross build flash: flash_boardloader flash_bootloader flash_firmware ## flash everything using OpenOCD +flash_ble: flash_ble_bootloader flash_softdevice flash_ble_firmware + +flash_ble_bootloader: + @echo Flashing: $(BLE_BOOTLOADER_BUILD_DIR)/ble_bootloader.hex + nrfjprog -f nrf52 --program $(BLE_BOOTLOADER_BUILD_DIR)/ble_bootloader.hex --sectorerase + +flash_ble_firmware: + @echo Flashing: $(BLE_FIRMWARE_BUILD_DIR)/ble_firmware_merged.hex + nrfjprog -f nrf52 --program $(BLE_FIRMWARE_BUILD_DIR)/ble_firmware_merged.hex --sectorerase + +flash_ble_bl_settings: + @echo Flashing: $(BLE_BOOTLOADER_BUILD_DIR)/settings.hex + nrfjprog -f nrf52 --program $(BLE_BOOTLOADER_BUILD_DIR)/settings.hex --sectorerase + +flash_softdevice: + @echo Flashing: s140_nrf52_7.2.0_softdevice.hex + nrfjprog -f nrf52 --program embed/sdk/nrf52/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --sectorerase + flash_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.bin ## flash boardloader using OpenOCD $(OPENOCD) -c "init; reset halt; flash write_image erase $< $(BOARDLOADER_START); exit" @@ -282,6 +316,9 @@ flash_combine: $(PRODTEST_BUILD_DIR)/combined.bin ## flash combined using OpenOC flash_erase: ## erase all sectors in flash bank 0 $(OPENOCD) -c "init; reset halt; flash info 0; flash erase_sector 0 0 last; flash erase_check 0; exit" +flash_erase_ble: + nrfjprog -f nrf52 --eraseall + flash_read_storage: ## read storage sectors from flash $(OPENOCD) -c "init; flash read_bank 0 storage1.data 0x10000 65536; flash read_bank 0 storage2.data 0x110000 65536; exit" @@ -310,6 +347,10 @@ openocd: ## start openocd which connects to the device openocd_reset: ## cause a system reset using OpenOCD $(OPENOCD) -c "init; reset; exit" +# nrfjprog debug commands: +nrfjprog_reset: + nrfjprog -f nrf52 --reset + GDB = arm-none-eabi-gdb --nx -ex 'set remotetimeout unlimited' -ex 'set confirm off' -ex 'target remote 127.0.0.1:3333' -ex 'monitor reset halt' gdb_boardloader: $(BOARDLOADER_BUILD_DIR)/boardloader.elf ## start remote gdb session to openocd with boardloader symbols diff --git a/core/SConscript.ble_bootloader b/core/SConscript.ble_bootloader new file mode 100644 index 000000000..1f5b5b6ca --- /dev/null +++ b/core/SConscript.ble_bootloader @@ -0,0 +1,341 @@ +# pylint: disable=E0602 + +import os +import tools + +TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') +CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) + +if TREZOR_MODEL in ('1', ): + # skip boardloader build + env = Environment() + def build_ble_bootloader(target,source,env): + print(f'BLE BOOTLOADER: nothing to build for Model {TREZOR_MODEL}') + program_bin = env.Command( + target='ble_bootloader.bin', + source=None, + action=build_ble_bootloader + ) + Return() + +CCFLAGS_MOD = '' +CPPPATH_MOD = [] +CPPDEFINES_MOD = [] +SOURCE_MOD = [] + +CCFLAGS_MOD += '-Wno-sequence-point ' + + +if int(ARGUMENTS.get('PRODUCTION', 0)) == 0: + # Build for monitor debug mode and RTT. + DEBUG = True +else: + DEBUG = False + + + +# C flags common to all targets +CPPDEFINES_MOD += [ + 'CONFIG_GPIO_AS_PINRESET', + 'FLOAT_ABI_HARD', + 'NRF52833_XXAA', + ('NRF_DFU_SETTINGS_VERSION','2'), + 'MBR_PRESENT', + 'SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION', + ('__HEAP_SIZE','0'), + + ('uECC_ENABLE_VLI_API', '0'), + ('uECC_OPTIMIZATION_LEVEL', '3'), + ('uECC_SQUARE_FUNC', '0'), + ('uECC_SUPPORT_COMPRESSED_POINT', '0'), + ('uECC_VLI_NATIVE_LITTLE_ENDIAN', '1'), +] + + + + +CPPPATH_MOD += [ +] +CPPDEFINES_MOD += [ +] +SOURCE_MOD += [ + +] + +CPPPATH_MOD += [ + 'embed/sdk/nrf52/modules/nrfx/drivers/include', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc', + 'embed/sdk/nrf52/components/libraries/memobj', + 'embed/sdk/nrf52/components/libraries/crc32', + 'embed/sdk/nrf52/components/libraries/sha256', + 'embed/sdk/nrf52/components/libraries/experimental_section_vars', + 'embed/sdk/nrf52/components/libraries/mem_manager', + 'embed/sdk/nrf52/components/libraries/fstorage', + 'embed/sdk/nrf52/components/libraries/util', + 'embed/sdk/nrf52/modules/nrfx', + 'embed/sdk/nrf52/external/nrf_oberon/include', + 'embed/sdk/nrf52/components/libraries/crypto/backend/oberon', + 'embed/sdk/nrf52/components/libraries/crypto/backend/cifra', + 'embed/sdk/nrf52/components/libraries/atomic', + 'embed/sdk/nrf52/integration/nrfx', + 'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl', + 'embed/sdk/nrf52/components/drivers_nrf/nrf_soc_nosd', + 'embed/sdk/nrf52/components/libraries/log/src', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu', + 'embed/sdk/nrf52/components/libraries/bootloader/serial_dfu', + 'embed/sdk/nrf52/external/nrf_cc310_bl/include', + 'embed/sdk/nrf52/external/segger_rtt', + 'embed/sdk/nrf52/components/libraries/delay', + 'embed/sdk/nrf52/integration/nrfx/legacy', + 'embed/sdk/nrf52/modules/nrfx/hal', + 'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_hw', + 'embed/sdk/nrf52/components/libraries/log', + 'embed/sdk/nrf52/external/nrf_oberon', + 'embed/sdk/nrf52/components/libraries/strerror', + 'embed/sdk/nrf52/components/libraries/crypto/backend/mbedtls', + 'embed/sdk/nrf52/components/libraries/crypto/backend/cc310', + 'embed/sdk/nrf52/components/libraries/bootloader', + 'embed/sdk/nrf52/components/softdevice/mbr/headers', + 'embed/sdk/nrf52/components/libraries/crypto', + 'embed/sdk/nrf52/components/libraries/crypto/backend/optiga', + 'embed/sdk/nrf52/components/libraries/scheduler', + 'embed/sdk/nrf52/components/libraries/slip', + 'embed/sdk/nrf52/external/fprintf', + 'embed/sdk/nrf52/components/toolchain/cmsis/include', + 'embed/sdk/nrf52/components/libraries/balloc', + 'embed/sdk/nrf52/components/libraries/stack_info', + 'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_sw', + 'embed/sdk/nrf52/modules/nrfx/mdk', + 'embed/sdk/nrf52/external/nrf_cc310/include', + 'embed/sdk/nrf52/external/nano-pb', + 'embed/sdk/nrf52/components/libraries/queue', + 'embed/sdk/nrf52/components/libraries/mutex', + 'embed/sdk/nrf52/components/libraries/ringbuf', + + 'embed/trezorhal/boards', +] +SOURCE_MOD += [ +] + + +SOURCE_NRFHAL_AS = [ + 'embed/sdk/nrf52/modules/nrfx/mdk/gcc_startup_nrf52833.S', +] + + + +SOURCE_NRFHAL = [ + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_frontend.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_str_formatter.c', + 'embed/sdk/nrf52/modules/nrfx/mdk/system_nrf52833.c', + 'embed/sdk/nrf52/components/libraries/util/app_error_weak.c', + 'embed/sdk/nrf52/components/libraries/scheduler/app_scheduler.c', + 'embed/sdk/nrf52/components/libraries/util/app_util_platform.c', + 'embed/sdk/nrf52/components/libraries/crc32/crc32.c', + 'embed/sdk/nrf52/components/libraries/sha256/sha256.c', + 'embed/sdk/nrf52/components/libraries/mem_manager/mem_manager.c', + 'embed/sdk/nrf52/components/libraries/util/nrf_assert.c', + 'embed/sdk/nrf52/components/libraries/atomic/nrf_atomic.c', + 'embed/sdk/nrf52/components/libraries/balloc/nrf_balloc.c', + 'embed/sdk/nrf52/external/fprintf/nrf_fprintf.c', + 'embed/sdk/nrf52/external/fprintf/nrf_fprintf_format.c', + 'embed/sdk/nrf52/components/libraries/fstorage/nrf_fstorage.c', + 'embed/sdk/nrf52/components/libraries/fstorage/nrf_fstorage_nvmc.c', + 'embed/sdk/nrf52/components/libraries/memobj/nrf_memobj.c', + 'embed/sdk/nrf52/components/libraries/queue/nrf_queue.c', + 'embed/sdk/nrf52/components/libraries/ringbuf/nrf_ringbuf.c', + 'embed/sdk/nrf52/components/libraries/strerror/nrf_strerror.c', + 'embed/sdk/nrf52/components/libraries/slip/slip.c', + 'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_uart.c', + 'embed/sdk/nrf52/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c', + 'embed/sdk/nrf52/modules/nrfx/hal/nrf_nvmc.c', + 'embed/sdk/nrf52/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c', + 'embed/sdk/nrf52/modules/nrfx/soc/nrfx_atomic.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/prs/nrfx_prs.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uart.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uarte.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecc.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecdsa.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_hash.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_init.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_shared.c', + 'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_app_start.c', + 'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_app_start_final.c', + 'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_dfu_timers.c', + 'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_fw_activation.c', + 'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_info.c', + 'embed/sdk/nrf52/components/libraries/bootloader/nrf_bootloader_wdt.c', + 'embed/sdk/nrf52/external/nano-pb/pb_common.c', + 'embed/sdk/nrf52/external/nano-pb/pb_decode.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/dfu-cc.pb.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_flash.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_mbr.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_settings.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_transport.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_utils.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_validation.c', + 'embed/sdk/nrf52/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c', + 'embed/sdk/nrf52/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c', +] + +SOURCE_BLE_BOOTLOADER = [ + 'embed/ble_bootloader/main.c', + 'embed/ble_bootloader/uecc/uECC.c', + 'embed/ble_bootloader/dfu_public_key.c', + # originally embed/sdk/nrf52/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c', + 'embed/ble_bootloader/nrf_dfu_serial_uart.c', + 'embed/ble_bootloader/nrf_bootloader.c', +] + +if DEBUG: + CPPDEFINES_MOD += [ + 'DEBUG', + 'DEBUG_NRF', + 'NRF_DFU_DEBUG_VERSION', + 'MMD' + ] + SOURCE_BLE_BOOTLOADER += [ + 'embed/segger/SEGGER_MMD/JLINK_MONITOR.c', + 'embed/segger/SEGGER_MMD/JLINK_MONITOR_ISR_SES.S' + ] + + SOURCE_NRFHAL += [ + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_rtt.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_serial.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_uart.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_default_backends.c', + 'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT.c', + 'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c', + 'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_printf.c', + ] + + + CPPPATH_MOD += [ + 'embed/segger/SEGGER_MMD' + ] + + + +env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0'))) + + +env.Replace( + CP='cp', + AS='arm-none-eabi-as', + AR='arm-none-eabi-ar', + CC='arm-none-eabi-gcc', + LINK='arm-none-eabi-gcc', + SIZE='arm-none-eabi-size', + STRIP='arm-none-eabi-strip', + OBJCOPY='arm-none-eabi-objcopy', + PYTHON='python', + MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py', ) + +env.Replace( + TREZOR_MODEL=TREZOR_MODEL, ) + +CPU_ASFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' +CPU_CCFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 ' + + + + +env.Replace( + COPT=env.get('ENV').get('OPTIMIZE', '-Og'), + CCFLAGS='$COPT ' + '-g3 ' + '-std=c99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -Wno-unused-function ' + '-fdata-sections -ffunction-sections ' + '-fno-strict-aliasing ' + '-fno-builtin ' + '-fshort-enums ' + + CPU_CCFLAGS + CCFLAGS_MOD, + LINKFLAGS='-Lembed/sdk/nrf52/modules/nrfx/mdk -T embed/ble_bootloader/memory.ld -Wl,--gc-sections --specs=nano.specs -Wl,-Map=build/ble_bootloader/ble_bootloader.map -Wl,--warn-common -Wl,--print-memory-usage', + CPPPATH=[ + 'embed/ble_bootloader', + 'embed/ble_bootloader/uecc', + 'embed/sdk/nrf52', + ] + CPPPATH_MOD, + CPPDEFINES=[ + 'BLE_BOOTLOADER', + 'TREZOR_MODEL_'+TREZOR_MODEL, + ] + CPPDEFINES_MOD, + ASFLAGS=CPU_ASFLAGS, + ASPPFLAGS='$CFLAGS $CCFLAGS', ) + +# +# Program objects +# + +obj_program = [] +obj_program += env.Object(source=SOURCE_BLE_BOOTLOADER) +obj_program += env.Object(source=SOURCE_NRFHAL_AS, COPT='-O0') +obj_program += env.Object(source=SOURCE_NRFHAL) +obj_program += env.Object(source=SOURCE_MOD) + +env.Replace( + ALLSOURCES=SOURCE_NRFHAL_AS + SOURCE_MOD + SOURCE_BLE_BOOTLOADER + SOURCE_NRFHAL, + ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'])) + +cmake_gen = env.Command( + target='CMakeLists.txt', + source='', + action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', +) + + +LIB_FILES = [ + 'embed/sdk/nrf52/external/nrf_oberon/lib/cortex-m4/hard-float/liboberon_3.0.8.a', + 'embed/sdk/nrf52/external/nrf_cc310_bl/lib/cortex-m4/hard-float/libnrf_cc310_bl_0.9.13.a', +] + +program_elf = env.Command( + target='ble_bootloader.elf', + source=obj_program, + action= + '$LINK -o $TARGET $CCFLAGS $CFLAGS $LINKFLAGS $SOURCES ' + ' '.join(LIB_FILES) + ' -lc -lnosys -lm', +) + + + +BINARY_NAME = f"build/ble_bootloader/ble_bootloader-{tools.get_model_identifier(TREZOR_MODEL)}" +BINARY_NAME += "-" + tools.get_version('embed/ble_bootloader/version.h') +BINARY_NAME += "-" + tools.get_git_revision_short_hash() +BINARY_NAME += "-dirty" if tools.get_git_modified() else "" +BINARY_NAME += ".bin" + +if CMAKELISTS != 0: + env.Depends(program_elf, cmake_gen) + + + +program_hex = env.Command( + target='ble_bootloader.hex', + source=program_elf, + action='$OBJCOPY -O ihex $SOURCE $TARGET', +) + +program_bin = env.Command( + target='ble_bootloader.bin', + source=program_elf, + action=[ + '$OBJCOPY -O binary $SOURCE $TARGET', + '$CP $TARGET ' + BINARY_NAME, + ], +) + +program_settings = env.Command( + target='settings.hex', + source=None, + action='$CP ./embed/ble_bootloader/settings.hex $TARGET', +) + +env.Depends(program_bin, program_hex) +env.Depends(program_bin, program_settings) diff --git a/core/SConscript.ble_firmware b/core/SConscript.ble_firmware new file mode 100644 index 000000000..e6e5b86ea --- /dev/null +++ b/core/SConscript.ble_firmware @@ -0,0 +1,495 @@ +# pylint: disable=E0602 + +import os +import tools + +TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') +CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) + +if TREZOR_MODEL in ('1', ): + # skip boardloader build + env = Environment() + def build_ble_firmware(target,source,env): + print(f'BLE FIRMWARE: nothing to build for Model {TREZOR_MODEL}') + program_bin = env.Command( + target='ble_firmware.bin', + source=None, + action=build_ble_firmware + ) + Return() + +CCFLAGS_MOD = '' +CPPPATH_MOD = [] +CPPDEFINES_MOD = [] +SOURCE_MOD = [] + +CCFLAGS_MOD += '-Wno-sequence-point ' + + +if int(ARGUMENTS.get('PRODUCTION', 0)) == 0: + # Build for monitor debug mode. + MMD = True +else: + MMD = False + + + +# C flags common to all targets +CPPDEFINES_MOD += [ + 'CONFIG_GPIO_AS_PINRESET', + 'FLOAT_ABI_HARD', + 'NRF52833_XXAA', + 'SOFTDEVICE_PRESENT', + ('NRF_SD_BLE_API_VERSION', '7'), + 'APP_TIMER_V2', + 'APP_TIMER_V2_RTC1_ENABLED', + 'S140', + ('__HEAP_SIZE','8192'), + ('__STACK_SIZE','8192'), + + ('uECC_ENABLE_VLI_API', '0'), + ('uECC_OPTIMIZATION_LEVEL', '3'), + ('uECC_SQUARE_FUNC', '0'), + ('uECC_SUPPORT_COMPRESSED_POINT', '0'), + ('uECC_VLI_NATIVE_LITTLE_ENDIAN', '1'), +] + + + +CPPPATH_MOD += [ +] +CPPDEFINES_MOD += [ +] +SOURCE_MOD += [ + +] + +CPPPATH_MOD += [ + 'embed/sdk/nrf52/components/nfc/ndef/generic/message', + 'embed/sdk/nrf52/components/nfc/t2t_lib', + 'embed/sdk/nrf52/components/nfc/t4t_parser/hl_detection_procedure', + 'embed/sdk/nrf52/components/ble/ble_services/ble_ancs_c', + 'embed/sdk/nrf52/components/ble/ble_services/ble_ias_c', + 'embed/sdk/nrf52/components/libraries/pwm', + 'embed/sdk/nrf52/components/libraries/usbd/class/cdc/acm', + 'embed/sdk/nrf52/components/libraries/usbd/class/hid/generic', + 'embed/sdk/nrf52/components/libraries/usbd/class/msc', + 'embed/sdk/nrf52/components/libraries/usbd/class/hid', + 'embed/sdk/nrf52/modules/nrfx/hal', + 'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser', + 'embed/sdk/nrf52/components/libraries/log', + 'embed/sdk/nrf52/components/ble/ble_services/ble_gls', + 'embed/sdk/nrf52/components/libraries/fstorage', + 'embed/sdk/nrf52/components/nfc/ndef/text', + 'embed/sdk/nrf52/components/libraries/mutex', + 'embed/sdk/nrf52/components/libraries/gfx', + 'embed/sdk/nrf52/components/libraries/bootloader/ble_dfu', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/common', + 'embed/sdk/nrf52/components/libraries/fifo', + 'embed/sdk/nrf52/components/nfc/ndef/generic/record', + 'embed/sdk/nrf52/components/nfc/t4t_parser/cc_file', + 'embed/sdk/nrf52/components/ble/ble_advertising', + 'embed/sdk/nrf52/external/utf_converter', + 'embed/sdk/nrf52/components/ble/ble_services/ble_bas_c', + 'embed/sdk/nrf52/modules/nrfx/drivers/include', + 'embed/sdk/nrf52/components/libraries/experimental_task_manager', + 'embed/sdk/nrf52/components/ble/ble_services/ble_hrs_c', + 'embed/sdk/nrf52/components/softdevice/s140/headers/nrf52', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/le_oob_rec', + 'embed/sdk/nrf52/components/libraries/queue', + 'embed/sdk/nrf52/components/libraries/pwr_mgmt', + 'embed/sdk/nrf52/components/ble/ble_dtm', + 'embed/sdk/nrf52/components/toolchain/cmsis/include', + 'embed/sdk/nrf52/components/ble/ble_services/ble_rscs_c', + 'embed/sdk/nrf52/components/ble/common', + 'embed/sdk/nrf52/components/ble/ble_services/ble_lls', + 'embed/sdk/nrf52/components/nfc/platform', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ac_rec', + 'embed/sdk/nrf52/components/ble/ble_services/ble_bas', + 'embed/sdk/nrf52/components/libraries/mpu', + 'embed/sdk/nrf52/components/libraries/experimental_section_vars', + 'embed/sdk/nrf52/components/ble/ble_services/ble_ans_c', + 'embed/sdk/nrf52/components/libraries/slip', + 'embed/sdk/nrf52/components/libraries/delay', + 'embed/sdk/nrf52/components/libraries/csense_drv', + 'embed/sdk/nrf52/components/libraries/memobj', + 'embed/sdk/nrf52/components/ble/ble_services/ble_nus_c', + 'embed/sdk/nrf52/components/softdevice/common', + 'embed/sdk/nrf52/components/ble/ble_services/ble_ias', + 'embed/sdk/nrf52/components/libraries/usbd/class/hid/mouse', + 'embed/sdk/nrf52/components/libraries/low_power_pwm', + 'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser', + 'embed/sdk/nrf52/components/ble/ble_services/ble_dfu', + 'embed/sdk/nrf52/external/fprintf', + 'embed/sdk/nrf52/components/libraries/svc', + 'embed/sdk/nrf52/components/libraries/atomic', + 'embed/sdk/nrf52/components', + 'embed/sdk/nrf52/components/libraries/scheduler', + 'embed/sdk/nrf52/components/libraries/cli', + 'embed/sdk/nrf52/components/ble/ble_services/ble_lbs', + 'embed/sdk/nrf52/components/ble/ble_services/ble_hts', + 'embed/sdk/nrf52/components/ble/ble_services/ble_cts_c', + 'embed/sdk/nrf52/components/libraries/crc16', + 'embed/sdk/nrf52/components/nfc/t4t_parser/apdu', + 'embed/sdk/nrf52/components/libraries/util', + 'embed/sdk/nrf52/components/libraries/usbd/class/cdc', + 'embed/sdk/nrf52/components/libraries/csense', + 'embed/sdk/nrf52/components/libraries/balloc', + 'embed/sdk/nrf52/components/libraries/ecc', + 'embed/sdk/nrf52/components/libraries/hardfault', + 'embed/sdk/nrf52/components/ble/ble_services/ble_cscs', + 'embed/sdk/nrf52/components/libraries/uart', + 'embed/sdk/nrf52/components/libraries/hci', + 'embed/sdk/nrf52/components/libraries/usbd/class/hid/kbd', + 'embed/sdk/nrf52/components/libraries/timer', + 'embed/sdk/nrf52/components/libraries/queue', + 'embed/sdk/nrf52/components/softdevice/s140/headers', + 'embed/sdk/nrf52/integration/nrfx', + 'embed/sdk/nrf52/components/nfc/t4t_parser/tlv', + 'embed/sdk/nrf52/components/libraries/sortlist', + 'embed/sdk/nrf52/components/libraries/spi_mngr', + 'embed/sdk/nrf52/components/libraries/led_softblink', + 'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser', + 'embed/sdk/nrf52/components/libraries/sdcard', + 'embed/sdk/nrf52/components/nfc/ndef/parser/record', + 'embed/sdk/nrf52/modules/nrfx/mdk', + 'embed/sdk/nrf52/components/ble/ble_link_ctx_manager', + 'embed/sdk/nrf52/components/ble/ble_services/ble_nus', + 'embed/sdk/nrf52/components/libraries/twi_mngr', + 'embed/sdk/nrf52/components/ble/ble_services/ble_hids', + 'embed/sdk/nrf52/components/libraries/strerror', + 'embed/sdk/nrf52/components/libraries/crc32', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ble_oob_advdata', + 'embed/sdk/nrf52/components/nfc/t2t_parser', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ble_pair_msg', + 'embed/sdk/nrf52/components/libraries/usbd/class/audio', + 'embed/sdk/nrf52/components/nfc/t4t_lib', + 'embed/sdk/nrf52/components/ble/peer_manager', + 'embed/sdk/nrf52/components/libraries/mem_manager', + 'embed/sdk/nrf52/components/libraries/ringbuf', + 'embed/sdk/nrf52/components/ble/ble_services/ble_tps', + 'embed/sdk/nrf52/components/nfc/ndef/parser/message', + 'embed/sdk/nrf52/components/ble/ble_services/ble_dis', + 'embed/sdk/nrf52/components/nfc/ndef/uri', + 'embed/sdk/nrf52/components/ble/nrf_ble_gatt', + 'embed/sdk/nrf52/components/ble/nrf_ble_qwr', + 'embed/sdk/nrf52/components/libraries/gpiote', + 'embed/sdk/nrf52/components/libraries/button', + 'embed/sdk/nrf52/modules/nrfx', + 'embed/sdk/nrf52/components/libraries/twi_sensor', + 'embed/sdk/nrf52/integration/nrfx/legacy', + 'embed/sdk/nrf52/components/libraries/usbd', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ep_oob_rec', + 'embed/sdk/nrf52/external/segger_rtt', + 'embed/sdk/nrf52/components/libraries/atomic_fifo', + 'embed/sdk/nrf52/components/ble/ble_services/ble_lbs_c', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/ble_pair_lib', + 'embed/sdk/nrf52/components/libraries/crypto', + 'embed/sdk/nrf52/components/libraries/crypto/backend/cc310', + 'embed/sdk/nrf52/components/libraries/crypto/backend/cc310_bl', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc', + 'embed/sdk/nrf52/components/libraries/crypto/backend/mbedtls', + 'embed/sdk/nrf52/components/libraries/crypto/backend/oberon', + 'embed/sdk/nrf52/components/libraries/crypto/backend/optiga', + 'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_sw', + 'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_hw', + 'embed/sdk/nrf52/components/libraries/crypto/backend/cifra', + 'embed/sdk/nrf52/components/ble/ble_racp', + 'embed/sdk/nrf52/components/libraries/fds', + 'embed/sdk/nrf52/components/nfc/ndef/launchapp', + 'embed/sdk/nrf52/components/libraries/atomic_flags', + 'embed/sdk/nrf52/components/ble/ble_services/ble_hrs', + 'embed/sdk/nrf52/components/ble/ble_services/ble_rscs', + 'embed/sdk/nrf52/components/nfc/ndef/connection_handover/hs_rec', + 'embed/sdk/nrf52/components/nfc/ndef/conn_hand_parser/ac_rec_parser', + 'embed/sdk/nrf52/components/libraries/stack_guard', + 'embed/sdk/nrf52/components/libraries/stack_info', + 'embed/sdk/nrf52/components/libraries/log/src', + 'embed/sdk/nrf52/external/mbedtls/include', + 'embed', + 'embed/trezorhal/boards', +] +SOURCE_MOD += [ +] + + +SOURCE_NRFHAL_AS = [ + 'embed/sdk/nrf52/modules/nrfx/mdk/gcc_startup_nrf52833.S', +] + + + +SOURCE_NRFHAL = [ + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_frontend.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_str_formatter.c', + 'embed/sdk/nrf52/components/libraries/button/app_button.c', + 'embed/sdk/nrf52/components/libraries/util/app_error.c', + 'embed/sdk/nrf52/components/libraries/util/app_error_handler_gcc.c', + 'embed/sdk/nrf52/components/libraries/util/app_error_weak.c', + 'embed/sdk/nrf52/components/libraries/fifo/app_fifo.c', + 'embed/sdk/nrf52/components/libraries/scheduler/app_scheduler.c', + 'embed/sdk/nrf52/components/libraries/timer/app_timer2.c', + 'embed/sdk/nrf52/components/libraries/uart/app_uart_fifo.c', + 'embed/sdk/nrf52/components/libraries/util/app_util_platform.c', + 'embed/sdk/nrf52/components/libraries/timer/drv_rtc.c', + 'embed/sdk/nrf52/components/libraries/hardfault/hardfault_implementation.c', + 'embed/sdk/nrf52/components/libraries/util/nrf_assert.c', + 'embed/sdk/nrf52/components/libraries/atomic_fifo/nrf_atfifo.c', + 'embed/sdk/nrf52/components/libraries/atomic_flags/nrf_atflags.c', + 'embed/sdk/nrf52/components/libraries/atomic/nrf_atomic.c', + 'embed/sdk/nrf52/components/libraries/balloc/nrf_balloc.c', + 'embed/sdk/nrf52/external/fprintf/nrf_fprintf.c', + 'embed/sdk/nrf52/external/fprintf/nrf_fprintf_format.c', + 'embed/sdk/nrf52/components/libraries/memobj/nrf_memobj.c', + 'embed/sdk/nrf52/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c', + 'embed/sdk/nrf52/components/libraries/ringbuf/nrf_ringbuf.c', + 'embed/sdk/nrf52/components/libraries/experimental_section_vars/nrf_section_iter.c', + 'embed/sdk/nrf52/components/libraries/sortlist/nrf_sortlist.c', + 'embed/sdk/nrf52/components/libraries/strerror/nrf_strerror.c', + 'embed/sdk/nrf52/components/libraries/uart/retarget.c', + 'embed/sdk/nrf52/components/libraries/queue/nrf_queue.c', + 'embed/sdk/nrf52/modules/nrfx/mdk/system_nrf52833.c', + 'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_clock.c', + 'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_uart.c', + 'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_spi.c', + 'embed/sdk/nrf52/integration/nrfx/legacy/nrf_drv_rng.c', + 'embed/sdk/nrf52/modules/nrfx/soc/nrfx_atomic.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_clock.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_gpiote.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/prs/nrfx_prs.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uart.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_uarte.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_rng.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_spi.c', + 'embed/sdk/nrf52/modules/nrfx/drivers/src/nrfx_spim.c', + 'embed/sdk/nrf52/components/ble/common/ble_advdata.c', + 'embed/sdk/nrf52/components/ble/ble_advertising/ble_advertising.c', + 'embed/sdk/nrf52/components/ble/common/ble_conn_params.c', + 'embed/sdk/nrf52/components/ble/common/ble_conn_state.c', + 'embed/sdk/nrf52/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c', + 'embed/sdk/nrf52/components/ble/common/ble_srv_common.c', + 'embed/sdk/nrf52/components/ble/nrf_ble_gatt/nrf_ble_gatt.c', + 'embed/sdk/nrf52/components/ble/nrf_ble_qwr/nrf_ble_qwr.c', + 'embed/sdk/nrf52/external/utf_converter/utf.c', + 'embed/sdk/nrf52/components/softdevice/common/nrf_sdh.c', + 'embed/sdk/nrf52/components/softdevice/common/nrf_sdh_ble.c', + 'embed/sdk/nrf52/components/softdevice/common/nrf_sdh_soc.c', + 'embed/sdk/nrf52/components/ble/peer_manager/gatt_cache_manager.c', + 'embed/sdk/nrf52/components/ble/peer_manager/gatts_cache_manager.c', + 'embed/sdk/nrf52/components/ble/peer_manager/id_manager.c', + 'embed/sdk/nrf52/components/ble/peer_manager/peer_data_storage.c', + 'embed/sdk/nrf52/components/ble/peer_manager/peer_database.c', + 'embed/sdk/nrf52/components/ble/peer_manager/peer_id.c', + 'embed/sdk/nrf52/components/ble/peer_manager/peer_manager.c', + 'embed/sdk/nrf52/components/ble/peer_manager/peer_manager_handler.c', + 'embed/sdk/nrf52/components/ble/peer_manager/pm_buffer.c', + 'embed/sdk/nrf52/components/ble/peer_manager/nrf_ble_lesc.c', + 'embed/sdk/nrf52/components/libraries/fds/fds.c', + 'embed/sdk/nrf52/components/ble/peer_manager/security_manager.c', + 'embed/sdk/nrf52/components/ble/peer_manager/security_dispatcher.c', + 'embed/sdk/nrf52/components/libraries/fstorage/nrf_fstorage.c', + 'embed/sdk/nrf52/components/libraries/fstorage/nrf_fstorage_sd.c', + 'embed/sdk/nrf52/components/ble/ble_services/ble_dis/ble_dis.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c', + 'embed/sdk/nrf52/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecc.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecdsa.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_ecdh.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_hash.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_init.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_shared.c', + 'embed/sdk/nrf52/components/libraries/crypto/nrf_crypto_rng.c', + 'embed/sdk/nrf52/external/mbedtls/library/ctr_drbg.c', + 'embed/sdk/nrf52/external/mbedtls/library/aes.c', + 'embed/sdk/nrf52/external/mbedtls/library/platform.c', + 'embed/sdk/nrf52/external/mbedtls/library/platform_util.c', + +] + +SOURCE_NANOPB = [ + 'vendor/nanopb/pb_common.c', + 'vendor/nanopb/pb_decode.c', + 'vendor/nanopb/pb_encode.c', +] + +SOURCE_BLE_FIRMWARE = [ + 'embed/ble_firmware/main.c', + 'embed/ble_firmware/ble_nus.c', + 'embed/ble_firmware/int_comm.c', + 'embed/ble_firmware/dis.c', + 'embed/ble_firmware/pm.c', + 'embed/ble_firmware/power.c', + 'embed/ble_firmware/advertising.c', + 'embed/ble_firmware/connection.c', + 'embed/bootloader/protob/messages.pb.c', + 'embed/lib/protob_helpers.c', + 'embed/ble_bootloader/uecc/uECC.c', +] + +if MMD: + CPPDEFINES_MOD += [ + 'DEBUG', + 'DEBUG_NRF', + 'MMD' + ] + SOURCE_BLE_FIRMWARE += [ + 'embed/segger/SEGGER_MMD/JLINK_MONITOR.c', + 'embed/segger/SEGGER_MMD/JLINK_MONITOR_ISR_SES.S' + ] + + SOURCE_NRFHAL += [ + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_rtt.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_serial.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_backend_uart.c', + 'embed/sdk/nrf52/components/libraries/log/src/nrf_log_default_backends.c', + 'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT.c', + 'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c', + 'embed/sdk/nrf52/external/segger_rtt/SEGGER_RTT_printf.c', + ] + + + CPPPATH_MOD += [ + 'embed/segger/SEGGER_MMD' + ] + + + +env = Environment(ENV=os.environ, CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0'))) + + +env.Replace( + CP='cp', + AS='arm-none-eabi-as', + AR='arm-none-eabi-ar', + CC='arm-none-eabi-gcc', + LINK='arm-none-eabi-gcc', + SIZE='arm-none-eabi-size', + STRIP='arm-none-eabi-strip', + OBJCOPY='arm-none-eabi-objcopy', + PYTHON='python', + MAKECMAKELISTS='$PYTHON tools/make_cmakelists.py', ) + +env.Replace( + TREZOR_MODEL=TREZOR_MODEL, ) + +CPU_ASFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' +CPU_CCFLAGS = '-mthumb -mabi=aapcs -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 ' + + + + +env.Replace( + COPT=env.get('ENV').get('OPTIMIZE', '-Og'), + CCFLAGS='$COPT ' + '-g3 ' + '-std=c99 -Wall -Werror -Wdouble-promotion -Wpointer-arith -Wno-missing-braces -Wno-unused-function ' + '-fdata-sections -ffunction-sections ' + '-fno-strict-aliasing ' + '-fno-builtin ' + '-fshort-enums ' + + CPU_CCFLAGS + CCFLAGS_MOD, + LINKFLAGS='-Lembed/sdk/nrf52/modules/nrfx/mdk -T embed/ble_firmware/memory.ld -Wl,--gc-sections --specs=nano.specs -Wl,-Map=build/ble_firmware/ble_firmware.map -Wl,--warn-common -Wl,--print-memory-usage', + CPPPATH=[ + 'embed/ble_firmware', + 'embed/bootloader/protob', + 'embed/sdk/nrf52', + 'embed/lib', + 'vendor/nanopb', + 'embed/ble_bootloader/uecc', + ] + CPPPATH_MOD, + CPPDEFINES=[ + 'BLE_FIRMWARE', + 'TREZOR_MODEL_'+TREZOR_MODEL, + ] + CPPDEFINES_MOD, + ASFLAGS=CPU_ASFLAGS, + ASPPFLAGS='$CFLAGS $CCFLAGS', ) + +# +# Program objects +# + +obj_program = [] +obj_program += env.Object(source=SOURCE_BLE_FIRMWARE) +obj_program += env.Object(source=SOURCE_NRFHAL_AS, COPT='-O0') +obj_program += env.Object(source=SOURCE_NRFHAL) +obj_program += env.Object(source=SOURCE_NANOPB) +obj_program += env.Object(source=SOURCE_MOD) + +env.Replace( + ALLSOURCES=SOURCE_NRFHAL_AS + SOURCE_MOD + SOURCE_BLE_FIRMWARE + SOURCE_NRFHAL, + ALLDEFS=tools.get_defs_for_cmake(env['CPPDEFINES'])) + +cmake_gen = env.Command( + target='CMakeLists.txt', + source='', + action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', +) + + +LIB_FILES = [ +] + +program_elf = env.Command( + target='ble_firmware.elf', + source=obj_program, + action= + '$LINK -o $TARGET $CCFLAGS $CFLAGS $LINKFLAGS $SOURCES ' + ' '.join(LIB_FILES) + ' -lc -lnosys -lm', +) + + + +BINARY_NAME = f"build/ble_firmware/ble_firmware-{tools.get_model_identifier(TREZOR_MODEL)}" +BINARY_NAME += "-" + tools.get_version('embed/ble_firmware/version.h') +BINARY_NAME += "-" + tools.get_git_revision_short_hash() +BINARY_NAME += "-dirty" if tools.get_git_modified() else "" +BINARY_NAME += ".bin" + +if CMAKELISTS != 0: + env.Depends(program_elf, cmake_gen) + + + +program_hex = env.Command( + target='ble_firmware.hex', + source=program_elf, + action='$OBJCOPY -O ihex $SOURCE $TARGET', +) + +program_pkg = env.Command( + target='ble_firmware.zip', + source=program_hex, + action=[ + f'nrfutil pkg generate --hw-version 52 --sd-req=0x100 --application $SOURCE --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --key-file ./embed/ble_bootloader/priv.pem $TARGET --application-version-string {tools.get_version("embed/ble_firmware/version.h")}' + ], +) + +settings = env.Command( + target='settings.hex', + source=program_hex, + action=f'nrfutil settings generate --family NRF52 --application $SOURCE --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --application-version-string {tools.get_version("embed/ble_firmware/version.h")} --bootloader-version {tools.get_version_int("embed/ble_bootloader/version.h")} --bl-settings-version 2 --sd-boot-validation VALIDATE_ECDSA_P256_SHA256 --softdevice ./embed/sdk/nrf52/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --key-file ./embed/ble_bootloader/priv.pem $TARGET', +) + +program_merge = env.Command( + target='ble_firmware_merged.hex', + source=[program_hex, settings], + action='mergehex -m $SOURCES -o $TARGET', +) + +program_bin = env.Command( + target='ble_firmware.bin', + source=program_elf, + action=[ + '$OBJCOPY -O binary $SOURCE $TARGET', + '$CP $TARGET ' + BINARY_NAME, + ], +) + +env.Depends(program_bin, program_hex) +env.Depends(program_pkg, program_hex) +env.Depends(settings, program_hex) +env.Depends(program_bin, program_pkg) +env.Depends(program_merge, settings) +env.Depends(program_merge, program_hex) +env.Depends(program_bin, program_merge) diff --git a/core/SConstruct b/core/SConstruct index a04364313..4ec232348 100644 --- a/core/SConstruct +++ b/core/SConstruct @@ -1,5 +1,7 @@ # pylint: disable=E0602 +SConscript('SConscript.ble_bootloader', variant_dir='build/ble_bootloader', duplicate=False) +SConscript('SConscript.ble_firmware', variant_dir='build/ble_firmware', duplicate=False) SConscript('SConscript.boardloader', variant_dir='build/boardloader', duplicate=False) SConscript('SConscript.bootloader', variant_dir='build/bootloader', duplicate=False) SConscript('SConscript.bootloader_ci', variant_dir='build/bootloader_ci', duplicate=False) diff --git a/core/embed/ble_bootloader/dfu_public_key.c b/core/embed/ble_bootloader/dfu_public_key.c new file mode 100644 index 000000000..fb06f836c --- /dev/null +++ b/core/embed/ble_bootloader/dfu_public_key.c @@ -0,0 +1,16 @@ + +/* This file was automatically generated by nrfutil on 2023-01-23 (YY-MM-DD) at + * 16:58:55 */ + +#include "compiler_abstraction.h" +#include "stdint.h" + +/** @brief Public key used to verify DFU images */ +__ALIGN(4) +const uint8_t pk[64] = { + 0x7e, 0x2f, 0x54, 0x41, 0xb7, 0x3f, 0x0c, 0xc8, 0xa8, 0x8f, 0x29, + 0x1a, 0x91, 0x3c, 0x9f, 0x70, 0x7e, 0xc6, 0x6f, 0x69, 0x51, 0x14, + 0xa6, 0x04, 0xeb, 0x0b, 0x23, 0x61, 0xf0, 0x22, 0xa4, 0xf4, 0xad, + 0x73, 0x9b, 0xfa, 0x48, 0x2e, 0x1a, 0x90, 0xf6, 0x59, 0x28, 0x4c, + 0x73, 0x49, 0x64, 0xc5, 0x18, 0xd3, 0xb3, 0xb2, 0x1a, 0x60, 0xf0, + 0x79, 0xe8, 0x2c, 0x0a, 0x7c, 0x04, 0x84, 0xcd, 0xd6}; diff --git a/core/embed/ble_bootloader/jlink.jdebug b/core/embed/ble_bootloader/jlink.jdebug new file mode 100644 index 000000000..a29b4a790 --- /dev/null +++ b/core/embed/ble_bootloader/jlink.jdebug @@ -0,0 +1,332 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +File : /home/mbruna/CLionProjects/trezor-model_r/core/embed/ble_bootloader/jlink.jdebug +Created : 6 Feb 2023 15:54 +Ozone Version : V3.28c +*/ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // + // Dialog-generated settings + // + Project.AddPathSubstitute (".", "$(ProjectDir)"); + Project.AddPathSubstitute (".", "$(ProjectDir)"); + Project.SetDevice ("Cortex-M4"); + Project.SetHostIF ("USB", ""); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("20 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); + // + // User settings + // + File.Open ("../../build/ble_bootloader/ble_bootloader.elf"); +} + +/********************************************************************* +* +* OnStartupComplete +* +* Function description +* Called when program execution has reached/passed +* the startup completion point. Optional. +* +********************************************************************** +*/ +//void OnStartupComplete (void) { +//} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging an application in RAM on a Cortex-M target device. +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// VectorTableAddr = Elf.GetBaseAddr(); +// // +// // Set up initial stack pointer +// // +// if (VectorTableAddr != 0xFFFFFFFF) { +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// } +// // +// // Set up entry point PC +// // +// PC = Elf.GetEntryPointPC(); +// +// if (PC != 0xFFFFFFFF) { +// Target.SetReg("PC", PC); +// } else if (VectorTableAddr != 0xFFFFFFFF) { +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } else { +// Util.Error("Project file error: failed to set entry point PC", 1); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +** +********************************************************************** +*/ +void AfterTargetReset (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +void BeforeTargetConnect (void) { + Project.SetJLinkScript("./MMDScript.JLinkScript"); +} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} + +/********************************************************************* +* +* BeforeTargetResume +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetResume (void) { +//} + +/********************************************************************* +* +* OnSnapshotLoad +* +* Function description +* Called upon loading a snapshot. Optional. +* +* Additional information +* This function is used to restore the target state in cases +* where values cannot simply be written to the target. +* Typical use: GPIO clock needs to be enabled, before +* GPIO is configured. +* +********************************************************************** +*/ +//void OnSnapshotLoad (void) { +//} + +/********************************************************************* +* +* OnSnapshotSave +* +* Function description +* Called upon saving a snapshot. Optional. +* +* Additional information +* This function is usually used to save values of the target +* state which can either not be trivially read, +* or need to be restored in a specific way or order. +* Typically use: Memory Mapped Registers, +* such as PLL and GPIO configuration. +* +********************************************************************** +*/ +//void OnSnapshotSave (void) { +//} + +/********************************************************************* +* +* OnError +* +* Function description +* Called when an error ocurred. Optional. +* +********************************************************************** +*/ +//void OnError (void) { +//} + +/********************************************************************* +* +* AfterProjectLoad +* +* Function description +* After Project load routine. Optional. +* +********************************************************************** +*/ +//void AfterProjectLoad (void) { +//} + +/********************************************************************* +* +* _SetupTarget +* +* Function description +* Setup the target. +* Called by AfterTargetReset() and AfterTargetDownload(). +* +* Auto-generated function. May be overridden by Ozone. +* +********************************************************************** +*/ +void _SetupTarget(void) { + // + // this function is intentionally empty because both inital PC and + // initial SP were chosen not to be set + // +} diff --git a/core/embed/ble_bootloader/main.c b/core/embed/ble_bootloader/main.c new file mode 100644 index 000000000..4a0112376 --- /dev/null +++ b/core/embed/ble_bootloader/main.c @@ -0,0 +1,169 @@ +/** + * Copyright (c) 2016 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be + * reverse engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +/** @file + * + * @defgroup bootloader_secure_ble main.c + * @{ + * @ingroup dfu_bootloader_api + * @brief Bootloader project main file for secure DFU. + * + */ + +#include +#include "app_error.h" +#include "app_error_weak.h" +#include "nrf_bootloader.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_bootloader_dfu_timers.h" +#include "nrf_bootloader_info.h" +#include "nrf_delay.h" +#include "nrf_dfu.h" +#include "nrf_gpio.h" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#include "nrf_log_default_backends.h" +#include "nrf_mbr.h" +#include "trezor_t3w1_d1_NRF.h" + +static void on_error(void) { + NRF_LOG_FINAL_FLUSH(); + +#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT) + // To allow the buffer to be flushed by the host. + nrf_delay_ms(100); +#endif +#ifdef NRF_DFU_DEBUG_VERSION + NRF_BREAKPOINT_COND; +#endif + NVIC_SystemReset(); +} + +void app_error_handler(uint32_t error_code, uint32_t line_num, + const uint8_t* p_file_name) { + NRF_LOG_ERROR("%s:%d, %d", p_file_name, line_num, error_code); + on_error(); +} + +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) { + NRF_LOG_ERROR("Received a fault! id: 0x%08x, pc: 0x%08x, info: 0x%08x", id, + pc, info); + on_error(); +} + +void app_error_handler_bare(uint32_t error_code) { + NRF_LOG_ERROR("Received an error: 0x%08x!", error_code); + on_error(); +} + +/** + * @brief Function notifies certain events in DFU process. + */ +static void dfu_observer(nrf_dfu_evt_type_t evt_type) { + switch (evt_type) { + case NRF_DFU_EVT_DFU_FAILED: + case NRF_DFU_EVT_DFU_ABORTED: + case NRF_DFU_EVT_DFU_INITIALIZED: + // bsp_board_init(BSP_INIT_LEDS); + // bsp_board_led_on(BSP_BOARD_LED_0); + // bsp_board_led_on(BSP_BOARD_LED_1); + // bsp_board_led_off(BSP_BOARD_LED_2); + break; + case NRF_DFU_EVT_TRANSPORT_ACTIVATED: + // bsp_board_led_off(BSP_BOARD_LED_1); + // bsp_board_led_on(BSP_BOARD_LED_2); + break; + case NRF_DFU_EVT_DFU_STARTED: + break; + default: + break; + } +} + +uint32_t nrf_dfu_init_user(void) { + // signalize DFU mode + nrf_gpio_pin_set(GPIO_1_PIN); + + return NRF_SUCCESS; +} + +/**@brief Function for application main entry. */ +int main(void) { + NRF_APPROTECT->DISABLE = APPROTECT_DISABLE_DISABLE_SwDisable; + + uint32_t ret_val; + // Apply priority for monitor mode interrupt + NVIC_SetPriority(DebugMonitor_IRQn, _PRIO_SD_LOW); + + // Must happen before flash protection is applied, since it edits a protected + // page. + nrf_bootloader_mbr_addrs_populate(); + + // Protect MBR and bootloader code from being overwritten. + ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE); + APP_ERROR_CHECK(ret_val); + ret_val = + nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR, BOOTLOADER_SIZE); + APP_ERROR_CHECK(ret_val); + + nrf_gpio_cfg_output(GPIO_1_PIN); + nrf_gpio_cfg_output(GPIO_2_PIN); + nrf_gpio_pin_clear(GPIO_1_PIN); + nrf_gpio_pin_clear(GPIO_2_PIN); + + (void)NRF_LOG_INIT(nrf_bootloader_dfu_timer_counter_get); + NRF_LOG_DEFAULT_BACKENDS_INIT(); + + NRF_LOG_INFO("Inside main"); + + ret_val = nrf_bootloader_init(dfu_observer); + APP_ERROR_CHECK(ret_val); + + NRF_LOG_FLUSH(); + + NRF_LOG_ERROR("After main, should never be reached."); + NRF_LOG_FLUSH(); + + APP_ERROR_CHECK_BOOL(false); +} + +/** + * @} + */ diff --git a/core/embed/ble_bootloader/memory.ld b/core/embed/ble_bootloader/memory.ld new file mode 100644 index 000000000..cba932d57 --- /dev/null +++ b/core/embed/ble_bootloader/memory.ld @@ -0,0 +1,156 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x70000, LENGTH = 0xe000 + RAM (rwx) : ORIGIN = 0x20002ae8, LENGTH = 0x1d518 + uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4 + bootloader_settings_page (r) : ORIGIN = 0x0007F000, LENGTH = 0x1000 + uicr_mbr_params_page (r) : ORIGIN = 0x10001018, LENGTH = 0x4 + mbr_params_page (r) : ORIGIN = 0x0007E000, LENGTH = 0x1000 +} + +SECTIONS +{ + . = ALIGN(4); + .uicr_bootloader_start_address : + { + PROVIDE(__start_uicr_bootloader_start_address = .); + KEEP(*(SORT(.uicr_bootloader_start_address*))) + PROVIDE(__stop_uicr_bootloader_start_address = .); + } > uicr_bootloader_start_address + . = ALIGN(4); + .bootloader_settings_page(NOLOAD) : + { + PROVIDE(__start_bootloader_settings_page = .); + KEEP(*(SORT(.bootloader_settings_page*))) + PROVIDE(__stop_bootloader_settings_page = .); + } > bootloader_settings_page + . = ALIGN(4); + .uicr_mbr_params_page : + { + PROVIDE(__start_uicr_mbr_params_page = .); + KEEP(*(SORT(.uicr_mbr_params_page*))) + PROVIDE(__stop_uicr_mbr_params_page = .); + } > uicr_mbr_params_page + . = ALIGN(4); + .mbr_params_page(NOLOAD) : + { + PROVIDE(__start_mbr_params_page = .); + KEEP(*(SORT(.mbr_params_page*))) + PROVIDE(__stop_mbr_params_page = .); + } > mbr_params_page +} + +SECTIONS +{ + . = ALIGN(4); + .mem_section_dummy_ram : + { + } + .log_dynamic_data : + { + PROVIDE(__start_log_dynamic_data = .); + KEEP(*(SORT(.log_dynamic_data*))) + PROVIDE(__stop_log_dynamic_data = .); + } > RAM + .log_filter_data : + { + PROVIDE(__start_log_filter_data = .); + KEEP(*(SORT(.log_filter_data*))) + PROVIDE(__stop_log_filter_data = .); + } > RAM + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + +} INSERT AFTER .data; + +SECTIONS +{ + .mem_section_dummy_rom : + { + } + .crypto_data : + { + PROVIDE(__start_crypto_data = .); + KEEP(*(SORT(.crypto_data*))) + PROVIDE(__stop_crypto_data = .); + } > FLASH + .nrf_queue : + { + PROVIDE(__start_nrf_queue = .); + KEEP(*(.nrf_queue)) + PROVIDE(__stop_nrf_queue = .); + } > FLASH + .dfu_trans : + { + PROVIDE(__start_dfu_trans = .); + KEEP(*(SORT(.dfu_trans*))) + PROVIDE(__stop_dfu_trans = .); + } > FLASH + .svc_data : + { + PROVIDE(__start_svc_data = .); + KEEP(*(.svc_data)) + PROVIDE(__stop_svc_data = .); + } > FLASH + .log_const_data : + { + PROVIDE(__start_log_const_data = .); + KEEP(*(SORT(.log_const_data*))) + PROVIDE(__stop_log_const_data = .); + } > FLASH + .nrf_balloc : + { + PROVIDE(__start_nrf_balloc = .); + KEEP(*(.nrf_balloc)) + PROVIDE(__stop_nrf_balloc = .); + } > FLASH + .sdh_ble_observers : + { + PROVIDE(__start_sdh_ble_observers = .); + KEEP(*(SORT(.sdh_ble_observers*))) + PROVIDE(__stop_sdh_ble_observers = .); + } > FLASH + .log_backends : + { + PROVIDE(__start_log_backends = .); + KEEP(*(SORT(.log_backends*))) + PROVIDE(__stop_log_backends = .); + } > FLASH + .sdh_req_observers : + { + PROVIDE(__start_sdh_req_observers = .); + KEEP(*(SORT(.sdh_req_observers*))) + PROVIDE(__stop_sdh_req_observers = .); + } > FLASH + .sdh_state_observers : + { + PROVIDE(__start_sdh_state_observers = .); + KEEP(*(SORT(.sdh_state_observers*))) + PROVIDE(__stop_sdh_state_observers = .); + } > FLASH + .sdh_stack_observers : + { + PROVIDE(__start_sdh_stack_observers = .); + KEEP(*(SORT(.sdh_stack_observers*))) + PROVIDE(__stop_sdh_stack_observers = .); + } > FLASH + .sdh_soc_observers : + { + PROVIDE(__start_sdh_soc_observers = .); + KEEP(*(SORT(.sdh_soc_observers*))) + PROVIDE(__stop_sdh_soc_observers = .); + } > FLASH + +} INSERT AFTER .text + + +INCLUDE "nrf_common.ld" diff --git a/core/embed/ble_bootloader/nrf_bootloader.c b/core/embed/ble_bootloader/nrf_bootloader.c new file mode 100644 index 000000000..66250f1c0 --- /dev/null +++ b/core/embed/ble_bootloader/nrf_bootloader.c @@ -0,0 +1,475 @@ +/** + * Copyright (c) 2016 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be + * reverse engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "nrf_bootloader.h" + +#include "app_scheduler.h" +#include "compiler_abstraction.h" +#include "nordic_common.h" +#include "nrf.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_bootloader_dfu_timers.h" +#include "nrf_bootloader_fw_activation.h" +#include "nrf_bootloader_info.h" +#include "nrf_bootloader_wdt.h" +#include "nrf_delay.h" +#include "nrf_dfu.h" +#include "nrf_dfu_settings.h" +#include "nrf_dfu_utils.h" +#include "nrf_dfu_validation.h" +#include "nrf_error.h" +#include "nrf_gpio.h" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#include "nrf_power.h" +#include "sdk_config.h" + +static nrf_dfu_observer_t + m_user_observer; //= 100) || + (NRF_BL_DFU_INACTIVITY_TIMEOUT_MS == 0), + "NRF_BL_DFU_INACTIVITY_TIMEOUT_MS must be 100 ms or more, or 0 " + "to indicate that it is disabled."); + +#if defined(NRF_LOG_BACKEND_FLASH_START_PAGE) +STATIC_ASSERT(NRF_LOG_BACKEND_FLASH_START_PAGE != 0, + "If nrf_log flash backend is used it cannot use space after code " + "because it would collide with settings page."); +#endif + +/**@brief Weak implemenation of nrf_dfu_init + * + * @note This function will be overridden if nrf_dfu.c is + * compiled and linked with the project + */ +#if (__LINT__ != 1) +__WEAK uint32_t nrf_dfu_init(nrf_dfu_observer_t observer) { + NRF_LOG_DEBUG("in weak nrf_dfu_init"); + return NRF_SUCCESS; +} +#endif + +/**@brief Weak implementation of nrf_dfu_init + * + * @note This function must be overridden in application if + * user-specific initialization is needed. + */ +__WEAK uint32_t nrf_dfu_init_user(void) { + NRF_LOG_DEBUG("in weak nrf_dfu_init_user"); + return NRF_SUCCESS; +} + +static void flash_write_callback(void* p_context) { + UNUSED_PARAMETER(p_context); + m_flash_write_done = true; +} + +static void do_reset(void* p_context) { + UNUSED_PARAMETER(p_context); + + NRF_LOG_FINAL_FLUSH(); + + nrf_delay_ms(NRF_BL_RESET_DELAY_MS); + + NVIC_SystemReset(); +} + +static void bootloader_reset(bool do_backup) { + NRF_LOG_DEBUG("Resetting bootloader."); + + if (do_backup) { + m_flash_write_done = false; + nrf_dfu_settings_backup(do_reset); + } else { + do_reset(NULL); + } +} + +static void inactivity_timeout(void) { + NRF_LOG_INFO("Inactivity timeout."); + bootloader_reset(true); +} + +/**@brief Function for handling DFU events. + */ +static void dfu_observer(nrf_dfu_evt_type_t evt_type) { + switch (evt_type) { + case NRF_DFU_EVT_DFU_STARTED: + case NRF_DFU_EVT_OBJECT_RECEIVED: + nrf_bootloader_dfu_inactivity_timer_restart( + NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS), + inactivity_timeout); + break; + case NRF_DFU_EVT_DFU_COMPLETED: + case NRF_DFU_EVT_DFU_ABORTED: + bootloader_reset(true); + break; + case NRF_DFU_EVT_TRANSPORT_DEACTIVATED: + // Reset the internal state of the DFU settings to the last stored state. + nrf_dfu_settings_reinit(); + break; + default: + break; + } + + if (m_user_observer) { + m_user_observer(evt_type); + } +} + +/**@brief Function for initializing the event scheduler. + */ +static void scheduler_init(void) { + APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); +} + +/**@brief Suspend the CPU until an interrupt occurs. + */ +static void wait_for_event(void) { +#if defined(BLE_STACK_SUPPORT_REQD) || defined(ANT_STACK_SUPPORT_REQD) + (void)sd_app_evt_wait(); +#else + // Wait for an event. + __WFE(); + // Clear the internal event register. + __SEV(); + __WFE(); +#endif +} + +/**@brief Continually sleep and process tasks whenever woken. + */ +static void loop_forever(void) { + while (true) { + // feed the watchdog if enabled. + nrf_bootloader_wdt_feed(); + + app_sched_execute(); + + if (!NRF_LOG_PROCESS()) { + wait_for_event(); + } + } +} + +#if NRF_BL_DFU_ENTER_METHOD_BUTTON +//#ifndef BUTTON_PULL +// #error NRF_BL_DFU_ENTER_METHOD_BUTTON is enabled but not buttons seem to +// be available on the board. +//#endif +/**@brief Function for initializing button used to enter DFU mode. + */ +static void dfu_enter_button_init(void) { + nrf_gpio_cfg_sense_input(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN, + NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); +} +#endif + +static bool crc_on_valid_app_required(void) { + bool ret = true; + if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET && + (nrf_power_resetreas_get() & NRF_POWER_RESETREAS_OFF_MASK)) { + nrf_power_resetreas_clear(NRF_POWER_RESETREAS_OFF_MASK); + ret = false; + } else if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 && + ((nrf_power_gpregret2_get() & BOOTLOADER_DFU_SKIP_CRC_MASK) == + BOOTLOADER_DFU_SKIP_CRC)) { + nrf_power_gpregret2_set(nrf_power_gpregret2_get() & + ~BOOTLOADER_DFU_SKIP_CRC); + ret = false; + } else { + } + + return ret; +} + +static bool boot_validate(boot_validation_t const* p_validation, + uint32_t data_addr, uint32_t data_len, bool do_crc) { + if (!do_crc && (p_validation->type == VALIDATE_CRC)) { + return true; + } + return nrf_dfu_validation_boot_validate(p_validation, data_addr, data_len); +} + +/** @brief Function for checking if the main application is valid. + * + * @details This function checks if there is a valid application + * located at Bank 0. + * + * @param[in] do_crc Perform CRC check on application. Only CRC checks + can be skipped. For other boot validation types, + this parameter is ignored. + * + * @retval true If a valid application has been detected. + * @retval false If there is no valid application. + */ +static bool app_is_valid(bool do_crc) { + if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP) { + NRF_LOG_INFO("Boot validation failed. No valid app to boot."); + return false; + } else if (NRF_BL_APP_SIGNATURE_CHECK_REQUIRED && + (s_dfu_settings.boot_validation_app.type != + VALIDATE_ECDSA_P256_SHA256)) { + NRF_LOG_WARNING( + "Boot validation failed. The boot validation of the app must be a " + "signature check."); + return false; + } else if (SD_PRESENT && + !boot_validate(&s_dfu_settings.boot_validation_softdevice, + MBR_SIZE, s_dfu_settings.sd_size, do_crc)) { + NRF_LOG_WARNING( + "Boot validation failed. SoftDevice is present but invalid."); + return false; + } else if (!boot_validate(&s_dfu_settings.boot_validation_app, + nrf_dfu_bank0_start_addr(), + s_dfu_settings.bank_0.image_size, do_crc)) { + NRF_LOG_WARNING("Boot validation failed. App is invalid."); + return false; + } + // The bootloader itself is not checked, since a self-check of this kind gives + // little to no benefit compared to the cost incurred on each bootup. + + NRF_LOG_DEBUG("App is valid"); + return true; +} + +/**@brief Function for clearing all DFU enter flags that + * preserve state during reset. + * + * @details This is used to make sure that each of these flags + * is checked only once after reset. + */ +static void dfu_enter_flags_clear(void) { + if (NRF_BL_DFU_ENTER_METHOD_PINRESET && + (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk)) { + // Clear RESETPIN flag. + NRF_POWER->RESETREAS |= POWER_RESETREAS_RESETPIN_Msk; + } + + if (NRF_BL_DFU_ENTER_METHOD_GPREGRET && + ((nrf_power_gpregret_get() & BOOTLOADER_DFU_START_MASK) == + BOOTLOADER_DFU_START)) { + // Clear DFU mark in GPREGRET register. + nrf_power_gpregret_set(nrf_power_gpregret_get() & ~BOOTLOADER_DFU_START); + } + + if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS && + (s_dfu_settings.enter_buttonless_dfu == 1)) { + // Clear DFU flag in flash settings. + s_dfu_settings.enter_buttonless_dfu = 0; + APP_ERROR_CHECK(nrf_dfu_settings_write(NULL)); + } +} + +/**@brief Function for checking whether to enter DFU mode or not. + */ +static bool dfu_enter_check(void) { + if (!app_is_valid(crc_on_valid_app_required())) { + NRF_LOG_DEBUG("DFU mode because app is not valid."); + return true; + } + + if (NRF_BL_DFU_ENTER_METHOD_BUTTON && + (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 1)) { + NRF_LOG_DEBUG("DFU mode requested via button."); + return true; + } + + if (NRF_BL_DFU_ENTER_METHOD_PINRESET && + (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk)) { + NRF_LOG_DEBUG("DFU mode requested via pin-reset."); + return true; + } + + if (NRF_BL_DFU_ENTER_METHOD_GPREGRET && + ((nrf_power_gpregret_get() & BOOTLOADER_DFU_START_MASK) == + BOOTLOADER_DFU_START)) { + NRF_LOG_DEBUG("DFU mode requested via GPREGRET."); + return true; + } + + if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS && + (s_dfu_settings.enter_buttonless_dfu == 1)) { + NRF_LOG_DEBUG("DFU mode requested via bootloader settings."); + return true; + } + + return false; +} + +#if NRF_BL_DFU_ALLOW_UPDATE_FROM_APP +static void postvalidate(void) { + NRF_LOG_INFO("Postvalidating update after reset."); + nrf_dfu_validation_init(); + + if (nrf_dfu_validation_init_cmd_present()) { + uint32_t firmware_start_addr; + uint32_t firmware_size; + + // Execute a previously received init packed. Subsequent executes will have + // no effect. + if (nrf_dfu_validation_init_cmd_execute( + &firmware_start_addr, &firmware_size) == NRF_DFU_RES_CODE_SUCCESS) { + if (nrf_dfu_validation_prevalidate() == NRF_DFU_RES_CODE_SUCCESS) { + if (nrf_dfu_validation_activation_prepare(firmware_start_addr, + firmware_size) == + NRF_DFU_RES_CODE_SUCCESS) { + NRF_LOG_INFO("Postvalidation successful."); + } + } + } + } + + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; + UNUSED_RETURN_VALUE(nrf_dfu_settings_write_and_backup(flash_write_callback)); +} +#endif + +ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer) { + NRF_LOG_DEBUG("In nrf_bootloader_init"); + + ret_code_t ret_val; + nrf_bootloader_fw_activation_result_t activation_result; + uint32_t initial_timeout; + bool dfu_enter = false; + + m_user_observer = observer; + + if (NRF_BL_DEBUG_PORT_DISABLE) { + nrf_bootloader_debug_port_disable(); + } + +#if NRF_BL_DFU_ENTER_METHOD_BUTTON + dfu_enter_button_init(); +#endif + + ret_val = nrf_dfu_settings_init(false); + if (ret_val != NRF_SUCCESS) { + return NRF_ERROR_INTERNAL; + } + +#if NRF_BL_DFU_ALLOW_UPDATE_FROM_APP + // Postvalidate if DFU has signaled that update is ready. + if (s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_1) { + postvalidate(); + } +#endif + + // Check if an update needs to be activated and activate it. + activation_result = nrf_bootloader_fw_activate(); + + switch (activation_result) { + case ACTIVATION_NONE: + initial_timeout = + NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS); + dfu_enter = dfu_enter_check(); + break; + + case ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE: + initial_timeout = + NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_CONTINUATION_TIMEOUT_MS); + dfu_enter = true; + break; + + case ACTIVATION_SUCCESS: + bootloader_reset(true); + NRF_LOG_ERROR("Unreachable"); + return NRF_ERROR_INTERNAL; // Should not reach this. + + case ACTIVATION_ERROR: + default: + return NRF_ERROR_INTERNAL; + } + + if (dfu_enter) { + nrf_bootloader_wdt_init(); + scheduler_init(); + dfu_enter_flags_clear(); + + // Call user-defined init function if implemented + ret_val = nrf_dfu_init_user(); + if (ret_val != NRF_SUCCESS) { + return NRF_ERROR_INTERNAL; + } + + nrf_bootloader_dfu_inactivity_timer_restart(initial_timeout, + inactivity_timeout); + + ret_val = nrf_dfu_init(dfu_observer); + if (ret_val != NRF_SUCCESS) { + return NRF_ERROR_INTERNAL; + } + + NRF_LOG_DEBUG("Enter main loop"); + loop_forever(); // This function will never return. + NRF_LOG_ERROR("Unreachable"); + } else { + // Erase additional data like peer data or advertisement name + ret_val = nrf_dfu_settings_additional_erase(); + if (ret_val != NRF_SUCCESS) { + return NRF_ERROR_INTERNAL; + } + + m_flash_write_done = false; + nrf_dfu_settings_backup(flash_write_callback); + ASSERT(m_flash_write_done); + + nrf_bootloader_app_start(); + NRF_LOG_ERROR("Unreachable"); + } + + // Should not be reached. + return NRF_ERROR_INTERNAL; +} diff --git a/core/embed/ble_bootloader/nrf_crypto_allocator.h b/core/embed/ble_bootloader/nrf_crypto_allocator.h new file mode 100644 index 000000000..e4c59bc55 --- /dev/null +++ b/core/embed/ble_bootloader/nrf_crypto_allocator.h @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2019 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be + * reverse engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef NRF_CRYPTO_ALLOCATOR_H__ +#define NRF_CRYPTO_ALLOCATOR_H__ + +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Crypto library in bootloader case does not use dynamic allocation */ +#define NRF_CRYPTO_ALLOC(size) \ + NULL; \ + ASSERT(0) +#define NRF_CRYPTO_ALLOC_ON_STACK(size) \ + NULL; \ + ASSERT(0) +#define NRF_CRYPTO_FREE(ptr) (void)ptr; + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_CRYPTO_ALLOCATOR_H__ */ diff --git a/core/embed/ble_bootloader/nrf_dfu_serial_uart.c b/core/embed/ble_bootloader/nrf_dfu_serial_uart.c new file mode 100644 index 000000000..579064bbd --- /dev/null +++ b/core/embed/ble_bootloader/nrf_dfu_serial_uart.c @@ -0,0 +1,276 @@ +// clang-format off + +/** + * Copyright (c) 2016 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "nrf_dfu_serial.h" + +#include +#include "trezor_t3w1_d1_NRF.h" + +#include "nrf_gpio.h" +#include "nordic_common.h" +#include "app_util_platform.h" +#include "nrf_dfu_transport.h" +#include "nrf_dfu_req_handler.h" +#include "slip.h" +#include "nrf_balloc.h" +#include "nrf_drv_uart.h" + +#define NRF_LOG_MODULE_NAME nrf_dfu_serial_uart +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + +/**@file + * + * @defgroup nrf_dfu_serial_uart DFU Serial UART transport + * @ingroup nrf_dfu + * @brief Device Firmware Update (DFU) transport layer using UART. + */ + +#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t)) +#define NRF_UART_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1) +#define RX_BUF_SIZE (64) //to get 64bytes payload +#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE) +#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE) +#define UART_SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1) +#define BALLOC_BUF_SIZE ((CEIL_DIV((RX_BUF_SIZE+OPCODE_SIZE),sizeof(uint32_t))*sizeof(uint32_t))) + +NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS); + +static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0); +static uint8_t m_rx_byte; + +static nrf_dfu_serial_t m_serial; +static slip_t m_slip; +static uint8_t m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP]; +static bool m_active; +static bool m_waiting_for_buffers = false; + +static nrf_dfu_observer_t m_observer; + +static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer); +static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception); + +DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const uart_dfu_transport) = +{ + .init_func = uart_dfu_transport_init, + .close_func = uart_dfu_transport_close, +}; + +static void payload_free(void * p_buf) +{ + uint8_t * p_buf_root = (uint8_t *)p_buf - DATA_OFFSET; //pointer is shifted to point to data + nrf_balloc_free(&m_payload_pool, p_buf_root); + uint8_t utilization = m_payload_pool.p_stack_limit - m_payload_pool.p_cb->p_stack_pointer; + + if (m_waiting_for_buffers && utilization < NRF_DFU_SERIAL_UART_RX_BUFFERS - 2) { + NRF_LOG_INFO("Buffer utilization: %d, resuming.", utilization); + + nrf_gpio_pin_set(RTS_PIN_NUMBER); + nrf_gpio_cfg_output(RTS_PIN_NUMBER); + m_uart.uarte.p_reg->PSEL.RTS = RTS_PIN_NUMBER; + m_waiting_for_buffers = false; + } + +} + +static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length) +{ + uint32_t slip_len; + (void) slip_encode(m_rsp_buf, (uint8_t *)p_data, length, &slip_len); + + return nrf_drv_uart_tx(&m_uart, m_rsp_buf, slip_len); +} + +static __INLINE void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len) +{ + ret_code_t ret_code = NRF_ERROR_TIMEOUT; + + // Check if there is byte to process. Zero length transfer means that RXTO occured. + if (len) + { + ret_code = slip_decode_add_byte(&m_slip, p_data[0]); + } + + (void) nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1); + + if (ret_code == NRF_SUCCESS) + { + nrf_dfu_serial_on_packet_received(p_transport, + (uint8_t const *)m_slip.p_buffer, + m_slip.current_index); + + uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool); + + uint8_t utilization = m_payload_pool.p_stack_limit - m_payload_pool.p_cb->p_stack_pointer; + + if (!m_waiting_for_buffers && utilization >= NRF_DFU_SERIAL_UART_RX_BUFFERS - 2) { + NRF_LOG_INFO("Buffer utilization: %d, waiting.", utilization); + m_uart.uarte.p_reg->PSEL.RTS = NRF_UART_PSEL_DISCONNECTED; + nrf_gpio_cfg_output(RTS_PIN_NUMBER); + nrf_gpio_pin_set(RTS_PIN_NUMBER); + m_waiting_for_buffers = true; + } + + if (p_rx_buf == NULL) + { + NRF_LOG_ERROR("Failed to allocate buffer"); + return; + } + NRF_LOG_INFO("Allocated buffer %x", p_rx_buf); + // reset the slip decoding + m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET]; + m_slip.current_index = 0; + m_slip.state = SLIP_STATE_DECODING; + } + +} + +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + switch (p_event->type) + { + case NRF_DRV_UART_EVT_RX_DONE: + on_rx_complete((nrf_dfu_serial_t*)p_context, + p_event->data.rxtx.p_data, + p_event->data.rxtx.bytes); + break; + + case NRF_DRV_UART_EVT_ERROR: + APP_ERROR_HANDLER(p_event->data.error.error_mask); + break; + + default: + // No action. + break; + } +} + +static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer) +{ + uint32_t err_code = NRF_SUCCESS; + + if (m_active) + { + return err_code; + } + + NRF_LOG_DEBUG("serial_dfu_transport_init()"); + + m_observer = observer; + + err_code = nrf_balloc_init(&m_payload_pool); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool); + + m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET]; + m_slip.current_index = 0; + m_slip.buffer_len = UART_SLIP_MTU; + m_slip.state = SLIP_STATE_DECODING; + + m_serial.rsp_func = rsp_send; + m_serial.payload_free_func = payload_free; + m_serial.mtu = UART_SLIP_MTU; + m_serial.p_rsp_buf = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP - + NRF_SERIAL_MAX_RESPONSE_SIZE]; + m_serial.p_low_level_transport = &uart_dfu_transport; + + nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG; + + uart_config.pseltxd = TX_PIN_NUMBER; + uart_config.pselrxd = RX_PIN_NUMBER; + uart_config.pselcts = CTS_PIN_NUMBER; + uart_config.pselrts = RTS_PIN_NUMBER; + uart_config.hwfc = NRF_UART_HWFC_ENABLED; + uart_config.p_context = &m_serial; + + nrf_gpio_cfg( + RTS_PIN_NUMBER, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); + + + nrf_gpio_pin_write(RTS_PIN_NUMBER, 0); + + err_code = nrf_drv_uart_init(&m_uart, &uart_config, uart_event_handler); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed initializing uart"); + return err_code; + } + + err_code = nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Failed initializing rx"); + } + + NRF_LOG_DEBUG("serial_dfu_transport_init() completed"); + + m_active = true; + + if (m_observer) + { + m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED); + } + + return err_code; +} + + +static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception) +{ + if ((m_active == true) && (p_exception != &uart_dfu_transport)) + { + nrf_drv_uart_uninit(&m_uart); + m_active = false; + } + + return NRF_SUCCESS; +} + diff --git a/core/embed/ble_bootloader/priv.pem b/core/embed/ble_bootloader/priv.pem new file mode 100644 index 000000000..a0bab98eb --- /dev/null +++ b/core/embed/ble_bootloader/priv.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIOSMfopjR9WnpAjLnog4xJG5XRVi5MfXk7bGGuxLanCAoAoGCCqGSM49 +AwEHoUQDQgAE9KQi8GEjC+sEphRRaW/GfnCfPJEaKY+oyAw/t0FUL37WzYQEfAos +6HnwYBqys9MYxWRJc0woWfaQGi5I+ptzrQ== +-----END EC PRIVATE KEY----- diff --git a/core/embed/ble_bootloader/sdk_config.h b/core/embed/ble_bootloader/sdk_config.h new file mode 100644 index 000000000..0757c6b77 --- /dev/null +++ b/core/embed/ble_bootloader/sdk_config.h @@ -0,0 +1,5307 @@ +// clang-format off + +/** + * Copyright (c) 2017 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +#ifndef SDK_CONFIG_H +#define SDK_CONFIG_H +// <<< Use Configuration Wizard in Context Menu >>>\n +#ifdef USE_APP_CONFIG +#include "app_config.h" +#endif +// nRF_Bootloader + +//========================================================== +// nrf_bootloader - Bootloader settings + +//========================================================== +// Application integrity checks + +//========================================================== +// NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 - Skip CRC integrity check of the application when bit 1 (0-indexed) is set in the GPREGRET2 register. + + +// Only CRC checks can be skipped. For other boot validation types, the GPREGRET2 register is ignored. + +#ifndef NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 +#define NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 1 +#endif + +// NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET - Skip integrity check of the application when waking up from the System Off state. + + +// Only CRC checks can be skipped. For other boot validation types, the reset state is ignored. + +#ifndef NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET +#define NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET 1 +#endif + +// NRF_BL_APP_SIGNATURE_CHECK_REQUIRED - Perform signature check on the app. Requires the signature to be sent in the init packet. + + +#ifndef NRF_BL_APP_SIGNATURE_CHECK_REQUIRED +#define NRF_BL_APP_SIGNATURE_CHECK_REQUIRED 1 +#endif + +// NRF_BL_DFU_ALLOW_UPDATE_FROM_APP - Whether to allow the app to receive firmware updates for the bootloader to activate. + + +// Enable this to allow the app to instruct the bootloader to activate firmware. +// The bootloader will do its own postvalidation. + +#ifndef NRF_BL_DFU_ALLOW_UPDATE_FROM_APP +#define NRF_BL_DFU_ALLOW_UPDATE_FROM_APP 0 +#endif + +// +//========================================================== + +// DFU mode enter method + +//========================================================== +// NRF_BL_DFU_ENTER_METHOD_BUTTON - Enter DFU mode on button press. +//========================================================== +#ifndef NRF_BL_DFU_ENTER_METHOD_BUTTON +#define NRF_BL_DFU_ENTER_METHOD_BUTTON 1 +#endif +// NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN - Button for entering DFU mode. + +// <0=> 0 (P0.0) +// <1=> 1 (P0.1) +// <2=> 2 (P0.2) +// <3=> 3 (P0.3) +// <4=> 4 (P0.4) +// <5=> 5 (P0.5) +// <6=> 6 (P0.6) +// <7=> 7 (P0.7) +// <8=> 8 (P0.8) +// <9=> 9 (P0.9) +// <10=> 10 (P0.10) +// <11=> 11 (P0.11) +// <12=> 12 (P0.12) +// <13=> 13 (P0.13) +// <14=> 14 (P0.14) +// <15=> 15 (P0.15) +// <16=> 16 (P0.16) +// <17=> 17 (P0.17) +// <18=> 18 (P0.18) +// <19=> 19 (P0.19) +// <20=> 20 (P0.20) +// <21=> 21 (P0.21) +// <22=> 22 (P0.22) +// <23=> 23 (P0.23) +// <24=> 24 (P0.24) +// <25=> 25 (P0.25) +// <26=> 26 (P0.26) +// <27=> 27 (P0.27) +// <28=> 28 (P0.28) +// <29=> 29 (P0.29) +// <30=> 30 (P0.30) +// <31=> 31 (P0.31) +// <32=> 32 (P1.0) +// <33=> 33 (P1.1) +// <34=> 34 (P1.2) +// <35=> 35 (P1.3) +// <36=> 36 (P1.4) +// <37=> 37 (P1.5) +// <38=> 38 (P1.6) +// <39=> 39 (P1.7) +// <40=> 40 (P1.8) +// <41=> 41 (P1.9) +// <42=> 42 (P1.10) +// <43=> 43 (P1.11) +// <44=> 44 (P1.12) +// <45=> 45 (P1.13) +// <46=> 46 (P1.14) +// <47=> 47 (P1.15) + +#ifndef NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN +#define NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN 40 +#endif + +// + +// NRF_BL_DFU_ENTER_METHOD_PINRESET - Enter DFU mode on pin reset. + + +#ifndef NRF_BL_DFU_ENTER_METHOD_PINRESET +#define NRF_BL_DFU_ENTER_METHOD_PINRESET 0 +#endif + +// NRF_BL_DFU_ENTER_METHOD_GPREGRET - Enter DFU mode when bit 0 is set in the NRF_POWER_GPREGRET register. + + +#ifndef NRF_BL_DFU_ENTER_METHOD_GPREGRET +#define NRF_BL_DFU_ENTER_METHOD_GPREGRET 1 +#endif + +// NRF_BL_DFU_ENTER_METHOD_BUTTONLESS - Enter DFU mode when the Boolean enter_buttonless_dfu in DFU settings is true. + + +#ifndef NRF_BL_DFU_ENTER_METHOD_BUTTONLESS +#define NRF_BL_DFU_ENTER_METHOD_BUTTONLESS 0 +#endif + +// +//========================================================== + +// DFU timers + +//========================================================== +// NRF_BL_DFU_CONTINUATION_TIMEOUT_MS - Timeout in ms when expecting an update immediately. <100-60000000> + + +// This timeout is used after updating the SoftDevice, when there is +// already a valid application present. The bootloader will enter DFU mode +// for a short time instead of booting the old application to allow the host +// to immediately transfer a new application if it wishes. + +#ifndef NRF_BL_DFU_CONTINUATION_TIMEOUT_MS +#define NRF_BL_DFU_CONTINUATION_TIMEOUT_MS 10000 +#endif + +// NRF_BL_DFU_INACTIVITY_TIMEOUT_MS - Timeout in ms before automatically starting a valid application due to inactivity. <0-60000000> + + +// If 0, no inactivity timer will be used. Values 1-99 are invalid. + +#ifndef NRF_BL_DFU_INACTIVITY_TIMEOUT_MS +#define NRF_BL_DFU_INACTIVITY_TIMEOUT_MS 120000 +#endif + +// +//========================================================== + +// Watchdog timer + +//========================================================== +// NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS - Maximum latency of the scheduler in miliseconds +// Maximum latency of the scheduler is compared with +// watchdog counter reload value (CRV). If latency is big +// enough, the watchdog will be fed from internal timer +// handler along with feed from user function. If latency +// is smaller than CRV, the watchdog will not be internally fed once +// it will be externally fed. Maximum latency is mainly affected +// by flash operations. + +#ifndef NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS +#define NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS 10000 +#endif + +// +//========================================================== + +// Misc Bootloader settings + +//========================================================== +// NRF_BL_DEBUG_PORT_DISABLE - Disable access to the chip via the debug port. + + +// Disable access to the chip via the debug port. +// This modifies the APPROTECT and DEBUGCTRL registers. +// Enable this option in production code if such +// access should be prohibited. Read about the registers +// for more details. + +#ifndef NRF_BL_DEBUG_PORT_DISABLE +#define NRF_BL_DEBUG_PORT_DISABLE 0 +#endif + +// NRF_BL_FW_COPY_PROGRESS_STORE_STEP - Number of pages copied after which progress in the settings page is updated. +// Progress stored in the settings page allows the bootloader to resume +// copying the new firmware in case of interruption (reset). +// If the value is small, then the resume point is more accurate. However, +// it also impacts negatively on flash wear. + +#ifndef NRF_BL_FW_COPY_PROGRESS_STORE_STEP +#define NRF_BL_FW_COPY_PROGRESS_STORE_STEP 8 +#endif + +// NRF_BL_RESET_DELAY_MS - Time to wait before resetting the bootloader. +// Time (in ms) to wait before resetting the bootloader after DFU has been completed or aborted. This allows more time for e.g. disconnecting the BLE link or writing logs. + +#ifndef NRF_BL_RESET_DELAY_MS +#define NRF_BL_RESET_DELAY_MS 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// +//========================================================== + +// nRF_Crypto + +//========================================================== +// NRF_CRYPTO_ENABLED - nrf_crypto - Cryptography library. +//========================================================== +#ifndef NRF_CRYPTO_ENABLED +#define NRF_CRYPTO_ENABLED 1 +#endif + +#ifndef NRF_CRYPTO_HASH_ENABLED +#define NRF_CRYPTO_HASH_ENABLED 1 +#endif + +// NRF_CRYPTO_ALLOCATOR - Memory allocator + + +// Choose memory allocator used by nrf_crypto. Default is alloca if possible or nrf_malloc otherwise. If 'User macros' are selected, the user has to create 'nrf_crypto_allocator.h' file that contains NRF_CRYPTO_ALLOC, NRF_CRYPTO_FREE, and NRF_CRYPTO_ALLOC_ON_STACK. +// <0=> Default +// <1=> User macros +// <2=> On stack (alloca) +// <3=> C dynamic memory (malloc) +// <4=> SDK Memory Manager (nrf_malloc) + +#ifndef NRF_CRYPTO_ALLOCATOR +#define NRF_CRYPTO_ALLOCATOR 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_ENABLED - Enable the ARM Cryptocell CC310 reduced backend. + +// The CC310 hardware-accelerated cryptography backend with reduced functionality and footprint (only available on nRF52840). +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED - Enable the secp224r1 elliptic curve support using CC310_BL. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED - Enable the secp256r1 elliptic curve support using CC310_BL. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED - CC310_BL SHA-256 hash functionality. + + +// CC310_BL backend implementation for hardware-accelerated SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED - nrf_cc310_bl buffers to RAM before running hash operation + + +// Enabling this makes hashing of addresses in FLASH range possible. Size of buffer allocated for hashing is set by NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE - nrf_cc310_bl hash outputs digests in little endian +// Makes the nrf_cc310_bl hash functions output digests in little endian format. Only for use in nRF SDK DFU! + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE +#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE 4096 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED - Enable Interrupts while support using CC310 bl. + + +// Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_CC310_ENABLED - Enable the ARM Cryptocell CC310 backend. + +// The CC310 hardware-accelerated cryptography backend (only available on nRF52840). +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_CC310_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED - Enable the AES CBC mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED - Enable the AES CTR mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED - Enable the AES ECB mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED - Enable the AES CBC_MAC mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED - Enable the AES CMAC mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED - Enable the AES CCM mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED - Enable the AES CCM* mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED - Enable the CHACHA-POLY mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED - Enable the secp160r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED - Enable the secp160r2 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED - Enable the secp192r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED - Enable the secp224r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED - Enable the secp256r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED - Enable the secp384r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED - Enable the secp521r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED - Enable the secp160k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED - Enable the secp192k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED - Enable the secp224k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED - Enable the secp256k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED - Enable the Curve25519 curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED - Enable the Ed25519 curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED - CC310 SHA-256 hash functionality. + + +// CC310 backend implementation for hardware-accelerated SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED - CC310 SHA-512 hash functionality + + +// CC310 backend implementation for SHA-512 (in software). + +#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED - CC310 HMAC using SHA-256 + + +// CC310 backend implementation for HMAC using hardware-accelerated SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED - CC310 HMAC using SHA-512 + + +// CC310 backend implementation for HMAC using SHA-512 (in software). + +#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED - Enable RNG support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED - Enable Interrupts while support using CC310. + + +// Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used + +#ifndef NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_CIFRA_ENABLED - Enable the Cifra backend. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_CIFRA_ENABLED +#define NRF_CRYPTO_BACKEND_CIFRA_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED - Enable the AES EAX mode using Cifra. + + +#ifndef NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED +#define NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED - Enable the mbed TLS backend. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED - Enable the AES CBC mode mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED - Enable the AES CTR mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED - Enable the AES CFB mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED - Enable the AES ECB mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED - Enable the AES CBC MAC mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED - Enable the AES CMAC mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED - Enable the AES CCM mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED - Enable the AES GCM mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED - Enable secp192r1 (NIST 192-bit) curve + + +// Enable this setting if you need secp192r1 (NIST 192-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED - Enable secp224r1 (NIST 224-bit) curve + + +// Enable this setting if you need secp224r1 (NIST 224-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED - Enable secp256r1 (NIST 256-bit) curve + + +// Enable this setting if you need secp256r1 (NIST 256-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED - Enable secp384r1 (NIST 384-bit) curve + + +// Enable this setting if you need secp384r1 (NIST 384-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED - Enable secp521r1 (NIST 521-bit) curve + + +// Enable this setting if you need secp521r1 (NIST 521-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED - Enable secp192k1 (Koblitz 192-bit) curve + + +// Enable this setting if you need secp192k1 (Koblitz 192-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED - Enable secp224k1 (Koblitz 224-bit) curve + + +// Enable this setting if you need secp224k1 (Koblitz 224-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED - Enable secp256k1 (Koblitz 256-bit) curve + + +// Enable this setting if you need secp256k1 (Koblitz 256-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED - Enable bp256r1 (Brainpool 256-bit) curve + + +// Enable this setting if you need bp256r1 (Brainpool 256-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED - Enable bp384r1 (Brainpool 384-bit) curve + + +// Enable this setting if you need bp384r1 (Brainpool 384-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED - Enable bp512r1 (Brainpool 512-bit) curve + + +// Enable this setting if you need bp512r1 (Brainpool 512-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED - Enable Curve25519 curve + + +// Enable this setting if you need Curve25519 support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED - Enable mbed TLS SHA-256 hash functionality. + + +// mbed TLS backend implementation for SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED - Enable mbed TLS SHA-512 hash functionality. + + +// mbed TLS backend implementation for SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED - Enable mbed TLS HMAC using SHA-256. + + +// mbed TLS backend implementation for HMAC using SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED - Enable mbed TLS HMAC using SHA-512. + + +// mbed TLS backend implementation for HMAC using SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED - Enable the micro-ecc backend. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED 1 +#endif +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED - Enable secp192r1 (NIST 192-bit) curve + + +// Enable this setting if you need secp192r1 (NIST 192-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED - Enable secp224r1 (NIST 224-bit) curve + + +// Enable this setting if you need secp224r1 (NIST 224-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED - Enable secp256r1 (NIST 256-bit) curve + + +// Enable this setting if you need secp256r1 (NIST 256-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED - Enable secp256k1 (Koblitz 256-bit) curve + + +// Enable this setting if you need secp256k1 (Koblitz 256-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED - Enable the nRF HW RNG backend. + +// The nRF HW backend provide access to RNG peripheral in nRF5x devices. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED - Enable mbed TLS CTR-DRBG algorithm. + + +// Enable mbed TLS CTR-DRBG standardized by NIST (NIST SP 800-90A Rev. 1). The nRF HW RNG is used as an entropy source for seeding. + +#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_NRF_SW_ENABLED - Enable the legacy nRFx sw for crypto. + +// The nRF SW cryptography backend (only used in bootloader context). +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_NRF_SW_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_SW_ENABLED 1 +#endif +// NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED - nRF SW hash backend support for SHA-256 + + +// The nRF SW backend provide access to nRF SDK legacy hash implementation of SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_OBERON_ENABLED - Enable the Oberon backend + +// The Oberon backend +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_OBERON_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED - Enable the CHACHA-POLY mode using Oberon. + + +#ifndef NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED - Enable secp256r1 curve + + +// Enable this setting if you need secp256r1 curve support using Oberon library + +#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED - Enable Curve25519 ECDH + + +// Enable this setting if you need Curve25519 ECDH support using Oberon library + +#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED - Enable Ed25519 signature scheme + + +// Enable this setting if you need Ed25519 support using Oberon library + +#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED - Oberon SHA-256 hash functionality + + +// Oberon backend implementation for SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED - Oberon SHA-512 hash functionality + + +// Oberon backend implementation for SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED - Oberon HMAC using SHA-256 + + +// Oberon backend implementation for HMAC using SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED - Oberon HMAC using SHA-512 + + +// Oberon backend implementation for HMAC using SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED 0 +#endif + +// + +// NRF_CRYPTO_BACKEND_OPTIGA_ENABLED - Enable the nrf_crypto Optiga Trust X backend. + +// Enables the nrf_crypto backend for Optiga Trust X devices. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ENABLED +#define NRF_CRYPTO_BACKEND_OPTIGA_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED - Optiga backend support for RNG + + +// The Optiga backend provide external chip RNG. + +#ifndef NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED +#define NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED - Optiga backend support for ECC secp256r1 + + +// The Optiga backend provide external chip ECC using secp256r1. + +#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED - Big-endian byte order in raw Curve25519 data + + +// Enable big-endian byte order in Curve25519 API, if set to 1. Use little-endian, if set to 0. + +#ifndef NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED +#define NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED 0 +#endif + +// + +// nrf_crypto_rng - RNG Configuration + +//========================================================== +// NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED - Use static memory buffers for context and temporary init buffer. + + +// Always recommended when using the nRF HW RNG as the context and temporary buffers are small. Consider disabling if using the CC310 RNG in a RAM constrained application. In this case, memory must be provided to nrf_crypto_rng_init, or it can be allocated internally provided that NRF_CRYPTO_ALLOCATOR does not allocate memory on the stack. + +#ifndef NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED +#define NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED 1 +#endif + +// NRF_CRYPTO_RNG_AUTO_INIT_ENABLED - Initialize the RNG module automatically when nrf_crypto is initialized. + + +// Automatic initialization is only supported with static or internally allocated context and temporary memory. + +#ifndef NRF_CRYPTO_RNG_AUTO_INIT_ENABLED +#define NRF_CRYPTO_RNG_AUTO_INIT_ENABLED 1 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_DFU + +//========================================================== +// DFU security - nrf_dfu_validation - DFU validation + +//========================================================== +// NRF_DFU_APP_ACCEPT_SAME_VERSION - Whether to accept application upgrades with the same version as the current application. + + +// This applies to application updates, and possibly to SoftDevice updates. +// Bootloader upgrades always require higher versions. SoftDevice upgrades +// look at the sd_req field independently of this config. +// Disabling this protects against replay attacks wearing out the flash of the device. +// This config only has an effect when NRF_DFU_APP_DOWNGRADE_PREVENTION is enabled. + +#ifndef NRF_DFU_APP_ACCEPT_SAME_VERSION +#define NRF_DFU_APP_ACCEPT_SAME_VERSION 1 +#endif + +// NRF_DFU_APP_DOWNGRADE_PREVENTION - Check the firmware version and SoftDevice requirements of application (and SoftDevice) updates. + + +// Whether to check the incoming version against the version of the existing app and/or +// the incoming SoftDevice requirements against the existing SoftDevice. +// This applies to application updates, and possibly to SoftDevice updates. +// Disabling this causes the checks to always ignore the incoming firmware version and +// to ignore the SoftDevice requirements if the first requirement is 0. +// This does not apply the bootloader updates. If the bootloader depends on the SoftDevice +// e.g. for BLE transport, this does not apply to SoftDevice updates. +// See @ref lib_bootloader_dfu_validation for more information. +// When signed updates are required, version checking should always be enabled. + +#ifndef NRF_DFU_APP_DOWNGRADE_PREVENTION +#define NRF_DFU_APP_DOWNGRADE_PREVENTION 1 +#endif + +// NRF_DFU_EXTERNAL_APP_VERSIONING - Require versioning for external applications. + + +// This configuration is only used if NRF_DFU_SUPPORTS_EXTERNAL_APP is set to 1. +// Setting this will require that any FW images using the FW upgrade type +// DFU_FW_TYPE_EXTERNAL_APPLICATION must follow a monotonic versioning scheme +// where the FW version of an upgrade must always be larger than the previously stored +// FW version. + +#ifndef NRF_DFU_EXTERNAL_APP_VERSIONING +#define NRF_DFU_EXTERNAL_APP_VERSIONING 1 +#endif + +// NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES - Accept only dual-bank application updates. + + +// If not enabled then if there is not enough space to perform dual-bank update +// application is deleted and single-bank update is performed. In case it is considered +// security concern user can prefer to discard update request rather than overwrite +// current application. + +#ifndef NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES +#define NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES 0 +#endif + +// NRF_DFU_HW_VERSION - Device hardware version. +// This is used to determine if given update is targeting the device. +// It is checked against the hw_version value in the init packet + +#ifndef NRF_DFU_HW_VERSION +#define NRF_DFU_HW_VERSION 52 +#endif + +// NRF_DFU_REQUIRE_SIGNED_APP_UPDATE - Require a valid signature to update the application or SoftDevice. + + +#ifndef NRF_DFU_REQUIRE_SIGNED_APP_UPDATE +#define NRF_DFU_REQUIRE_SIGNED_APP_UPDATE 1 +#endif + +// NRF_DFU_SINGLE_BANK_APP_UPDATES - Place the application and the SoftDevice directly where they are supposed to be. + + +// Note that this creates security concerns when signing and version checks +// are enabled. An attacker will be able to delete (but not replace) +// the current app or SoftDevice without knowing the signature key. + +#ifndef NRF_DFU_SINGLE_BANK_APP_UPDATES +#define NRF_DFU_SINGLE_BANK_APP_UPDATES 0 +#endif + +// +//========================================================== + +// NRF_DFU_SETTINGS_COMPATIBILITY_MODE - nrf_dfu_settings - DFU Settings + + +#ifndef NRF_DFU_SETTINGS_COMPATIBILITY_MODE +#define NRF_DFU_SETTINGS_COMPATIBILITY_MODE 1 +#endif + +// nrf_dfu - Device Firmware Upgrade + +//========================================================== +// DFU transport + +//========================================================== +// NRF_DFU_TRANSPORT_ANT - ANT transport settings +//========================================================== +#ifndef NRF_DFU_TRANSPORT_ANT +#define NRF_DFU_TRANSPORT_ANT 0 +#endif +// NRF_DFU_ANT_MTU - MTU size used for firmware bursts. +// Sets the maximum burst size used for DFU write commands. + +#ifndef NRF_DFU_ANT_MTU +#define NRF_DFU_ANT_MTU 1024 +#endif + +// ANT DFU buffers + +//========================================================== +// NRF_DFU_ANT_BUFFERS_OVERRIDE + +// Check this option to override the default number of buffers. +//========================================================== +#ifndef NRF_DFU_ANT_BUFFERS_OVERRIDE +#define NRF_DFU_ANT_BUFFERS_OVERRIDE 0 +#endif +// NRF_DFU_ANT_BUFFERS - Number of buffers in the ANT transport. +// Number of buffers to store incoming data while it is being written to flash. +// Reduce this value to save RAM. If this value is too low, the DFU process will fail. + +#ifndef NRF_DFU_ANT_BUFFERS +#define NRF_DFU_ANT_BUFFERS 8 +#endif + +// + +// +//========================================================== + +// ANT DFU Channel Configuration + +//========================================================== +// NRF_DFU_ANT_RF_FREQ - DFU RF channel. +#ifndef NRF_DFU_ANT_RF_FREQ +#define NRF_DFU_ANT_RF_FREQ 66 +#endif + +// NRF_DFU_ANT_DEV_TYPE - Device type field to use for DFU channel id. +#ifndef NRF_DFU_ANT_DEV_TYPE +#define NRF_DFU_ANT_DEV_TYPE 10 +#endif + +// NRF_DFU_ANT_CHANNEL_PERIOD - Channel period of DFU ANT channel. +#ifndef NRF_DFU_ANT_CHANNEL_PERIOD +#define NRF_DFU_ANT_CHANNEL_PERIOD 2048 +#endif + +// +//========================================================== + +// + +// NRF_DFU_TRANSPORT_BLE - BLE transport settings +//========================================================== +#ifndef NRF_DFU_TRANSPORT_BLE +#define NRF_DFU_TRANSPORT_BLE 0 +#endif +// NRF_DFU_BLE_SKIP_SD_INIT - Skip the SoftDevice and interrupt vector table initialization. + + +#ifndef NRF_DFU_BLE_SKIP_SD_INIT +#define NRF_DFU_BLE_SKIP_SD_INIT 0 +#endif + +// NRF_DFU_BLE_ADV_NAME - Default advertising name. +#ifndef NRF_DFU_BLE_ADV_NAME +#define NRF_DFU_BLE_ADV_NAME "DfuTarg" +#endif + +// NRF_DFU_BLE_ADV_INTERVAL - Advertising interval (in units of 0.625 ms) +#ifndef NRF_DFU_BLE_ADV_INTERVAL +#define NRF_DFU_BLE_ADV_INTERVAL 40 +#endif + +// BLE DFU security + +//========================================================== +// NRF_DFU_BLE_REQUIRES_BONDS - Require bond with peer. + + +#ifndef NRF_DFU_BLE_REQUIRES_BONDS +#define NRF_DFU_BLE_REQUIRES_BONDS 0 +#endif + +// +//========================================================== + +// BLE DFU connection + +//========================================================== +// NRF_DFU_BLE_MIN_CONN_INTERVAL - Minimum connection interval (units). +// Minimum GAP connection interval, in 1.25 ms units. + +#ifndef NRF_DFU_BLE_MIN_CONN_INTERVAL +#define NRF_DFU_BLE_MIN_CONN_INTERVAL 12 +#endif + +// NRF_DFU_BLE_MAX_CONN_INTERVAL - Maximum connection interval (units). +// Maximum GAP connection interval, in 1.25 ms units. + +#ifndef NRF_DFU_BLE_MAX_CONN_INTERVAL +#define NRF_DFU_BLE_MAX_CONN_INTERVAL 12 +#endif + +// NRF_DFU_BLE_CONN_SUP_TIMEOUT_MS - Supervision timeout (ms). +// GAP connection supervision timeout, in milliseconds. + +#ifndef NRF_DFU_BLE_CONN_SUP_TIMEOUT_MS +#define NRF_DFU_BLE_CONN_SUP_TIMEOUT_MS 6000 +#endif + +// +//========================================================== + +// BLE DFU buffers + +//========================================================== +// NRF_DFU_BLE_BUFFERS_OVERRIDE + +// Check this option to override the default number of buffers. +//========================================================== +#ifndef NRF_DFU_BLE_BUFFERS_OVERRIDE +#define NRF_DFU_BLE_BUFFERS_OVERRIDE 0 +#endif +// NRF_DFU_BLE_BUFFERS - Number of buffers in the BLE transport. +// Number of buffers to store incoming data while it is being written to flash. +// Reduce this value to save RAM. If this value is too low, the DFU process will fail. + +#ifndef NRF_DFU_BLE_BUFFERS +#define NRF_DFU_BLE_BUFFERS 8 +#endif + +// + +// +//========================================================== + +// + +// +//========================================================== + +// DFU protocol + +//========================================================== +// NRF_DFU_PROTOCOL_FW_VERSION_MSG - Firmware version message support. + + +// Firmware version message support. +// If disabled, firmware version requests will return NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED. + +#ifndef NRF_DFU_PROTOCOL_FW_VERSION_MSG +#define NRF_DFU_PROTOCOL_FW_VERSION_MSG 1 +#endif + +// NRF_DFU_PROTOCOL_REDUCED - Reduced protocol opcode selection. + + +// Only support a minimal set of opcodes; return NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED +// for unsupported opcodes. The supported opcodes are:NRF_DFU_OP_OBJECT_CREATE, +// NRF_DFU_OP_OBJECT_EXECUTE, NRF_DFU_OP_OBJECT_SELECT, NRF_DFU_OP_OBJECT_WRITE, +// NRF_DFU_OP_CRC_GET, NRF_DFU_OP_RECEIPT_NOTIF_SET, and NRF_DFU_OP_ABORT. +// This reduced feature set is used by the BLE transport to reduce flash usage. + +#ifndef NRF_DFU_PROTOCOL_REDUCED +#define NRF_DFU_PROTOCOL_REDUCED 0 +#endif + +// NRF_DFU_PROTOCOL_VERSION_MSG - Protocol version message support. + + +// Protocol version message support. +// If disabled, protocol version requests will return NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED. + +#ifndef NRF_DFU_PROTOCOL_VERSION_MSG +#define NRF_DFU_PROTOCOL_VERSION_MSG 1 +#endif + +// +//========================================================== + +// Misc DFU settings + +//========================================================== +// NRF_DFU_APP_DATA_AREA_SIZE - The size (in bytes) of the flash area reserved for application data. +// This area is found at the end of the application area, next to the start of +// the bootloader. This area will not be erased by the bootloader during a +// firmware upgrade. The size must be a multiple of the flash page size. + +#ifndef NRF_DFU_APP_DATA_AREA_SIZE +#define NRF_DFU_APP_DATA_AREA_SIZE 12288 +#endif + +// NRF_DFU_IN_APP - Specifies that this code is in the app, not the bootloader, so some settings are off-limits. + + +// Enable this to disable writing to areas of the settings that are protected +// by the bootlader. If this is not enabled in the app, certain settings write +// operations will cause HardFaults or will be ignored. Enabling this option +// also causes postvalidation to be disabled since this is meant to be done +// in the bootloader. NRF_BL_DFU_ALLOW_UPDATE_FROM_APP must be enabled in the bootloader. + +#ifndef NRF_DFU_IN_APP +#define NRF_DFU_IN_APP 0 +#endif + +// NRF_DFU_SAVE_PROGRESS_IN_FLASH - Save DFU progress in flash. + + +// Save DFU progress to flash so that it can be resumed if interrupted, instead of being restarted. +// Keep this setting disabled to maximize transfer speed and minimize flash wear. +// The init packet is always saved in flash, regardless of this setting. + +#ifndef NRF_DFU_SAVE_PROGRESS_IN_FLASH +#define NRF_DFU_SAVE_PROGRESS_IN_FLASH 0 +#endif + +// NRF_DFU_SUPPORTS_EXTERNAL_APP - [Experimental] Support for external app. + + +// External apps are apps that will not be activated. They can +// e.g. be apps to be sent to a third party. External app updates +// are verified upon reception, but will remain in bank 1, and +// will never be booted. An external app will be overwritten if +// a new DFU procedure is performed. Note: This functionality is +// experimental and not yet used in any examples. + +#ifndef NRF_DFU_SUPPORTS_EXTERNAL_APP +#define NRF_DFU_SUPPORTS_EXTERNAL_APP 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nrf_dfu_serial_uart - UART DFU transport + +//========================================================== +// NRF_DFU_SERIAL_UART_USES_HWFC - HWFC configuration + + +#ifndef NRF_DFU_SERIAL_UART_USES_HWFC +#define NRF_DFU_SERIAL_UART_USES_HWFC 1 +#endif + +// NRF_DFU_SERIAL_UART_RX_BUFFERS - Number of RX buffers. +// Number of buffers depends on flash access vs. +// transport throughtput. If value is too low it may lead +// to received packets being dropped. + +#ifndef NRF_DFU_SERIAL_UART_RX_BUFFERS +#define NRF_DFU_SERIAL_UART_RX_BUFFERS 10 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_Drivers + +//========================================================== +// NRFX_PRS_ENABLED - nrfx_prs - Peripheral Resource Sharing module +//========================================================== +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 1 +#endif +// NRFX_PRS_BOX_0_ENABLED - Enables box 0 in the module. + + +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +// NRFX_PRS_BOX_1_ENABLED - Enables box 1 in the module. + + +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +// NRFX_PRS_BOX_2_ENABLED - Enables box 2 in the module. + + +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +// NRFX_PRS_BOX_3_ENABLED - Enables box 3 in the module. + + +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +// NRFX_PRS_BOX_4_ENABLED - Enables box 4 in the module. + + +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 1 +#endif + +// NRFX_PRS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_PRS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_PRS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PRS_CONFIG_INFO_COLOR +#define NRFX_PRS_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_PRS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PRS_CONFIG_DEBUG_COLOR +#define NRFX_PRS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver +//========================================================== +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 1 +#endif +// NRFX_UARTE0_ENABLED - Enable UARTE0 instance +#ifndef NRFX_UARTE0_ENABLED +#define NRFX_UARTE0_ENABLED 0 +#endif + +// NRFX_UARTE1_ENABLED - Enable UARTE1 instance +#ifndef NRFX_UARTE1_ENABLED +#define NRFX_UARTE1_ENABLED 0 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_HWFC +#define NRFX_UARTE_DEFAULT_CONFIG_HWFC 1 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_PARITY +#define NRFX_UARTE_DEFAULT_CONFIG_PARITY 0 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <8388608=> 31250 baud +// <10289152=> 38400 baud +// <15007744=> 56000 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE +#define NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE 30801920 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_UARTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_UARTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_UARTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UARTE_CONFIG_INFO_COLOR +#define NRFX_UARTE_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_UARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UARTE_CONFIG_DEBUG_COLOR +#define NRFX_UARTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_UART_ENABLED - nrfx_uart - UART peripheral driver +//========================================================== +#ifndef NRFX_UART_ENABLED +#define NRFX_UART_ENABLED 1 +#endif +// NRFX_UART0_ENABLED - Enable UART0 instance +#ifndef NRFX_UART0_ENABLED +#define NRFX_UART0_ENABLED 0 +#endif + +// NRFX_UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef NRFX_UART_DEFAULT_CONFIG_HWFC +#define NRFX_UART_DEFAULT_CONFIG_HWFC 0 +#endif + +// NRFX_UART_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef NRFX_UART_DEFAULT_CONFIG_PARITY +#define NRFX_UART_DEFAULT_CONFIG_PARITY 0 +#endif + +// NRFX_UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3866624=> 14400 baud +// <5152768=> 19200 baud +// <7729152=> 28800 baud +// <8388608=> 31250 baud +// <10309632=> 38400 baud +// <15007744=> 56000 baud +// <15462400=> 57600 baud +// <20615168=> 76800 baud +// <30924800=> 115200 baud +// <61845504=> 230400 baud +// <67108864=> 250000 baud +// <123695104=> 460800 baud +// <247386112=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef NRFX_UART_DEFAULT_CONFIG_BAUDRATE +#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE 268435456 +#endif + +// NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_UART_CONFIG_LOG_ENABLED +#define NRFX_UART_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_UART_CONFIG_LOG_LEVEL +#define NRFX_UART_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UART_CONFIG_INFO_COLOR +#define NRFX_UART_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UART_CONFIG_DEBUG_COLOR +#define NRFX_UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer +//========================================================== +#ifndef UART_ENABLED +#define UART_ENABLED 1 +#endif +// UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef UART_DEFAULT_CONFIG_HWFC +#define UART_DEFAULT_CONFIG_HWFC 1 +#endif + +// UART_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef UART_DEFAULT_CONFIG_PARITY +#define UART_DEFAULT_CONFIG_PARITY 0 +#endif + +// UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef UART_DEFAULT_CONFIG_BAUDRATE +#define UART_DEFAULT_CONFIG_BAUDRATE 268435456 +#endif + +// UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY +#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA + + +#ifndef UART_EASY_DMA_SUPPORT +#define UART_EASY_DMA_SUPPORT 1 +#endif + +// UART_LEGACY_SUPPORT - Driver supporting Legacy mode + + +#ifndef UART_LEGACY_SUPPORT +#define UART_LEGACY_SUPPORT 0 +#endif + +// UART0_ENABLED - Enable UART0 instance +//========================================================== +#ifndef UART0_ENABLED +#define UART0_ENABLED 1 +#endif +// UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA + + +#ifndef UART0_CONFIG_USE_EASY_DMA +#define UART0_CONFIG_USE_EASY_DMA 1 +#endif + +// + +// UART1_ENABLED - Enable UART1 instance +//========================================================== +#ifndef UART1_ENABLED +#define UART1_ENABLED 0 +#endif +// + +// + +// +//========================================================== + +// nRF_Libraries + +//========================================================== +// APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler +//========================================================== +#ifndef APP_SCHEDULER_ENABLED +#define APP_SCHEDULER_ENABLED 1 +#endif +// APP_SCHEDULER_WITH_PAUSE - Enabling pause feature + + +#ifndef APP_SCHEDULER_WITH_PAUSE +#define APP_SCHEDULER_WITH_PAUSE 0 +#endif + +// APP_SCHEDULER_WITH_PROFILER - Enabling scheduler profiling + + +#ifndef APP_SCHEDULER_WITH_PROFILER +#define APP_SCHEDULER_WITH_PROFILER 0 +#endif + +// + +// CRC32_ENABLED - crc32 - CRC32 calculation routines + + +#ifndef CRC32_ENABLED +#define CRC32_ENABLED 1 +#endif + +// MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator +//========================================================== +#ifndef MEM_MANAGER_ENABLED +#define MEM_MANAGER_ENABLED 1 +#endif +// MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block. <0-255> + + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT +#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1 +#endif + +// MEMORY_MANAGER_SMALL_BLOCK_SIZE - Size of each memory blocks identified as 'small' block. +// Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE +#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block. <0-255> + + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT +#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_SIZE - Size of each memory blocks identified as 'medium' block. +// Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE +#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block. <0-255> + + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT +#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_SIZE - Size of each memory blocks identified as 'large' block. +// Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE +#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_XLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra large' block. <0-255> + + +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT +#define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XLARGE_BLOCK_SIZE - Size of each memory blocks identified as 'extra large' block. +// Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_SIZE +#define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 1320 +#endif + +// MEMORY_MANAGER_XXLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra large' block. <0-255> + + +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT +#define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XXLARGE_BLOCK_SIZE - Size of each memory blocks identified as 'extra extra large' block. +// Size of each memory blocks identified as 'extra extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_SIZE +#define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 3444 +#endif + +// MEMORY_MANAGER_XSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra small' block. <0-255> + + +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT +#define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XSMALL_BLOCK_SIZE - Size of each memory blocks identified as 'extra small' block. +// Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_SIZE +#define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 64 +#endif + +// MEMORY_MANAGER_XXSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra small' block. <0-255> + + +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT +#define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XXSMALL_BLOCK_SIZE - Size of each memory blocks identified as 'extra extra small' block. +// Size of each memory blocks identified as 'extra extra small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_SIZE +#define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 32 +#endif + +// MEM_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef MEM_MANAGER_CONFIG_LOG_ENABLED +#define MEM_MANAGER_CONFIG_LOG_ENABLED 0 +#endif +// MEM_MANAGER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef MEM_MANAGER_CONFIG_LOG_LEVEL +#define MEM_MANAGER_CONFIG_LOG_LEVEL 3 +#endif + +// MEM_MANAGER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MEM_MANAGER_CONFIG_INFO_COLOR +#define MEM_MANAGER_CONFIG_INFO_COLOR 0 +#endif + +// MEM_MANAGER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MEM_MANAGER_CONFIG_DEBUG_COLOR +#define MEM_MANAGER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// MEM_MANAGER_DISABLE_API_PARAM_CHECK - Disable API parameter checks in the module. + + +#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK +#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0 +#endif + +// + +// NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module +//========================================================== +#ifndef NRF_BALLOC_ENABLED +#define NRF_BALLOC_ENABLED 1 +#endif +// NRF_BALLOC_CONFIG_DEBUG_ENABLED - Enables debug mode in the module. +//========================================================== +#ifndef NRF_BALLOC_CONFIG_DEBUG_ENABLED +#define NRF_BALLOC_CONFIG_DEBUG_ENABLED 0 +#endif +// NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS - Number of words used as head guard. <0-255> + + +#ifndef NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS +#define NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS 1 +#endif + +// NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS - Number of words used as tail guard. <0-255> + + +#ifndef NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS +#define NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS 1 +#endif + +// NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED - Enables basic checks in this module. + + +#ifndef NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED +#define NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED 0 +#endif + +// NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED - Enables double memory free check in this module. + + +#ifndef NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED +#define NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED 0 +#endif + +// NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED - Enables free memory corruption check in this module. + + +#ifndef NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED +#define NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED 0 +#endif + +// NRF_BALLOC_CLI_CMDS - Enable CLI commands specific to the module + + +#ifndef NRF_BALLOC_CLI_CMDS +#define NRF_BALLOC_CLI_CMDS 0 +#endif + +// + +// + +// NRF_FSTORAGE_ENABLED - nrf_fstorage - Flash abstraction library +//========================================================== +#ifndef NRF_FSTORAGE_ENABLED +#define NRF_FSTORAGE_ENABLED 1 +#endif +// nrf_fstorage - Common settings + +// Common settings to all fstorage implementations +//========================================================== +// NRF_FSTORAGE_PARAM_CHECK_DISABLED - Disable user input validation + + +// If selected, use ASSERT to validate user input. +// This effectively removes user input validation in production code. +// Recommended setting: OFF, only enable this setting if size is a major concern. + +#ifndef NRF_FSTORAGE_PARAM_CHECK_DISABLED +#define NRF_FSTORAGE_PARAM_CHECK_DISABLED 1 +#endif + +// +//========================================================== + +// nrf_fstorage_sd - Implementation using the SoftDevice + +// Configuration options for the fstorage implementation using the SoftDevice +//========================================================== +// NRF_FSTORAGE_SD_QUEUE_SIZE - Size of the internal queue of operations +// Increase this value if API calls frequently return the error @ref NRF_ERROR_NO_MEM. + +#ifndef NRF_FSTORAGE_SD_QUEUE_SIZE +#define NRF_FSTORAGE_SD_QUEUE_SIZE 16 +#endif + +// NRF_FSTORAGE_SD_MAX_RETRIES - Maximum number of attempts at executing an operation when the SoftDevice is busy +// Increase this value if events frequently return the @ref NRF_ERROR_TIMEOUT error. +// The SoftDevice might fail to schedule flash access due to high BLE activity. + +#ifndef NRF_FSTORAGE_SD_MAX_RETRIES +#define NRF_FSTORAGE_SD_MAX_RETRIES 8 +#endif + +// NRF_FSTORAGE_SD_MAX_WRITE_SIZE - Maximum number of bytes to be written to flash in a single operation +// This value must be a multiple of four. +// Lowering this value can increase the chances of the SoftDevice being able to execute flash operations in between radio activity. +// This value is bound by the maximum number of bytes that can be written to flash in a single call to @ref sd_flash_write. +// That is 1024 bytes for nRF51 ICs and 4096 bytes for nRF52 ICs. + +#ifndef NRF_FSTORAGE_SD_MAX_WRITE_SIZE +#define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 20 +#endif + +// +//========================================================== + +// + +// NRF_MEMOBJ_ENABLED - nrf_memobj - Linked memory allocator module + + +#ifndef NRF_MEMOBJ_ENABLED +#define NRF_MEMOBJ_ENABLED 1 +#endif + +// NRF_QUEUE_ENABLED - nrf_queue - Queue module +//========================================================== +#ifndef NRF_QUEUE_ENABLED +#define NRF_QUEUE_ENABLED 0 +#endif +// NRF_QUEUE_CLI_CMDS - Enable CLI commands specific to the module + + +#ifndef NRF_QUEUE_CLI_CMDS +#define NRF_QUEUE_CLI_CMDS 0 +#endif + +// + +// NRF_STRERROR_ENABLED - nrf_strerror - Library for converting error code to string. + + +#ifndef NRF_STRERROR_ENABLED +#define NRF_STRERROR_ENABLED 1 +#endif + +// SLIP_ENABLED - slip - SLIP encoding and decoding + + +#ifndef SLIP_ENABLED +#define SLIP_ENABLED 1 +#endif + +// nrf_fprintf - fprintf function. + +//========================================================== +// NRF_FPRINTF_ENABLED - Enable/disable fprintf module. + + +#ifndef NRF_FPRINTF_ENABLED +#define NRF_FPRINTF_ENABLED 1 +#endif + +// NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED - For each printed LF, function will add CR. + + +#ifndef NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED +#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1 +#endif + +// NRF_FPRINTF_DOUBLE_ENABLED - Enable IEEE-754 double precision formatting. + + +#ifndef NRF_FPRINTF_DOUBLE_ENABLED +#define NRF_FPRINTF_DOUBLE_ENABLED 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_Log +#ifdef DEBUG_NRF +//========================================================== +// NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend +//========================================================== +#ifndef NRF_LOG_BACKEND_RTT_ENABLED +#define NRF_LOG_BACKEND_RTT_ENABLED 1 +#endif +// NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings. +// Size of the buffer is a trade-off between RAM usage and processing. +// if buffer is smaller then strings will often be fragmented. +// It is recommended to use size which will fit typical log and only the +// longer one will be fragmented. + +#ifndef NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE +#define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64 +#endif + +// NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS - Period before retrying writing to RTT +#ifndef NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS +#define NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS 1 +#endif + +// NRF_LOG_BACKEND_RTT_TX_RETRY_CNT - Writing to RTT retries. +// If RTT fails to accept any new data after retries +// module assumes that host is not active and on next +// request it will perform only one write attempt. +// On successful writing, module assumes that host is active +// and scheme with retry is applied again. + +#ifndef NRF_LOG_BACKEND_RTT_TX_RETRY_CNT +#define NRF_LOG_BACKEND_RTT_TX_RETRY_CNT 3 +#endif + +// + +// NRF_LOG_BACKEND_UART_ENABLED - nrf_log_backend_uart - Log UART backend +//========================================================== +#ifndef NRF_LOG_BACKEND_UART_ENABLED +#define NRF_LOG_BACKEND_UART_ENABLED 0 +#endif +// NRF_LOG_BACKEND_UART_TX_PIN - UART TX pin +#ifndef NRF_LOG_BACKEND_UART_TX_PIN +#define NRF_LOG_BACKEND_UART_TX_PIN 6 +#endif + +// NRF_LOG_BACKEND_UART_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef NRF_LOG_BACKEND_UART_BAUDRATE +#define NRF_LOG_BACKEND_UART_BAUDRATE 30801920 +#endif + +// NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings. +// Size of the buffer is a trade-off between RAM usage and processing. +// if buffer is smaller then strings will often be fragmented. +// It is recommended to use size which will fit typical log and only the +// longer one will be fragmented. + +#ifndef NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE +#define NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE 64 +#endif + +#endif + +// + +// NRF_LOG_ENABLED - nrf_log - Logger +//========================================================== +#ifndef NRF_LOG_ENABLED +#ifdef DEBUG_NRF +#define NRF_LOG_ENABLED 1 +#else +#define NRF_LOG_ENABLED 0 +#endif +#endif +// Log message pool - Configuration of log message pool + +//========================================================== +// NRF_LOG_MSGPOOL_ELEMENT_SIZE - Size of a single element in the pool of memory objects. +// If a small value is set, then performance of logs processing +// is degraded because data is fragmented. Bigger value impacts +// RAM memory utilization. The size is set to fit a message with +// a timestamp and up to 2 arguments in a single memory object. + +#ifndef NRF_LOG_MSGPOOL_ELEMENT_SIZE +#define NRF_LOG_MSGPOOL_ELEMENT_SIZE 20 +#endif + +// NRF_LOG_MSGPOOL_ELEMENT_COUNT - Number of elements in the pool of memory objects +// If a small value is set, then it may lead to a deadlock +// in certain cases if backend has high latency and holds +// multiple messages for long time. Bigger value impacts +// RAM memory usage. + +#ifndef NRF_LOG_MSGPOOL_ELEMENT_COUNT +#define NRF_LOG_MSGPOOL_ELEMENT_COUNT 8 +#endif + +// +//========================================================== + +// NRF_LOG_ALLOW_OVERFLOW - Configures behavior when circular buffer is full. + + +// If set then oldest logs are overwritten. Otherwise a +// marker is injected informing about overflow. + +#ifndef NRF_LOG_ALLOW_OVERFLOW +#define NRF_LOG_ALLOW_OVERFLOW 1 +#endif + +// NRF_LOG_BUFSIZE - Size of the buffer for storing logs (in bytes). + + +// Must be power of 2 and multiple of 4. +// If NRF_LOG_DEFERRED = 0 then buffer size can be reduced to minimum. +// <128=> 128 +// <256=> 256 +// <512=> 512 +// <1024=> 1024 +// <2048=> 2048 +// <4096=> 4096 +// <8192=> 8192 +// <16384=> 16384 + +#ifndef NRF_LOG_BUFSIZE +#ifdef DEBUG_NRF +#define NRF_LOG_BUFSIZE 4096 +#else +#define NRF_LOG_BUFSIZE 1024 +#endif +#endif + +// NRF_LOG_CLI_CMDS - Enable CLI commands for the module. + + +#ifndef NRF_LOG_CLI_CMDS +#define NRF_LOG_CLI_CMDS 0 +#endif + +// NRF_LOG_DEFAULT_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_LOG_DEFAULT_LEVEL +#ifdef DEBUG_NRF +#define NRF_LOG_DEFAULT_LEVEL 4 +#else +#define NRF_LOG_DEFAULT_LEVEL 3 +#endif +#endif + +// NRF_LOG_DEFERRED - Enable deffered logger. + + +// Log data is buffered and can be processed in idle. + +#ifndef NRF_LOG_DEFERRED +#define NRF_LOG_DEFERRED 1 +#endif + +// NRF_LOG_FILTERS_ENABLED - Enable dynamic filtering of logs. + + +#ifndef NRF_LOG_FILTERS_ENABLED +#define NRF_LOG_FILTERS_ENABLED 0 +#endif + +// NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED - Enable use of critical region for non deffered mode when flushing logs. + + +// When enabled NRF_LOG_FLUSH is called from critical section when non deffered mode is used. +// Log output will never be corrupted as access to the log backend is exclusive +// but system will spend significant amount of time in critical section + +#ifndef NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED +#define NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED 0 +#endif + +// NRF_LOG_STR_PUSH_BUFFER_SIZE - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH. + +// <16=> 16 +// <32=> 32 +// <64=> 64 +// <128=> 128 +// <256=> 256 +// <512=> 512 +// <1024=> 1024 + +#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE +#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128 +#endif + +// NRF_LOG_STR_PUSH_BUFFER_SIZE - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH. + +// <16=> 16 +// <32=> 32 +// <64=> 64 +// <128=> 128 +// <256=> 256 +// <512=> 512 +// <1024=> 1024 + +#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE +#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128 +#endif + +// NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string +//========================================================== +#ifndef NRF_LOG_USES_COLORS +#define NRF_LOG_USES_COLORS 0 +#endif +// NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_COLOR_DEFAULT +#define NRF_LOG_COLOR_DEFAULT 0 +#endif + +// NRF_LOG_ERROR_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_ERROR_COLOR +#define NRF_LOG_ERROR_COLOR 2 +#endif + +// NRF_LOG_WARNING_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_WARNING_COLOR +#define NRF_LOG_WARNING_COLOR 4 +#endif + +// + +// NRF_LOG_USES_TIMESTAMP - Enable timestamping + +// Function for getting the timestamp is provided by the user +//========================================================== +#ifndef NRF_LOG_USES_TIMESTAMP +#define NRF_LOG_USES_TIMESTAMP 0 +#endif +// NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY - Default frequency of the timestamp (in Hz) or 0 to use app_timer frequency. +#ifndef NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY +#define NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY 0 +#endif + +// + +// nrf_log module configuration + +//========================================================== +// nrf_log in nRF_Core + +//========================================================== +// NRF_MPU_LIB_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_MPU_LIB_CONFIG_LOG_ENABLED +#define NRF_MPU_LIB_CONFIG_LOG_ENABLED 0 +#endif +// NRF_MPU_LIB_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_MPU_LIB_CONFIG_LOG_LEVEL +#define NRF_MPU_LIB_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_MPU_LIB_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MPU_LIB_CONFIG_INFO_COLOR +#define NRF_MPU_LIB_CONFIG_INFO_COLOR 0 +#endif + +// NRF_MPU_LIB_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MPU_LIB_CONFIG_DEBUG_COLOR +#define NRF_MPU_LIB_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_STACK_GUARD_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_STACK_GUARD_CONFIG_LOG_ENABLED +#define NRF_STACK_GUARD_CONFIG_LOG_ENABLED 0 +#endif +// NRF_STACK_GUARD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_STACK_GUARD_CONFIG_LOG_LEVEL +#define NRF_STACK_GUARD_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_STACK_GUARD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_STACK_GUARD_CONFIG_INFO_COLOR +#define NRF_STACK_GUARD_CONFIG_INFO_COLOR 0 +#endif + +// NRF_STACK_GUARD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_STACK_GUARD_CONFIG_DEBUG_COLOR +#define NRF_STACK_GUARD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TASK_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TASK_MANAGER_CONFIG_LOG_ENABLED +#define TASK_MANAGER_CONFIG_LOG_ENABLED 0 +#endif +// TASK_MANAGER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TASK_MANAGER_CONFIG_LOG_LEVEL +#define TASK_MANAGER_CONFIG_LOG_LEVEL 3 +#endif + +// TASK_MANAGER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TASK_MANAGER_CONFIG_INFO_COLOR +#define TASK_MANAGER_CONFIG_INFO_COLOR 0 +#endif + +// TASK_MANAGER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TASK_MANAGER_CONFIG_DEBUG_COLOR +#define TASK_MANAGER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// nrf_log in nRF_Drivers + +//========================================================== +// CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef CLOCK_CONFIG_LOG_ENABLED +#define CLOCK_CONFIG_LOG_ENABLED 0 +#endif +// CLOCK_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef CLOCK_CONFIG_LOG_LEVEL +#define CLOCK_CONFIG_LOG_LEVEL 3 +#endif + +// CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_INFO_COLOR +#define CLOCK_CONFIG_INFO_COLOR 0 +#endif + +// CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_DEBUG_COLOR +#define CLOCK_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// COMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef COMP_CONFIG_LOG_ENABLED +#define COMP_CONFIG_LOG_ENABLED 0 +#endif +// COMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef COMP_CONFIG_LOG_LEVEL +#define COMP_CONFIG_LOG_LEVEL 3 +#endif + +// COMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_INFO_COLOR +#define COMP_CONFIG_INFO_COLOR 0 +#endif + +// COMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_DEBUG_COLOR +#define COMP_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef GPIOTE_CONFIG_LOG_ENABLED +#define GPIOTE_CONFIG_LOG_ENABLED 0 +#endif +// GPIOTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef GPIOTE_CONFIG_LOG_LEVEL +#define GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +// GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_INFO_COLOR +#define GPIOTE_CONFIG_INFO_COLOR 0 +#endif + +// GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_DEBUG_COLOR +#define GPIOTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef LPCOMP_CONFIG_LOG_ENABLED +#define LPCOMP_CONFIG_LOG_ENABLED 0 +#endif +// LPCOMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef LPCOMP_CONFIG_LOG_LEVEL +#define LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +// LPCOMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_INFO_COLOR +#define LPCOMP_CONFIG_INFO_COLOR 0 +#endif + +// LPCOMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_DEBUG_COLOR +#define LPCOMP_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// MAX3421E_HOST_CONFIG_LOG_ENABLED - Enable logging in the module +//========================================================== +#ifndef MAX3421E_HOST_CONFIG_LOG_ENABLED +#define MAX3421E_HOST_CONFIG_LOG_ENABLED 0 +#endif +// MAX3421E_HOST_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef MAX3421E_HOST_CONFIG_LOG_LEVEL +#define MAX3421E_HOST_CONFIG_LOG_LEVEL 3 +#endif + +// MAX3421E_HOST_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MAX3421E_HOST_CONFIG_INFO_COLOR +#define MAX3421E_HOST_CONFIG_INFO_COLOR 0 +#endif + +// MAX3421E_HOST_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MAX3421E_HOST_CONFIG_DEBUG_COLOR +#define MAX3421E_HOST_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRFX_USBD_CONFIG_LOG_ENABLED - Enable logging in the module +//========================================================== +#ifndef NRFX_USBD_CONFIG_LOG_ENABLED +#define NRFX_USBD_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_USBD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_USBD_CONFIG_LOG_LEVEL +#define NRFX_USBD_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_USBD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_USBD_CONFIG_INFO_COLOR +#define NRFX_USBD_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_USBD_CONFIG_DEBUG_COLOR +#define NRFX_USBD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PDM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PDM_CONFIG_LOG_ENABLED +#define PDM_CONFIG_LOG_ENABLED 0 +#endif +// PDM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PDM_CONFIG_LOG_LEVEL +#define PDM_CONFIG_LOG_LEVEL 3 +#endif + +// PDM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_INFO_COLOR +#define PDM_CONFIG_INFO_COLOR 0 +#endif + +// PDM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_DEBUG_COLOR +#define PDM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PPI_CONFIG_LOG_ENABLED +#define PPI_CONFIG_LOG_ENABLED 0 +#endif +// PPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PPI_CONFIG_LOG_LEVEL +#define PPI_CONFIG_LOG_LEVEL 3 +#endif + +// PPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_INFO_COLOR +#define PPI_CONFIG_INFO_COLOR 0 +#endif + +// PPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_DEBUG_COLOR +#define PPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PWM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PWM_CONFIG_LOG_ENABLED +#define PWM_CONFIG_LOG_ENABLED 0 +#endif +// PWM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PWM_CONFIG_LOG_LEVEL +#define PWM_CONFIG_LOG_LEVEL 3 +#endif + +// PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_INFO_COLOR +#define PWM_CONFIG_INFO_COLOR 0 +#endif + +// PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_DEBUG_COLOR +#define PWM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// QDEC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef QDEC_CONFIG_LOG_ENABLED +#define QDEC_CONFIG_LOG_ENABLED 0 +#endif +// QDEC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef QDEC_CONFIG_LOG_LEVEL +#define QDEC_CONFIG_LOG_LEVEL 3 +#endif + +// QDEC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_INFO_COLOR +#define QDEC_CONFIG_INFO_COLOR 0 +#endif + +// QDEC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_DEBUG_COLOR +#define QDEC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// RNG_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RNG_CONFIG_LOG_ENABLED +#define RNG_CONFIG_LOG_ENABLED 0 +#endif +// RNG_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RNG_CONFIG_LOG_LEVEL +#define RNG_CONFIG_LOG_LEVEL 3 +#endif + +// RNG_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_INFO_COLOR +#define RNG_CONFIG_INFO_COLOR 0 +#endif + +// RNG_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_DEBUG_COLOR +#define RNG_CONFIG_DEBUG_COLOR 0 +#endif + +// RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED - Enables logging of random numbers. + + +#ifndef RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED +#define RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED 0 +#endif + +// + +// RTC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RTC_CONFIG_LOG_ENABLED +#define RTC_CONFIG_LOG_ENABLED 0 +#endif +// RTC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RTC_CONFIG_LOG_LEVEL +#define RTC_CONFIG_LOG_LEVEL 3 +#endif + +// RTC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_INFO_COLOR +#define RTC_CONFIG_INFO_COLOR 0 +#endif + +// RTC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_DEBUG_COLOR +#define RTC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SAADC_CONFIG_LOG_ENABLED +#define SAADC_CONFIG_LOG_ENABLED 0 +#endif +// SAADC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SAADC_CONFIG_LOG_LEVEL +#define SAADC_CONFIG_LOG_LEVEL 3 +#endif + +// SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_INFO_COLOR +#define SAADC_CONFIG_INFO_COLOR 0 +#endif + +// SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_DEBUG_COLOR +#define SAADC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// SPIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPIS_CONFIG_LOG_ENABLED +#define SPIS_CONFIG_LOG_ENABLED 0 +#endif +// SPIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPIS_CONFIG_LOG_LEVEL +#define SPIS_CONFIG_LOG_LEVEL 3 +#endif + +// SPIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_INFO_COLOR +#define SPIS_CONFIG_INFO_COLOR 0 +#endif + +// SPIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_DEBUG_COLOR +#define SPIS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// SPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPI_CONFIG_LOG_ENABLED +#define SPI_CONFIG_LOG_ENABLED 0 +#endif +// SPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPI_CONFIG_LOG_LEVEL +#define SPI_CONFIG_LOG_LEVEL 3 +#endif + +// SPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_INFO_COLOR +#define SPI_CONFIG_INFO_COLOR 0 +#endif + +// SPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_DEBUG_COLOR +#define SPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TIMER_CONFIG_LOG_ENABLED +#define TIMER_CONFIG_LOG_ENABLED 0 +#endif +// TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TIMER_CONFIG_LOG_LEVEL +#define TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_INFO_COLOR +#define TIMER_CONFIG_INFO_COLOR 0 +#endif + +// TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_DEBUG_COLOR +#define TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TWIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWIS_CONFIG_LOG_ENABLED +#define TWIS_CONFIG_LOG_ENABLED 0 +#endif +// TWIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWIS_CONFIG_LOG_LEVEL +#define TWIS_CONFIG_LOG_LEVEL 3 +#endif + +// TWIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_INFO_COLOR +#define TWIS_CONFIG_INFO_COLOR 0 +#endif + +// TWIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_DEBUG_COLOR +#define TWIS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWI_CONFIG_LOG_ENABLED +#define TWI_CONFIG_LOG_ENABLED 0 +#endif +// TWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWI_CONFIG_LOG_LEVEL +#define TWI_CONFIG_LOG_LEVEL 3 +#endif + +// TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_INFO_COLOR +#define TWI_CONFIG_INFO_COLOR 0 +#endif + +// TWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_DEBUG_COLOR +#define TWI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef UART_CONFIG_LOG_ENABLED +#define UART_CONFIG_LOG_ENABLED 0 +#endif +// UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef UART_CONFIG_LOG_LEVEL +#define UART_CONFIG_LOG_LEVEL 3 +#endif + +// UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_INFO_COLOR +#define UART_CONFIG_INFO_COLOR 0 +#endif + +// UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_DEBUG_COLOR +#define UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// USBD_CONFIG_LOG_ENABLED - Enable logging in the module +//========================================================== +#ifndef USBD_CONFIG_LOG_ENABLED +#define USBD_CONFIG_LOG_ENABLED 0 +#endif +// USBD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef USBD_CONFIG_LOG_LEVEL +#define USBD_CONFIG_LOG_LEVEL 3 +#endif + +// USBD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef USBD_CONFIG_INFO_COLOR +#define USBD_CONFIG_INFO_COLOR 0 +#endif + +// USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef USBD_CONFIG_DEBUG_COLOR +#define USBD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// WDT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef WDT_CONFIG_LOG_ENABLED +#define WDT_CONFIG_LOG_ENABLED 0 +#endif +// WDT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef WDT_CONFIG_LOG_LEVEL +#define WDT_CONFIG_LOG_LEVEL 3 +#endif + +// WDT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_INFO_COLOR +#define WDT_CONFIG_INFO_COLOR 0 +#endif + +// WDT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_DEBUG_COLOR +#define WDT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// nrf_log in nRF_Libraries + +//========================================================== +// APP_BUTTON_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_BUTTON_CONFIG_LOG_ENABLED +#define APP_BUTTON_CONFIG_LOG_ENABLED 0 +#endif +// APP_BUTTON_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_BUTTON_CONFIG_LOG_LEVEL +#define APP_BUTTON_CONFIG_LOG_LEVEL 3 +#endif + +// APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL - Initial severity level if dynamic filtering is enabled. + + +// If module generates a lot of logs, initial log level can +// be decreased to prevent flooding. Severity level can be +// increased on instance basis. +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL +#define APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL 3 +#endif + +// APP_BUTTON_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_BUTTON_CONFIG_INFO_COLOR +#define APP_BUTTON_CONFIG_INFO_COLOR 0 +#endif + +// APP_BUTTON_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_BUTTON_CONFIG_DEBUG_COLOR +#define APP_BUTTON_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_TIMER_CONFIG_LOG_ENABLED +#define APP_TIMER_CONFIG_LOG_ENABLED 0 +#endif +// APP_TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_TIMER_CONFIG_LOG_LEVEL +#define APP_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// APP_TIMER_CONFIG_INITIAL_LOG_LEVEL - Initial severity level if dynamic filtering is enabled. + + +// If module generates a lot of logs, initial log level can +// be decreased to prevent flooding. Severity level can be +// increased on instance basis. +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_TIMER_CONFIG_INITIAL_LOG_LEVEL +#define APP_TIMER_CONFIG_INITIAL_LOG_LEVEL 3 +#endif + +// APP_TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_TIMER_CONFIG_INFO_COLOR +#define APP_TIMER_CONFIG_INFO_COLOR 0 +#endif + +// APP_TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_TIMER_CONFIG_DEBUG_COLOR +#define APP_TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED +#define APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL +#define APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_CDC_ACM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CDC_ACM_CONFIG_INFO_COLOR +#define APP_USBD_CDC_ACM_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR +#define APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module. +//========================================================== +#ifndef APP_USBD_CONFIG_LOG_ENABLED +#define APP_USBD_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_CONFIG_LOG_LEVEL +#define APP_USBD_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CONFIG_INFO_COLOR +#define APP_USBD_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CONFIG_DEBUG_COLOR +#define APP_USBD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_DUMMY_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_DUMMY_CONFIG_LOG_ENABLED +#define APP_USBD_DUMMY_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_DUMMY_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_DUMMY_CONFIG_LOG_LEVEL +#define APP_USBD_DUMMY_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_DUMMY_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_DUMMY_CONFIG_INFO_COLOR +#define APP_USBD_DUMMY_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_DUMMY_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_DUMMY_CONFIG_DEBUG_COLOR +#define APP_USBD_DUMMY_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_MSC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_MSC_CONFIG_LOG_ENABLED +#define APP_USBD_MSC_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_MSC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_MSC_CONFIG_LOG_LEVEL +#define APP_USBD_MSC_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_MSC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_MSC_CONFIG_INFO_COLOR +#define APP_USBD_MSC_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_MSC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_MSC_CONFIG_DEBUG_COLOR +#define APP_USBD_MSC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_ATFIFO_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_ATFIFO_CONFIG_LOG_ENABLED +#define NRF_ATFIFO_CONFIG_LOG_ENABLED 0 +#endif +// NRF_ATFIFO_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_ATFIFO_CONFIG_LOG_LEVEL +#define NRF_ATFIFO_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_ATFIFO_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_ATFIFO_CONFIG_INFO_COLOR +#define NRF_ATFIFO_CONFIG_INFO_COLOR 0 +#endif + +// NRF_ATFIFO_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_ATFIFO_CONFIG_DEBUG_COLOR +#define NRF_ATFIFO_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BALLOC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BALLOC_CONFIG_LOG_ENABLED +#define NRF_BALLOC_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BALLOC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BALLOC_CONFIG_LOG_LEVEL +#define NRF_BALLOC_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL - Initial severity level if dynamic filtering is enabled. + + +// If module generates a lot of logs, initial log level can +// be decreased to prevent flooding. Severity level can be +// increased on instance basis. +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL +#define NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL 3 +#endif + +// NRF_BALLOC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BALLOC_CONFIG_INFO_COLOR +#define NRF_BALLOC_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BALLOC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BALLOC_CONFIG_DEBUG_COLOR +#define NRF_BALLOC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED +#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL +#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR +#define NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR +#define NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED +#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL +#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR +#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR +#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED +#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL +#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR +#define NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR +#define NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED +#define NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED 0 +#endif +// NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL +#define NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_CLI_BLE_UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_BLE_UART_CONFIG_INFO_COLOR +#define NRF_CLI_BLE_UART_CONFIG_INFO_COLOR 0 +#endif + +// NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR +#define NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED +#define NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED 0 +#endif +// NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL +#define NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR +#define NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR 0 +#endif + +// NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR +#define NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_CLI_UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_CLI_UART_CONFIG_LOG_ENABLED +#define NRF_CLI_UART_CONFIG_LOG_ENABLED 0 +#endif +// NRF_CLI_UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_CLI_UART_CONFIG_LOG_LEVEL +#define NRF_CLI_UART_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_CLI_UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_UART_CONFIG_INFO_COLOR +#define NRF_CLI_UART_CONFIG_INFO_COLOR 0 +#endif + +// NRF_CLI_UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_UART_CONFIG_DEBUG_COLOR +#define NRF_CLI_UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_LIBUARTE_CONFIG_LOG_ENABLED +#define NRF_LIBUARTE_CONFIG_LOG_ENABLED 0 +#endif +// NRF_LIBUARTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_LIBUARTE_CONFIG_LOG_LEVEL +#define NRF_LIBUARTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_LIBUARTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LIBUARTE_CONFIG_INFO_COLOR +#define NRF_LIBUARTE_CONFIG_INFO_COLOR 0 +#endif + +// NRF_LIBUARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LIBUARTE_CONFIG_DEBUG_COLOR +#define NRF_LIBUARTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_MEMOBJ_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_MEMOBJ_CONFIG_LOG_ENABLED +#define NRF_MEMOBJ_CONFIG_LOG_ENABLED 0 +#endif +// NRF_MEMOBJ_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_MEMOBJ_CONFIG_LOG_LEVEL +#define NRF_MEMOBJ_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_MEMOBJ_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MEMOBJ_CONFIG_INFO_COLOR +#define NRF_MEMOBJ_CONFIG_INFO_COLOR 0 +#endif + +// NRF_MEMOBJ_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MEMOBJ_CONFIG_DEBUG_COLOR +#define NRF_MEMOBJ_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_PWR_MGMT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_PWR_MGMT_CONFIG_LOG_ENABLED +#define NRF_PWR_MGMT_CONFIG_LOG_ENABLED 0 +#endif +// NRF_PWR_MGMT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_PWR_MGMT_CONFIG_LOG_LEVEL +#define NRF_PWR_MGMT_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_PWR_MGMT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_PWR_MGMT_CONFIG_INFO_COLOR +#define NRF_PWR_MGMT_CONFIG_INFO_COLOR 0 +#endif + +// NRF_PWR_MGMT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_PWR_MGMT_CONFIG_DEBUG_COLOR +#define NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_QUEUE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_QUEUE_CONFIG_LOG_ENABLED +#define NRF_QUEUE_CONFIG_LOG_ENABLED 0 +#endif +// NRF_QUEUE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_QUEUE_CONFIG_LOG_LEVEL +#define NRF_QUEUE_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_QUEUE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_QUEUE_CONFIG_INFO_COLOR +#define NRF_QUEUE_CONFIG_INFO_COLOR 0 +#endif + +// NRF_QUEUE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_QUEUE_CONFIG_DEBUG_COLOR +#define NRF_QUEUE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_ANT_LOG_ENABLED - Enable logging in SoftDevice handler (ANT) module. +//========================================================== +#ifndef NRF_SDH_ANT_LOG_ENABLED +#define NRF_SDH_ANT_LOG_ENABLED 0 +#endif +// NRF_SDH_ANT_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_ANT_LOG_LEVEL +#define NRF_SDH_ANT_LOG_LEVEL 3 +#endif + +// NRF_SDH_ANT_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_ANT_INFO_COLOR +#define NRF_SDH_ANT_INFO_COLOR 0 +#endif + +// NRF_SDH_ANT_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_ANT_DEBUG_COLOR +#define NRF_SDH_ANT_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_BLE_LOG_ENABLED - Enable logging in SoftDevice handler (BLE) module. +//========================================================== +#ifndef NRF_SDH_BLE_LOG_ENABLED +#define NRF_SDH_BLE_LOG_ENABLED 0 +#endif +// NRF_SDH_BLE_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_BLE_LOG_LEVEL +#define NRF_SDH_BLE_LOG_LEVEL 3 +#endif + +// NRF_SDH_BLE_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_BLE_INFO_COLOR +#define NRF_SDH_BLE_INFO_COLOR 0 +#endif + +// NRF_SDH_BLE_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_BLE_DEBUG_COLOR +#define NRF_SDH_BLE_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_LOG_ENABLED - Enable logging in SoftDevice handler module. +//========================================================== +#ifndef NRF_SDH_LOG_ENABLED +#define NRF_SDH_LOG_ENABLED 0 +#endif +// NRF_SDH_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_LOG_LEVEL +#define NRF_SDH_LOG_LEVEL 3 +#endif + +// NRF_SDH_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_INFO_COLOR +#define NRF_SDH_INFO_COLOR 0 +#endif + +// NRF_SDH_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_DEBUG_COLOR +#define NRF_SDH_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_SOC_LOG_ENABLED - Enable logging in SoftDevice handler (SoC) module. +//========================================================== +#ifndef NRF_SDH_SOC_LOG_ENABLED +#define NRF_SDH_SOC_LOG_ENABLED 0 +#endif +// NRF_SDH_SOC_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_SOC_LOG_LEVEL +#define NRF_SDH_SOC_LOG_LEVEL 3 +#endif + +// NRF_SDH_SOC_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_SOC_INFO_COLOR +#define NRF_SDH_SOC_INFO_COLOR 0 +#endif + +// NRF_SDH_SOC_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_SOC_DEBUG_COLOR +#define NRF_SDH_SOC_DEBUG_COLOR 0 +#endif + +// + +// NRF_SORTLIST_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_SORTLIST_CONFIG_LOG_ENABLED +#define NRF_SORTLIST_CONFIG_LOG_ENABLED 0 +#endif +// NRF_SORTLIST_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SORTLIST_CONFIG_LOG_LEVEL +#define NRF_SORTLIST_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_SORTLIST_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SORTLIST_CONFIG_INFO_COLOR +#define NRF_SORTLIST_CONFIG_INFO_COLOR 0 +#endif + +// NRF_SORTLIST_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SORTLIST_CONFIG_DEBUG_COLOR +#define NRF_SORTLIST_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_TWI_SENSOR_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_TWI_SENSOR_CONFIG_LOG_ENABLED +#define NRF_TWI_SENSOR_CONFIG_LOG_ENABLED 0 +#endif +// NRF_TWI_SENSOR_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_TWI_SENSOR_CONFIG_LOG_LEVEL +#define NRF_TWI_SENSOR_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_TWI_SENSOR_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_TWI_SENSOR_CONFIG_INFO_COLOR +#define NRF_TWI_SENSOR_CONFIG_INFO_COLOR 0 +#endif + +// NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR +#define NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PM_LOG_ENABLED - Enable logging in Peer Manager and its submodules. +//========================================================== +#ifndef PM_LOG_ENABLED +#define PM_LOG_ENABLED 1 +#endif +// PM_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PM_LOG_LEVEL +#define PM_LOG_LEVEL 3 +#endif + +// PM_LOG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PM_LOG_INFO_COLOR +#define PM_LOG_INFO_COLOR 0 +#endif + +// PM_LOG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PM_LOG_DEBUG_COLOR +#define PM_LOG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// nrf_log in nRF_Serialization + +//========================================================== +// SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED +#define SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED 0 +#endif +// SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL +#define SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL 3 +#endif + +// SER_HAL_TRANSPORT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SER_HAL_TRANSPORT_CONFIG_INFO_COLOR +#define SER_HAL_TRANSPORT_CONFIG_INFO_COLOR 0 +#endif + +// SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR +#define SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// +//========================================================== + +// + +// NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED - nrf_log_str_formatter - Log string formatter + + +#ifndef NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED +#define NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED 1 +#endif + +// +//========================================================== + +// nRF_Segger_RTT + +//========================================================== +// segger_rtt - SEGGER RTT + +//========================================================== +// SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. +// Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE +// or this value is actually used. It depends on which one is bigger. + +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 4096 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Maximum number of upstream buffers. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of downstream buffer. +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Maximum number of downstream buffers. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full. + + +// The following modes are supported: +// - SKIP - Do not block, output nothing. +// - TRIM - Do not block, output as much as fits. +// - BLOCK - Wait until there is space in the buffer. +// <0=> SKIP +// <1=> TRIM +// <2=> BLOCK_IF_FIFO_FULL + +#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE +#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// <<< end of configuration section >>> +#endif //SDK_CONFIG_H + diff --git a/core/embed/ble_bootloader/settings.hex b/core/embed/ble_bootloader/settings.hex new file mode 100644 index 000000000..4406d2ad1 --- /dev/null +++ b/core/embed/ble_bootloader/settings.hex @@ -0,0 +1,104 @@ +:020000040007F3 +:10E000005021D2AF0200000000000000000000001C +:10E01000000000000000000080820100C0F8B7B4DA +:10E0200001000000000000000000000000000000EF +:10E030000000000034560200000000000000000054 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000001F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E2200000000000000000000000000000000000EE +:10E2300000000000000000000000000000000000DE +:10E2400000000000000000000000000000000000CE +:10E250000000000000000000000000008AEF67D40A +:10E26000039C5C1C98A20BBD8ABFB9C46939106BB2 +:10E27000B47E723565915A51FAC818DE94DD6E8C01 +:10E280002BD8C489343239712A38D616C1A9482C02 +:10E29000CDA78E5E28F37D0E3AF147DF285C80170C +:10E2A00071035B9F4D32703D914A924FB5B9142076 +:10E2B000EE2F84400F8681CD396EC8C55C811676FD +:10E2C000EC52E336EE8EF89DB5B57AAF4C54E69736 +:10E2D000A3E5472CD695C51C2E4EB86E56EE19F503 +:10E2E00051AE00000000000000000000000000002F +:10E2F000000000000000000000000000000000001E +:10E30000000000000000000000000000000000000D +:10E3100000000000000000000000000000000000FD +:04E32000000000FFFA +:10F000005021D2AF0200000000000000000000000C +:10F01000000000000000000080820100C0F8B7B4CA +:10F0200001000000000000000000000000000000DF +:10F030000000000034560200000000000000000044 +:10F0400000000000000000000000000000000000C0 +:10F0500000000000000000000000000000000000B0 +:10F0600000000000000000000000000000000000A0 +:10F070000000000000000000000000000000000090 +:10F080000000000000000000000000000000000080 +:10F090000000000000000000000000000000000070 +:10F0A0000000000000000000000000000000000060 +:10F0B0000000000000000000000000000000000050 +:10F0C0000000000000000000000000000000000040 +:10F0D0000000000000000000000000000000000030 +:10F0E0000000000000000000000000000000000020 +:10F0F0000000000000000000000000000000000010 +:10F1000000000000000000000000000000000000FF +:10F1100000000000000000000000000000000000EF +:10F1200000000000000000000000000000000000DF +:10F1300000000000000000000000000000000000CF +:10F1400000000000000000000000000000000000BF +:10F1500000000000000000000000000000000000AF +:10F16000000000000000000000000000000000009F +:10F17000000000000000000000000000000000008F +:10F18000000000000000000000000000000000007F +:10F19000000000000000000000000000000000006F +:10F1A000000000000000000000000000000000005F +:10F1B000000000000000000000000000000000004F +:10F1C000000000000000000000000000000000003F +:10F1D000000000000000000000000000000000002F +:10F1E000000000000000000000000000000000001F +:10F1F000000000000000000000000000000000000F +:10F2000000000000000000000000000000000000FE +:10F2100000000000000000000000000000000000EE +:10F2200000000000000000000000000000000000DE +:10F2300000000000000000000000000000000000CE +:10F2400000000000000000000000000000000000BE +:10F250000000000000000000000000008AEF67D4FA +:10F26000039C5C1C98A20BBD8ABFB9C46939106BA2 +:10F27000B47E723565915A51FAC818DE94DD6E8CF1 +:10F280002BD8C489343239712A38D616C1A9482CF2 +:10F29000CDA78E5E28F37D0E3AF147DF285C8017FC +:10F2A00071035B9F4D32703D914A924FB5B9142066 +:10F2B000EE2F84400F8681CD396EC8C55C811676ED +:10F2C000EC52E336EE8EF89DB5B57AAF4C54E69726 +:10F2D000A3E5472CD695C51C2E4EB86E56EE19F5F3 +:10F2E00051AE00000000000000000000000000001F +:10F2F000000000000000000000000000000000000E +:10F3000000000000000000000000000000000000FD +:10F3100000000000000000000000000000000000ED +:04F32000000000FFEA +:00000001FF diff --git a/core/embed/ble_bootloader/uecc/.gitignore b/core/embed/ble_bootloader/uecc/.gitignore new file mode 100644 index 000000000..561bd57ec --- /dev/null +++ b/core/embed/ble_bootloader/uecc/.gitignore @@ -0,0 +1,11 @@ +__build__/ +__pycache__ +*.pyc +*.pyo +*.pyd +*.pyz +*.egg-info/ +*.a +*.o +*.so +.DS_Store diff --git a/core/embed/ble_bootloader/uecc/LICENSE.txt b/core/embed/ble_bootloader/uecc/LICENSE.txt new file mode 100644 index 000000000..ab099ae5a --- /dev/null +++ b/core/embed/ble_bootloader/uecc/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2014, Kenneth MacKay +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/core/embed/ble_bootloader/uecc/README.md b/core/embed/ble_bootloader/uecc/README.md new file mode 100644 index 000000000..111321bf7 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/README.md @@ -0,0 +1,41 @@ +micro-ecc +========== + +A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors. + +The static version of micro-ecc (ie, where the curve was selected at compile-time) can be found in the "static" branch. + +Features +-------- + + * Resistant to known side-channel attacks. + * Written in C, with optional GCC inline assembly for AVR, ARM and Thumb platforms. + * Supports 8, 32, and 64-bit architectures. + * Small code size. + * No dynamic memory allocation. + * Support for 5 standard curves: secp160r1, secp192r1, secp224r1, secp256r1, and secp256k1. + * BSD 2-clause license. + +Usage Notes +----------- +### Point Representation ### +Compressed points are represented in the standard format as defined in http://www.secg.org/sec1-v2.pdf; uncompressed points are represented in standard format, but without the `0x04` prefix. All functions except `uECC_decompress()` only accept uncompressed points; use `uECC_compress()` and `uECC_decompress()` to convert between compressed and uncompressed point representations. + +Private keys are represented in the standard format. + +### Using the Code ### + +I recommend just copying (or symlink) the uECC files into your project. Then just `#include "uECC.h"` to use the micro-ecc functions. + +For use with Arduino, you can use the Library Manager to download micro-ecc (**Sketch**=>**Include Library**=>**Manage Libraries**). You can then use uECC just like any other Arduino library (uECC should show up in the **Sketch**=>**Import Library** submenu). + +See uECC.h for documentation for each function. + +### Compilation Notes ### + + * Should compile with any C/C++ compiler that supports stdint.h (this includes Visual Studio 2013). + * If you want to change the defaults for any of the uECC compile-time options (such as `uECC_OPTIMIZATION_LEVEL`), you must change them in your Makefile or similar so that uECC.c is compiled with the desired values (ie, compile uECC.c with `-DuECC_OPTIMIZATION_LEVEL=3` or whatever). + * When compiling for a Thumb-1 platform, you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for an ARM/Thumb-2 platform with `uECC_OPTIMIZATION_LEVEL` >= 3, you must use the `-fomit-frame-pointer` GCC option (this is enabled by default when compiling with `-O1` or higher). + * When compiling for AVR, you must have optimizations enabled (compile with `-O1` or higher). + * When building for Windows, you will need to link in the `advapi32.lib` system library. diff --git a/core/embed/ble_bootloader/uecc/asm_arm.inc b/core/embed/ble_bootloader/uecc/asm_arm.inc new file mode 100644 index 000000000..12e747f9b --- /dev/null +++ b/core/embed/ble_bootloader/uecc/asm_arm.inc @@ -0,0 +1,820 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_H_ +#define _UECC_ASM_ARM_H_ + +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #define uECC_MIN_WORDS 8 +#endif +#if uECC_SUPPORTS_secp224r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 7 +#endif +#if uECC_SUPPORTS_secp192r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 6 +#endif +#if uECC_SUPPORTS_secp160r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 5 +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb) + #define REG_RW "+&l" + #define REG_WRITE "=&l" +#else + #define REG_RW "+&r" + #define REG_WRITE "=&r" +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb || uECC_PLATFORM == uECC_arm_thumb2) + #define REG_RW_LO "+&l" + #define REG_WRITE_LO "=&l" +#else + #define REG_RW_LO "+&r" + #define REG_WRITE_LO "=&r" +#endif + +#if (uECC_PLATFORM == uECC_arm_thumb2) + #define RESUME_SYNTAX +#else + #define RESUME_SYNTAX ".syntax divided \n\t" +#endif + +#if (uECC_OPTIMIZATION_LEVEL >= 2) + +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { +#if (uECC_MAX_WORDS != uECC_MIN_WORDS) + #if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2) + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 2 + 1; + #else /* ARM */ + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 4; + #endif +#endif + uint32_t carry; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs %[carry], #0 \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "adr %[left], 1f \n\t" + ".align 4 \n\t" + "adds %[jump], %[left] \n\t" + #endif + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adds %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "bx %[jump] \n\t" + #endif + "1: \n\t" + REPEAT(DEC(uECC_MAX_WORDS), + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "adcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" + RESUME_SYNTAX + : [dptr] REG_RW_LO (result), [lptr] REG_RW_LO (left), [rptr] REG_RW_LO (right), + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + [jump] REG_RW_LO (jump), + #endif + [carry] REG_WRITE_LO (carry), [left] REG_WRITE_LO (left_word), + [right] REG_WRITE_LO (right_word) + : + : "cc", "memory" + ); + return carry; +} +#define asm_add 1 + +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { +#if (uECC_MAX_WORDS != uECC_MIN_WORDS) + #if (uECC_PLATFORM == uECC_arm_thumb) || (uECC_PLATFORM == uECC_arm_thumb2) + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 2 + 1; + #else /* ARM */ + uint32_t jump = (uECC_MAX_WORDS - num_words) * 4 * 4; + #endif +#endif + uint32_t carry; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "movs %[carry], #0 \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "adr %[left], 1f \n\t" + ".align 4 \n\t" + "adds %[jump], %[left] \n\t" + #endif + + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "subs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t" + + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "bx %[jump] \n\t" + #endif + "1: \n\t" + REPEAT(DEC(uECC_MAX_WORDS), + "ldmia %[lptr]!, {%[left]} \n\t" + "ldmia %[rptr]!, {%[right]} \n\t" + "sbcs %[left], %[right] \n\t" + "stmia %[dptr]!, {%[left]} \n\t") + + "adcs %[carry], %[carry] \n\t" + RESUME_SYNTAX + : [dptr] REG_RW_LO (result), [lptr] REG_RW_LO (left), [rptr] REG_RW_LO (right), + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + [jump] REG_RW_LO (jump), + #endif + [carry] REG_WRITE_LO (carry), [left] REG_WRITE_LO (left_word), + [right] REG_WRITE_LO (right_word) + : + : "cc", "memory" + ); + return !carry; /* Note that on ARM, carry flag set means "no borrow" when subtracting + (for some reason...) */ +} +#define asm_sub 1 + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 2) */ + +#if (uECC_OPTIMIZATION_LEVEL >= 3) + +#if (uECC_PLATFORM != uECC_arm_thumb) + +#if uECC_ARM_USE_UMAAL + #include "asm_arm_mult_square_umaal.inc" +#else + #include "asm_arm_mult_square.inc" +#endif + +#if (uECC_OPTIMIZATION_LEVEL == 3) + +uECC_VLI_API void uECC_vli_mult(uint32_t *result, + const uint32_t *left, + const uint32_t *right, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register const uint32_t *r2 __asm__("r2") = right; + register uint32_t r3 __asm__("r3") = num_words; + + __asm__ volatile ( + ".syntax unified \n\t" +#if (uECC_MIN_WORDS == 5) + FAST_MULT_ASM_5 + #if (uECC_MAX_WORDS > 5) + FAST_MULT_ASM_5_TO_6 + #endif + #if (uECC_MAX_WORDS > 6) + FAST_MULT_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 6) + FAST_MULT_ASM_6 + #if (uECC_MAX_WORDS > 6) + FAST_MULT_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 7) + FAST_MULT_ASM_7 + #if (uECC_MAX_WORDS > 7) + FAST_MULT_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 8) + FAST_MULT_ASM_8 +#endif + "1: \n\t" + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register uint32_t r2 __asm__("r2") = num_words; + + __asm__ volatile ( + ".syntax unified \n\t" +#if (uECC_MIN_WORDS == 5) + FAST_SQUARE_ASM_5 + #if (uECC_MAX_WORDS > 5) + FAST_SQUARE_ASM_5_TO_6 + #endif + #if (uECC_MAX_WORDS > 6) + FAST_SQUARE_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 6) + FAST_SQUARE_ASM_6 + #if (uECC_MAX_WORDS > 6) + FAST_SQUARE_ASM_6_TO_7 + #endif + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 7) + FAST_SQUARE_ASM_7 + #if (uECC_MAX_WORDS > 7) + FAST_SQUARE_ASM_7_TO_8 + #endif +#elif (uECC_MIN_WORDS == 8) + FAST_SQUARE_ASM_8 +#endif + + "1: \n\t" + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#else /* (uECC_OPTIMIZATION_LEVEL > 3) */ + +uECC_VLI_API void uECC_vli_mult(uint32_t *result, + const uint32_t *left, + const uint32_t *right, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register const uint32_t *r2 __asm__("r2") = right; + register uint32_t r3 __asm__("r3") = num_words; + +#if uECC_SUPPORTS_secp160r1 + if (num_words == 5) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_5 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp192r1 + if (num_words == 6) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_6 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp224r1 + if (num_words == 7) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_7 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + if (num_words == 8) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_MULT_ASM_8 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1), "+r" (r2) + : "r" (r3) + : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + register uint32_t *r0 __asm__("r0") = result; + register const uint32_t *r1 __asm__("r1") = left; + register uint32_t r2 __asm__("r2") = num_words; + +#if uECC_SUPPORTS_secp160r1 + if (num_words == 5) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_5 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp192r1 + if (num_words == 6) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_6 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if uECC_SUPPORTS_secp224r1 + if (num_words == 7) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_7 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + if (num_words == 8) { + __asm__ volatile ( + ".syntax unified \n\t" + FAST_SQUARE_ASM_8 + RESUME_SYNTAX + : "+r" (r0), "+r" (r1) + : "r" (r2) + : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); + return; + } +#endif +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#endif /* (uECC_OPTIMIZATION_LEVEL > 3) */ + +#endif /* uECC_PLATFORM != uECC_arm_thumb */ + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 3) */ + +/* ---- "Small" implementations ---- */ + +#if !asm_add +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uint32_t carry = 0; + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "1: \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "lsrs %[carry], #1 \n\t" /* Set up carry flag (carry = 0 after this). */ + "adcs %[left], %[left], %[right] \n\t" /* Add with carry. */ + "adcs %[carry], %[carry], %[carry] \n\t" /* Store carry bit. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + "subs %[ctr], #1 \n\t" /* Decrement counter. */ + "bne 1b \n\t" /* Loop until counter == 0. */ + RESUME_SYNTAX + : [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right), + [ctr] REG_RW (num_words), [carry] REG_RW (carry), + [left] REG_WRITE (left_word), [right] REG_WRITE (right_word) + : + : "cc", "memory" + ); + return carry; +} +#define asm_add 1 +#endif + +#if !asm_sub +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uint32_t carry = 1; /* carry = 1 initially (means don't borrow) */ + uint32_t left_word; + uint32_t right_word; + + __asm__ volatile ( + ".syntax unified \n\t" + "1: \n\t" + "ldmia %[lptr]!, {%[left]} \n\t" /* Load left word. */ + "ldmia %[rptr]!, {%[right]} \n\t" /* Load right word. */ + "lsrs %[carry], #1 \n\t" /* Set up carry flag (carry = 0 after this). */ + "sbcs %[left], %[left], %[right] \n\t" /* Subtract with borrow. */ + "adcs %[carry], %[carry], %[carry] \n\t" /* Store carry bit. */ + "stmia %[dptr]!, {%[left]} \n\t" /* Store result word. */ + "subs %[ctr], #1 \n\t" /* Decrement counter. */ + "bne 1b \n\t" /* Loop until counter == 0. */ + RESUME_SYNTAX + : [dptr] REG_RW (result), [lptr] REG_RW (left), [rptr] REG_RW (right), + [ctr] REG_RW (num_words), [carry] REG_RW (carry), + [left] REG_WRITE (left_word), [right] REG_WRITE (right_word) + : + : "cc", "memory" + ); + return !carry; +} +#define asm_sub 1 +#endif + +#if !asm_mult +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { +#if (uECC_PLATFORM != uECC_arm_thumb) + uint32_t c0 = 0; + uint32_t c1 = 0; + uint32_t c2 = 0; + uint32_t k = 0; + uint32_t i; + uint32_t t0, t1; + + __asm__ volatile ( + ".syntax unified \n\t" + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[i], #0 \n\t" /* i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[i], %[k] \n\t" /* i = k */ + "subs %[i], %[last_word] \n\t" /* i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "subs %[t0], %[k], %[i] \n\t" /* t0 = k-i */ + + "ldr %[t1], [%[right], %[t0]] \n\t" /* t1 = right[k - i] */ + "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = left[i] */ + + "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = left[i] * right[k - i] */ + + "adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */ + + "adds %[i], #4 \n\t" /* i += 4 */ + "cmp %[i], %[last_word] \n\t" /* i > (num_words - 1) (times 4)? */ + "bgt 4f \n\t" /* if so, exit the loop */ + "cmp %[i], %[k] \n\t" /* i <= k? */ + "ble 3b \n\t" /* if so, continue looping */ + + "4: \n\t" /* end inner loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[k] = c0 */ + "mov %[c0], %[c1] \n\t" /* c0 = c1 */ + "mov %[c1], %[c2] \n\t" /* c1 = c2 */ + "movs %[c2], #0 \n\t" /* c2 = 0 */ + "adds %[k], #4 \n\t" /* k += 4 */ + "cmp %[k], %[last_word] \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[k], %[last_word], lsl #1 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, start with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[num_words * 2 - 1] = c0 */ + RESUME_SYNTAX + : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), + [k] "+r" (k), [i] "=&r" (i), [t0] "=&r" (t0), [t1] "=&r" (t1) + : [result] "r" (result), [left] "r" (left), [right] "r" (right), + [last_word] "r" ((num_words - 1) * 4) + : "cc", "memory" + ); + +#else /* Thumb-1 */ + uint32_t r4, r5, r6, r7; + + __asm__ volatile ( + ".syntax unified \n\t" + "subs %[r3], #1 \n\t" /* r3 = num_words - 1 */ + "lsls %[r3], #2 \n\t" /* r3 = (num_words - 1) * 4 */ + "mov r8, %[r3] \n\t" /* r8 = (num_words - 1) * 4 */ + "lsls %[r3], #1 \n\t" /* r3 = (num_words - 1) * 8 */ + "mov r9, %[r3] \n\t" /* r9 = (num_words - 1) * 8 */ + "movs %[r3], #0 \n\t" /* c0 = 0 */ + "movs %[r4], #0 \n\t" /* c1 = 0 */ + "movs %[r5], #0 \n\t" /* c2 = 0 */ + "movs %[r6], #0 \n\t" /* k = 0 */ + + "push {%[r0]} \n\t" /* keep result on the stack */ + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[r7], #0 \n\t" /* r7 = i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[r7], %[r6] \n\t" /* r7 = k */ + "mov %[r0], r8 \n\t" /* r0 = (num_words - 1) * 4 */ + "subs %[r7], %[r0] \n\t" /* r7 = i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "mov r10, %[r3] \n\t" + "mov r11, %[r4] \n\t" + "mov r12, %[r5] \n\t" + "mov r14, %[r6] \n\t" + "subs %[r0], %[r6], %[r7] \n\t" /* r0 = k - i */ + + "ldr %[r4], [%[r2], %[r0]] \n\t" /* r4 = right[k - i] */ + "ldr %[r0], [%[r1], %[r7]] \n\t" /* r0 = left[i] */ + + "lsrs %[r3], %[r0], #16 \n\t" /* r3 = a1 */ + "uxth %[r0], %[r0] \n\t" /* r0 = a0 */ + + "lsrs %[r5], %[r4], #16 \n\t" /* r5 = b1 */ + "uxth %[r4], %[r4] \n\t" /* r4 = b0 */ + + "movs %[r6], %[r3] \n\t" /* r6 = a1 */ + "muls %[r6], %[r5], %[r6] \n\t" /* r6 = a1 * b1 */ + "muls %[r3], %[r4], %[r3] \n\t" /* r3 = b0 * a1 */ + "muls %[r5], %[r0], %[r5] \n\t" /* r5 = a0 * b1 */ + "muls %[r0], %[r4], %[r0] \n\t" /* r0 = a0 * b0 */ + + /* Add middle terms */ + "lsls %[r4], %[r3], #16 \n\t" + "lsrs %[r3], %[r3], #16 \n\t" + "adds %[r0], %[r4] \n\t" + "adcs %[r6], %[r3] \n\t" + + "lsls %[r4], %[r5], #16 \n\t" + "lsrs %[r5], %[r5], #16 \n\t" + "adds %[r0], %[r4] \n\t" + "adcs %[r6], %[r5] \n\t" + + "mov %[r3], r10\n\t" + "mov %[r4], r11\n\t" + "mov %[r5], r12\n\t" + "adds %[r3], %[r0] \n\t" /* add low word to c0 */ + "adcs %[r4], %[r6] \n\t" /* add high word to c1, including carry */ + "movs %[r0], #0 \n\t" /* r0 = 0 (does not affect carry bit) */ + "adcs %[r5], %[r0] \n\t" /* add carry to c2 */ + + "mov %[r6], r14\n\t" /* r6 = k */ + + "adds %[r7], #4 \n\t" /* i += 4 */ + "cmp %[r7], r8 \n\t" /* i > (num_words - 1) (times 4)? */ + "bgt 4f \n\t" /* if so, exit the loop */ + "cmp %[r7], %[r6] \n\t" /* i <= k? */ + "ble 3b \n\t" /* if so, continue looping */ + + "4: \n\t" /* end inner loop */ + + "ldr %[r0], [sp, #0] \n\t" /* r0 = result */ + + "str %[r3], [%[r0], %[r6]] \n\t" /* result[k] = c0 */ + "mov %[r3], %[r4] \n\t" /* c0 = c1 */ + "mov %[r4], %[r5] \n\t" /* c1 = c2 */ + "movs %[r5], #0 \n\t" /* c2 = 0 */ + "adds %[r6], #4 \n\t" /* k += 4 */ + "cmp %[r6], r8 \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[r6], r9 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[r3], [%[r0], %[r6]] \n\t" /* result[num_words * 2 - 1] = c0 */ + "pop {%[r0]} \n\t" /* pop result off the stack */ + + RESUME_SYNTAX + : [r3] "+l" (num_words), [r4] "=&l" (r4), + [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7) + : [r0] "l" (result), [r1] "l" (left), [r2] "l" (right) + : "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +#endif +} +#define asm_mult 1 +#endif + +#if uECC_SQUARE_FUNC +#if !asm_square +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { +#if (uECC_PLATFORM != uECC_arm_thumb) + uint32_t c0 = 0; + uint32_t c1 = 0; + uint32_t c2 = 0; + uint32_t k = 0; + uint32_t i, tt; + uint32_t t0, t1; + + __asm__ volatile ( + ".syntax unified \n\t" + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[i], #0 \n\t" /* i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[i], %[k] \n\t" /* i = k */ + "subs %[i], %[last_word] \n\t" /* i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "subs %[tt], %[k], %[i] \n\t" /* tt = k-i */ + + "ldr %[t1], [%[left], %[tt]] \n\t" /* t1 = left[k - i] */ + "ldr %[t0], [%[left], %[i]] \n\t" /* t0 = left[i] */ + + "umull %[t0], %[t1], %[t0], %[t1] \n\t" /* (t0, t1) = left[i] * right[k - i] */ + + "cmp %[i], %[tt] \n\t" /* (i < k - i) ? */ + "bge 4f \n\t" /* if i >= k - i, skip */ + "adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */ + + "4: \n\t" + "adds %[c0], %[c0], %[t0] \n\t" /* add low word to c0 */ + "adcs %[c1], %[c1], %[t1] \n\t" /* add high word to c1, including carry */ + "adcs %[c2], %[c2], #0 \n\t" /* add carry to c2 */ + + "adds %[i], #4 \n\t" /* i += 4 */ + "cmp %[i], %[k] \n\t" /* i >= k? */ + "bge 5f \n\t" /* if so, exit the loop */ + "subs %[tt], %[k], %[i] \n\t" /* tt = k - i */ + "cmp %[i], %[tt] \n\t" /* i <= k - i? */ + "ble 3b \n\t" /* if so, continue looping */ + + "5: \n\t" /* end inner loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[k] = c0 */ + "mov %[c0], %[c1] \n\t" /* c0 = c1 */ + "mov %[c1], %[c2] \n\t" /* c1 = c2 */ + "movs %[c2], #0 \n\t" /* c2 = 0 */ + "adds %[k], #4 \n\t" /* k += 4 */ + "cmp %[k], %[last_word] \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[k], %[last_word], lsl #1 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, start with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[c0], [%[result], %[k]] \n\t" /* result[num_words * 2 - 1] = c0 */ + RESUME_SYNTAX + : [c0] "+r" (c0), [c1] "+r" (c1), [c2] "+r" (c2), + [k] "+r" (k), [i] "=&r" (i), [tt] "=&r" (tt), [t0] "=&r" (t0), [t1] "=&r" (t1) + : [result] "r" (result), [left] "r" (left), [last_word] "r" ((num_words - 1) * 4) + : "cc", "memory" + ); + +#else + uint32_t r3, r4, r5, r6, r7; + + __asm__ volatile ( + ".syntax unified \n\t" + "subs %[r2], #1 \n\t" /* r2 = num_words - 1 */ + "lsls %[r2], #2 \n\t" /* r2 = (num_words - 1) * 4 */ + "mov r8, %[r2] \n\t" /* r8 = (num_words - 1) * 4 */ + "lsls %[r2], #1 \n\t" /* r2 = (num_words - 1) * 8 */ + "mov r9, %[r2] \n\t" /* r9 = (num_words - 1) * 8 */ + "movs %[r2], #0 \n\t" /* c0 = 0 */ + "movs %[r3], #0 \n\t" /* c1 = 0 */ + "movs %[r4], #0 \n\t" /* c2 = 0 */ + "movs %[r5], #0 \n\t" /* k = 0 */ + + "push {%[r0]} \n\t" /* keep result on the stack */ + + "1: \n\t" /* outer loop (k < num_words) */ + "movs %[r6], #0 \n\t" /* r6 = i = 0 */ + "b 3f \n\t" + + "2: \n\t" /* outer loop (k >= num_words) */ + "movs %[r6], %[r5] \n\t" /* r6 = k */ + "mov %[r0], r8 \n\t" /* r0 = (num_words - 1) * 4 */ + "subs %[r6], %[r0] \n\t" /* r6 = i = k - (num_words - 1) (times 4) */ + + "3: \n\t" /* inner loop */ + "mov r10, %[r2] \n\t" + "mov r11, %[r3] \n\t" + "mov r12, %[r4] \n\t" + "mov r14, %[r5] \n\t" + "subs %[r7], %[r5], %[r6] \n\t" /* r7 = k - i */ + + "ldr %[r3], [%[r1], %[r7]] \n\t" /* r3 = left[k - i] */ + "ldr %[r0], [%[r1], %[r6]] \n\t" /* r0 = left[i] */ + + "lsrs %[r2], %[r0], #16 \n\t" /* r2 = a1 */ + "uxth %[r0], %[r0] \n\t" /* r0 = a0 */ + + "lsrs %[r4], %[r3], #16 \n\t" /* r4 = b1 */ + "uxth %[r3], %[r3] \n\t" /* r3 = b0 */ + + "movs %[r5], %[r2] \n\t" /* r5 = a1 */ + "muls %[r5], %[r4], %[r5] \n\t" /* r5 = a1 * b1 */ + "muls %[r2], %[r3], %[r2] \n\t" /* r2 = b0 * a1 */ + "muls %[r4], %[r0], %[r4] \n\t" /* r4 = a0 * b1 */ + "muls %[r0], %[r3], %[r0] \n\t" /* r0 = a0 * b0 */ + + /* Add middle terms */ + "lsls %[r3], %[r2], #16 \n\t" + "lsrs %[r2], %[r2], #16 \n\t" + "adds %[r0], %[r3] \n\t" + "adcs %[r5], %[r2] \n\t" + + "lsls %[r3], %[r4], #16 \n\t" + "lsrs %[r4], %[r4], #16 \n\t" + "adds %[r0], %[r3] \n\t" + "adcs %[r5], %[r4] \n\t" + + /* Add to acc, doubling if necessary */ + "mov %[r2], r10\n\t" + "mov %[r3], r11\n\t" + "mov %[r4], r12\n\t" + + "cmp %[r6], %[r7] \n\t" /* (i < k - i) ? */ + "bge 4f \n\t" /* if i >= k - i, skip */ + "movs %[r7], #0 \n\t" /* r7 = 0 */ + "adds %[r2], %[r0] \n\t" /* add low word to c0 */ + "adcs %[r3], %[r5] \n\t" /* add high word to c1, including carry */ + "adcs %[r4], %[r7] \n\t" /* add carry to c2 */ + "4: \n\t" + "movs %[r7], #0 \n\t" /* r7 = 0 */ + "adds %[r2], %[r0] \n\t" /* add low word to c0 */ + "adcs %[r3], %[r5] \n\t" /* add high word to c1, including carry */ + "adcs %[r4], %[r7] \n\t" /* add carry to c2 */ + + "mov %[r5], r14\n\t" /* r5 = k */ + + "adds %[r6], #4 \n\t" /* i += 4 */ + "cmp %[r6], %[r5] \n\t" /* i >= k? */ + "bge 5f \n\t" /* if so, exit the loop */ + "subs %[r7], %[r5], %[r6] \n\t" /* r7 = k - i */ + "cmp %[r6], %[r7] \n\t" /* i <= k - i? */ + "ble 3b \n\t" /* if so, continue looping */ + + "5: \n\t" /* end inner loop */ + + "ldr %[r0], [sp, #0] \n\t" /* r0 = result */ + + "str %[r2], [%[r0], %[r5]] \n\t" /* result[k] = c0 */ + "mov %[r2], %[r3] \n\t" /* c0 = c1 */ + "mov %[r3], %[r4] \n\t" /* c1 = c2 */ + "movs %[r4], #0 \n\t" /* c2 = 0 */ + "adds %[r5], #4 \n\t" /* k += 4 */ + "cmp %[r5], r8 \n\t" /* k <= (num_words - 1) (times 4) ? */ + "ble 1b \n\t" /* if so, loop back, start with i = 0 */ + "cmp %[r5], r9 \n\t" /* k <= (num_words * 2 - 2) (times 4) ? */ + "ble 2b \n\t" /* if so, loop back, with i = (k + 1) - num_words */ + /* end outer loop */ + + "str %[r2], [%[r0], %[r5]] \n\t" /* result[num_words * 2 - 1] = c0 */ + "pop {%[r0]} \n\t" /* pop result off the stack */ + + RESUME_SYNTAX + : [r2] "+l" (num_words), [r3] "=&l" (r3), [r4] "=&l" (r4), + [r5] "=&l" (r5), [r6] "=&l" (r6), [r7] "=&l" (r7) + : [r0] "l" (result), [r1] "l" (left) + : "r8", "r9", "r10", "r11", "r12", "r14", "cc", "memory" + ); +#endif +} +#define asm_square 1 +#endif +#endif /* uECC_SQUARE_FUNC */ + +#endif /* _UECC_ASM_ARM_H_ */ diff --git a/core/embed/ble_bootloader/uecc/asm_arm_mult_square.inc b/core/embed/ble_bootloader/uecc/asm_arm_mult_square.inc new file mode 100644 index 000000000..8907fc185 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/asm_arm_mult_square.inc @@ -0,0 +1,2311 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_MULT_SQUARE_H_ +#define _UECC_ASM_ARM_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_5 \ + "push {r3} \n\t" \ + "add r0, 12 \n\t" \ + "add r2, 12 \n\t" \ + "ldmia r1!, {r3,r4} \n\t" \ + "ldmia r2!, {r6,r7} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adc r10, r10, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 28 \n\t" \ + "sub r2, 20 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + "ldmia r1!, {r5} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adc r11, r11, r9 \n\t" \ + "stmia r0!, {r10, r11} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_5_TO_6 \ + "cmp r3, #5 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + "sub r2, #20 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r11, r14 \n\t" \ + "adc r12, r12, r9 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_6 \ + "push {r3} \n\t" \ + "add r0, 12 \n\t" \ + "add r2, 12 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + \ + "sub r0, 36 \n\t" \ + "sub r2, 24 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adc r14, r14, r11 \n\t" \ + "stmia r0!, {r12, r14} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_6_TO_7 \ + "cmp r3, #6 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "sub r2, #24 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_7 \ + "push {r3} \n\t" \ + "add r0, 24 \n\t" \ + "add r2, 24 \n\t" \ + "ldmia r1!, {r3} \n\t" \ + "ldmia r2!, {r6} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 20 \n\t" \ + "sub r2, 16 \n\t" \ + "ldmia r2!, {r6, r7, r8} \n\t" \ + "ldmia r1!, {r4, r5} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r12, r3, r7 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r9, r11, r4, r6 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adcs r12, r12, r11 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + \ + "sub r0, 44 \n\t" \ + "sub r1, 16 \n\t" \ + "sub r2, 28 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r9, r10, r3, r6 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r12, r3, r7 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r9, r11, r4, r6 \n\t" \ + "adds r10, r10, r9 \n\t" \ + "adcs r12, r12, r11 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r4, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r4, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "umull r10, r11, r3, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adc r14, r14, r11 \n\t" \ + "stmia r0!, {r12, r14} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_7_TO_8 \ + "cmp r3, #7 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high, r5 = right high */ \ + "ldr r4, [r1] \n\t" \ + "ldr r5, [r2] \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "sub r2, #28 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r10, r10, r6 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r9, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r10, r10, r11 \n\t" \ + "adcs r14, r14, r12 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r14, r14, r6 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "ldr r7, [r1], #4 \n\t" \ + "ldr r8, [r2], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "ldr r6, [r0] \n\t" \ + "adds r9, r9, r6 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + /* skip past already-loaded (r4, r5) */ \ + "ldr r7, [r1], #8 \n\t" \ + "ldr r8, [r2], #8 \n\t" \ + "mov r14, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r9, r9, r11 \n\t" \ + "adcs r10, r10, r12 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "umull r11, r12, r4, r5 \n\t" \ + "adds r11, r11, r10 \n\t" \ + "adc r12, r12, r14 \n\t" \ + "stmia r0!, {r11, r12} \n\t" + +#define FAST_MULT_ASM_8 \ + "push {r3} \n\t" \ + "add r0, 24 \n\t" \ + "add r2, 24 \n\t" \ + "ldmia r1!, {r3,r4} \n\t" \ + "ldmia r2!, {r6,r7} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adc r10, r10, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + \ + "sub r0, 28 \n\t" \ + "sub r2, 20 \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + "ldmia r1!, {r5} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adc r11, r11, r9 \n\t" \ + "stmia r0!, {r10, r11} \n\t" \ + \ + "sub r0, 52 \n\t" \ + "sub r1, 20 \n\t" \ + "sub r2, 32 \n\t" \ + "ldmia r1!, {r3,r4,r5} \n\t" \ + "ldmia r2!, {r6,r7,r8} \n\t" \ + \ + "umull r11, r12, r3, r6 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r9, r3, r7 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r11, r14, r4, r6 \n\t" \ + "adds r12, r12, r11 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r3, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r5, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r4, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r5, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r1!, {r5} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r3, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r5, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r4, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r5, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r1!, {r4} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r5, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r3, r8 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r14, #0 \n\t" \ + "umull r9, r10, r5, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r3, r6 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "umull r9, r10, r4, r8 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "ldr r9, [r0] \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adcs r12, r12, #0 \n\t" \ + "adc r14, r14, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "ldmia r2!, {r8} \n\t" \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r5, r8 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r3, r7 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "umull r10, r11, r4, r6 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "ldr r10, [r0] \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r14, r14, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "ldmia r2!, {r6} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r5, r6 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r8 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r4, r7 \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "ldr r11, [r0] \n\t" \ + "adds r14, r14, r11 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r14} \n\t" \ + \ + "ldmia r2!, {r7} \n\t" \ + "mov r11, #0 \n\t" \ + "umull r12, r14, r5, r7 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r3, r6 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "umull r12, r14, r4, r8 \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, r14 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "ldr r12, [r0] \n\t" \ + "adds r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r9} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r14, r9, r3, r7 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r14, r9, r4, r6 \n\t" \ + "adds r10, r10, r14 \n\t" \ + "adcs r11, r11, r9 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r10} \n\t" \ + \ + "umull r9, r10, r4, r7 \n\t" \ + "adds r11, r11, r9 \n\t" \ + "adc r12, r12, r10 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + "pop {r3} \n\t" + +#define FAST_SQUARE_ASM_5 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6} \n\t" \ + "push {r1} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "umull r1, r14, r3, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "umull r1, r14, r3, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "umull r1, r14, r4, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r6 \n\t" \ + "umull r1, r14, r4, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r4, r6 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r5, r5 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r5, r6 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r6, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_5_TO_6 \ + "cmp r2, #5 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r6,r7,r8,r9,r10,r11} \n\t" \ + "umull r3, r4, r6, r11 \n\t" \ + "umull r6, r5, r7, r11 \n\t" \ + "adds r4, r4, r6 \n\t" \ + "umull r7, r6, r8, r11 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "umull r8, r7, r9, r11 \n\t" \ + "adcs r6, r6, r8 \n\t" \ + "umull r9, r8, r10, r11 \n\t" \ + "adcs r7, r7, r9 \n\t" \ + "adcs r8, r8, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r9, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0], #4 \n\t" \ + "adds r3, r3, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r4, r4, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r5, r5, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r6, r6, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r7, r7, r14 \n\t" \ + "adcs r8, r8, #0 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "sub r0, #20 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r8, r9, r11, r11 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9} \n\t" + +#define FAST_SQUARE_ASM_6 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6,r7} \n\t" \ + "push {r1} \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "umull r1, r14, r3, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "umull r1, r14, r3, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "umull r1, r14, r4, r4 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "umull r1, r14, r3, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "umull r1, r14, r4, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "umull r1, r14, r4, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "umull r1, r14, r5, r5 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r9, r9, r14 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r4, r7 \n\t" \ + "umull r1, r14, r5, r6 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r14 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r5, r7 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r6, r6 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r6, r7 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r7, r7 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_6_TO_7 \ + "cmp r2, #6 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r6,r7,r8,r9,r10,r11,r12} \n\t" \ + "umull r3, r4, r6, r12 \n\t" \ + "umull r6, r5, r7, r12 \n\t" \ + "adds r4, r4, r6 \n\t" \ + "umull r7, r6, r8, r12 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "umull r8, r7, r9, r12 \n\t" \ + "adcs r6, r6, r8 \n\t" \ + "umull r9, r8, r10, r12 \n\t" \ + "adcs r7, r7, r9 \n\t" \ + "umull r10, r9, r11, r12 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r10, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r14, [r0], #4 \n\t" \ + "adds r3, r3, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r4, r4, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r5, r5, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r6, r6, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r7, r7, r14 \n\t" \ + "ldr r14, [r0], #4 \n\t" \ + "adcs r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "sub r0, #24 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r9, r10, r12, r12 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10} \n\t" + +#define FAST_SQUARE_ASM_7 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2, r3, r4, r5, r6, r7, r8} \n\t" \ + "push {r1} \n\t" \ + "sub r1, 4 \n\t" \ + \ + "add r0, 24 \n\t" \ + "umull r9, r10, r2, r8 \n\t" \ + "stmia r0!, {r9, r10} \n\t" \ + "sub r0, 32 \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r4 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r3, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r4 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r5 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r2} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r4, r2 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r5, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r6, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r6, r2 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r7, r7 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r7, r2 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r2, r2 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_7_TO_8 \ + "cmp r2, #7 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r6,r7,r8,r9,r10,r11,r12,r14} \n\t" \ + "umull r3, r4, r6, r14 \n\t" \ + "umull r6, r5, r7, r14 \n\t" \ + "adds r4, r4, r6 \n\t" \ + "umull r7, r6, r8, r14 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "umull r8, r7, r9, r14 \n\t" \ + "adcs r6, r6, r8 \n\t" \ + "umull r9, r8, r10, r14 \n\t" \ + "adcs r7, r7, r9 \n\t" \ + "umull r10, r9, r11, r14 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "umull r11, r10, r12, r14 \n\t" \ + "adcs r9, r9, r11 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r11, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "sub r0, #28 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r10, r11, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10,r11} \n\t" + +#define FAST_SQUARE_ASM_8 \ + "push {r2} \n\t" \ + "ldmia r1!, {r2,r3,r4,r5,r6,r7,r8,r9} \n\t" \ + "push {r1} \n\t" \ + "sub r1, 8 \n\t" \ + \ + "add r0, 24 \n\t" \ + "umull r10, r11, r2, r8 \n\t" \ + "umull r12, r14, r2, r9 \n\t" \ + "umull r8, r9, r3, r9 \n\t" \ + "adds r11, r11, r12 \n\t" \ + "adcs r12, r14, r8 \n\t" \ + "adcs r14, r9, #0 \n\t" \ + "stmia r0!, {r10, r11, r12, r14} \n\t" \ + "sub r0, 40 \n\t" \ + \ + "umull r11, r12, r2, r2 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umull r10, r11, r2, r3 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r11, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r12, r12, r10 \n\t" \ + "adcs r8, r8, r11 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r11, r12, r2, r4 \n\t" \ + "adds r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "umull r11, r12, r3, r3 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r5 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r4 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r2, r6 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r3, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r4 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r2, r7 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r3, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r5 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r2} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r3, r7 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r4, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r5 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r3, r2 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r4, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r6 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "ldmia r1!, {r3} \n\t" \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r4, r2 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r5, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r6 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r4, r3 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r5, r2 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r6, r7 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "ldr r14, [r0] \n\t" \ + "adds r8, r8, r14 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umull r8, r9, r5, r3 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r6, r2 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adc r10, r10, r10 \n\t" \ + "mov r14, r9 \n\t" \ + "umlal r8, r9, r7, r7 \n\t" \ + "cmp r14, r9 \n\t" \ + "it hi \n\t" \ + "adchi r10, r10, #0 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umull r8, r11, r6, r3 \n\t" \ + "mov r14, r11 \n\t" \ + "umlal r8, r11, r7, r2 \n\t" \ + "cmp r14, r11 \n\t" \ + "it hi \n\t" \ + "adchi r12, r12, #0 \n\t" \ + "adds r8, r8, r8 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adc r12, r12, r12 \n\t" \ + "adds r8, r8, r9 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "adc r12, r12, #0 \n\t" \ + "stmia r0!, {r8} \n\t" \ + \ + "mov r8, #0 \n\t" \ + "umull r1, r10, r7, r3 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "umull r1, r10, r2, r2 \n\t" \ + "adds r11, r11, r1 \n\t" \ + "adcs r12, r12, r10 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "stmia r0!, {r11} \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umull r1, r10, r2, r3 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "adds r12, r12, r1 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "adc r11, r11, #0 \n\t" \ + "stmia r0!, {r12} \n\t" \ + \ + "umull r1, r10, r3, r3 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "adcs r11, r11, r10 \n\t" \ + "stmia r0!, {r8, r11} \n\t" \ + "pop {r1, r2} \n\t" + +#endif /* _UECC_ASM_ARM_MULT_SQUARE_H_ */ diff --git a/core/embed/ble_bootloader/uecc/asm_arm_mult_square_umaal.inc b/core/embed/ble_bootloader/uecc/asm_arm_mult_square_umaal.inc new file mode 100644 index 000000000..c554d20e3 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/asm_arm_mult_square_umaal.inc @@ -0,0 +1,1202 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_ARM_MULT_SQUARE_H_ +#define _UECC_ASM_ARM_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_5 \ + "push {r3} \n\t" \ + "ldmia r2!, {r3, r4, r5, r6, r7} \n\t" \ + "push {r2} \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "umull r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "mov r14, #0 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "ldr r2, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r3, r2 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r2 \n\t" \ + "umaal r10, r11, r5, r2 \n\t" \ + "umaal r11, r12, r6, r2 \n\t" \ + "umaal r12, r14, r7, r2 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" \ + "str r14, [r0], #4 \n\t" \ + \ + "pop {r2, r3} \n\t" + +#define FAST_MULT_ASM_5_TO_6 \ + "cmp r3, #5 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high */ \ + "ldr r4, [r1] \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + "sub r2, #20 \n\t" \ + \ + /* Do right side */ \ + "ldr r14, [r2], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r0], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r7, [r0], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r8, [r0], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r9, [r0], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r10, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "sub r0, #20 \n\t" \ + \ + /* r4 = right high */ \ + "ldr r4, [r2], #4 \n\t" \ + \ + /* Do left side */ \ + "ldr r14, [r1], #4 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r12, r5, r4, r14 \n\t" \ + "str r12, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "stmia r0!, {r9, r10} \n\t" + +#define FAST_MULT_ASM_6 \ + "ldmia r2!, {r4, r5, r6} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "ldmia r2!, {r4, r5, r6} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" + +#define FAST_MULT_ASM_6_TO_7 \ + "cmp r3, #6 \n\t" \ + "beq 1f \n\t" \ + \ + /* r4 = left high */ \ + "ldr r4, [r1] \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + "sub r2, #24 \n\t" \ + \ + /* Do right side */ \ + "ldr r14, [r2], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r0], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r7, [r0], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r8, [r0], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r9, [r0], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r10, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r11, [r0], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "sub r0, #24 \n\t" \ + \ + /* r4 = right high */ \ + "ldr r4, [r2], #4 \n\t" \ + \ + /* Do left side */ \ + "ldr r14, [r1], #4 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r12, r5, r4, r14 \n\t" \ + "str r12, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "str r9, [r0], #4 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "stmia r0!, {r10, r11} \n\t" + +#define FAST_MULT_ASM_7 \ + "ldmia r2!, {r4, r5, r6, r7} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "ldmia r2!, {r4, r5, r6} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" + +#define FAST_MULT_ASM_7_TO_8 \ + "cmp r3, #7 \n\t" \ + "beq 1f \n\t" \ + "push {r3} \n\t" \ + \ + /* r4 = left high */ \ + "ldr r4, [r1] \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + "sub r2, #28 \n\t" \ + \ + /* Do right side */ \ + "ldr r14, [r2], #4 \n\t" \ + "mov r5, #0 \n\t" \ + "ldr r6, [r0], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r7, [r0], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r8, [r0], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r9, [r0], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r10, [r0], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r11, [r0], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "ldr r14, [r2], #4 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "umaal r11, r12, r4, r14 \n\t" \ + "sub r0, #28 \n\t" \ + \ + /* r4 = right high */ \ + "ldr r4, [r2], #4 \n\t" \ + \ + /* Do left side */ \ + "ldr r14, [r1], #4 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r3, r5, r4, r14 \n\t" \ + "str r3, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r5, r6, r4, r14 \n\t" \ + "str r5, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r6, r7, r4, r14 \n\t" \ + "str r6, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r7, r8, r4, r14 \n\t" \ + "str r7, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r9, r10, r4, r14 \n\t" \ + "str r9, [r0], #4 \n\t" \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r10, r11, r4, r14 \n\t" \ + "str r10, [r0], #4 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umaal r11, r12, r4, r14 \n\t" \ + "stmia r0!, {r11, r12} \n\t" \ + "pop {r3} \n\t" + +#define FAST_MULT_ASM_8 \ + "ldmia r2!, {r4, r5, r6, r7} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "umull r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" \ + \ + "sub r0, #32 \n\t" \ + "sub r1, #32 \n\t" \ + "ldmia r2!, {r4, r5, r6, r7} \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "mov r11, #0 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "mov r12, #0 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "ldr r14, [r1], #4 \n\t" \ + "ldr r8, [r0] \n\t" \ + "umaal r8, r9, r4, r14 \n\t" \ + "str r8, [r0], #4 \n\t" \ + "umaal r9, r10, r5, r14 \n\t" \ + "umaal r10, r11, r6, r14 \n\t" \ + "umaal r11, r12, r7, r14 \n\t" \ + \ + "str r9, [r0], #4 \n\t" \ + "str r10, [r0], #4 \n\t" \ + "str r11, [r0], #4 \n\t" \ + "str r12, [r0], #4 \n\t" + +#define FAST_SQUARE_ASM_5 \ + "ldmia r1!, {r9,r10,r11,r12,r14} \n\t" \ + "push {r1, r2} \n\t" \ + \ + "umull r1, r2, r10, r9 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r2, r3, r11, r9 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r12, r9 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r14, r9 \n\t" \ + \ + "mov r6, #0 \n\t" \ + "umaal r6, r3, r11, r10 \n\t" \ + "umaal r3, r4, r12, r10 \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + \ + "umull r7, r8, r9, r9 \n\t" \ + /* Store carry in r9 */ \ + "mov r9, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + "adds r8, r8, r1 \n\t" \ + "stmia r0!, {r7,r8} \n\t" \ + \ + "umull r7, r8, r10, r10 \n\t" \ + "adcs r7, r7, r2 \n\t" \ + "adcs r8, r8, r6 \n\t" \ + "stmia r0!, {r7,r8} \n\t" \ + \ + "umaal r4, r5, r14, r10 \n\t" \ + /* Store carry in r10 */ \ + "mov r10, #0 \n\t" \ + "adc r10, r10, #0 \n\t" \ + \ + "mov r1, #0 \n\t" \ + "umaal r1, r4, r12, r11 \n\t" \ + "umaal r4, r5, r14, r11 \n\t" \ + \ + "mov r2, #0 \n\t" \ + "umaal r2, r5, r14, r12 \n\t" \ + /* Load carry from r9 */ \ + "lsrs r9, #1 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + /* r9 is 0 now */ \ + "adc r9, r9, #0 \n\t" \ + \ + /* Use carry from r10 */ \ + "umaal r3, r10, r11, r11 \n\t" \ + "adds r10, r10, r1 \n\t" \ + "stmia r0!, {r3,r10} \n\t" \ + \ + "umull r6, r10, r12, r12 \n\t" \ + "adcs r6, r6, r4 \n\t" \ + "adcs r10, r10, r2 \n\t" \ + "stmia r0!, {r6,r10} \n\t" \ + \ + "umull r6, r10, r14, r14 \n\t" \ + "adcs r6, r6, r5 \n\t" \ + "adcs r10, r10, r9 \n\t" \ + "stmia r0!, {r6,r10} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_5_TO_6 \ + "cmp r2, #5 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #20 \n\t" \ + "sub r1, #20 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r5,r6,r7,r8,r9,r14} \n\t" \ + "umull r3, r4, r5, r14 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r14 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r7, r14 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r8, r14 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r7, r8, r9, r14 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r9, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "adcs r8, r8, #0 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "sub r0, #20 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r8, r9, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9} \n\t" + +#define FAST_SQUARE_ASM_6 \ + "ldmia r1!, {r8,r9,r10,r11,r12,r14} \n\t" \ + "push {r1, r2} \n\t" \ + \ + "umull r1, r2, r9, r8 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r2, r3, r10, r8 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r11, r8 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r12, r8 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r14, r8 \n\t" \ + \ + "mov r7, #0 \n\t" \ + "umaal r7, r3, r10, r9 \n\t" \ + "umaal r3, r4, r11, r9 \n\t" \ + "umaal r4, r5, r12, r9 \n\t" \ + "push {r4, r5} \n\t" \ + "adds r1, r1, r1 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + \ + "umull r4, r5, r8, r8 \n\t" \ + /* Store carry in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + "adds r5, r5, r1 \n\t" \ + "stmia r0!, {r4,r5} \n\t" \ + \ + "umull r4, r5, r9, r9 \n\t" \ + "adcs r4, r4, r2 \n\t" \ + "adcs r5, r5, r7 \n\t" \ + "stmia r0!, {r4,r5} \n\t" \ + \ + "pop {r4, r5} \n\t" \ + "umaal r5, r6, r14, r9 \n\t" \ + /* Store carry in r9 */ \ + "mov r9, #0 \n\t" \ + "adc r9, r9, #0 \n\t" \ + \ + "mov r1, #0 \n\t" \ + "umaal r1, r4, r11, r10 \n\t" \ + "umaal r4, r5, r12, r10 \n\t" \ + "umaal r5, r6, r14, r10 \n\t" \ + \ + "mov r2, #0 \n\t" \ + "umaal r2, r5, r12, r11 \n\t" \ + "umaal r5, r6, r14, r11 \n\t" \ + \ + "mov r7, #0 \n\t" \ + "umaal r7, r6, r14, r12 \n\t" \ + \ + /* Load carry from r8 */ \ + "lsrs r8, #1 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + /* Use carry from r9 */ \ + "umaal r3, r9, r10, r10 \n\t" \ + "adds r9, r9, r1 \n\t" \ + "stmia r0!, {r3,r9} \n\t" \ + \ + "umull r9, r10, r11, r11 \n\t" \ + "adcs r9, r9, r4 \n\t" \ + "adcs r10, r10, r2 \n\t" \ + "stmia r0!, {r9,r10} \n\t" \ + \ + "umull r9, r10, r12, r12 \n\t" \ + "adcs r9, r9, r5 \n\t" \ + "adcs r10, r10, r7 \n\t" \ + "stmia r0!, {r9,r10} \n\t" \ + \ + "umull r9, r10, r14, r14 \n\t" \ + "adcs r9, r9, r6 \n\t" \ + "adcs r10, r10, r8 \n\t" \ + "stmia r0!, {r9,r10} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_6_TO_7 \ + "cmp r2, #6 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #24 \n\t" \ + "sub r1, #24 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r5,r6,r7,r8,r9,r10,r14} \n\t" \ + "umull r3, r4, r5, r14 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r14 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r7, r14 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r8, r14 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r7, r8, r9, r14 \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r10, r14 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r10, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "adcs r9, r9, #0 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "sub r0, #24 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r9, r10, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10} \n\t" + +#define FAST_SQUARE_ASM_7 \ + "ldmia r1!, {r9,r10,r11,r12} \n\t" \ + "push {r2} \n\t" \ + \ + "umull r14, r2, r10, r9 \n\t" \ + "mov r3, #0 \n\t" \ + "umaal r2, r3, r11, r9 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r12, r9 \n\t" \ + \ + "mov r5, #0 \n\t" \ + "umaal r5, r3, r11, r10 \n\t" \ + "adds r14, r14, r14 \n\t" \ + "adcs r2, r2, r2 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + /* Store carry in r7 */ \ + "mov r7, #0 \n\t" \ + "adc r7, r7, #0 \n\t" \ + \ + "umull r6, r8, r9, r9 \n\t" \ + "adds r8, r8, r14 \n\t" \ + "stmia r0!, {r6,r8} \n\t" \ + \ + "umull r6, r8, r10, r10 \n\t" \ + "adcs r6, r6, r2 \n\t" \ + "adcs r8, r8, r5 \n\t" \ + "stmia r0!, {r6,r8} \n\t" \ + /* Store carry in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "ldmia r1!, {r2, r6, r14} \n\t" \ + "push {r1} \n\t" \ + "umaal r3, r4, r2, r9 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r9 \n\t" \ + "mov r1, #0 \n\t" \ + "umaal r5, r1, r14, r9 \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umaal r3, r9, r12, r10 \n\t" \ + "umaal r9, r4, r2, r10 \n\t" \ + "umaal r4, r5, r6, r10 \n\t" \ + "umaal r5, r1, r14, r10 \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umaal r10, r9, r12, r11 \n\t" \ + "umaal r9, r4, r2, r11 \n\t" \ + "umaal r4, r5, r6, r11 \n\t" \ + "umaal r5, r1, r14, r11 \n\t" \ + \ + /* Load carry from r7 */ \ + "lsrs r7, #1 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + /* Store carry back in r7 */ \ + "adc r7, r7, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r3, r8, r11, r11 \n\t" \ + "adds r8, r8, r10 \n\t" \ + "stmia r0!, {r3,r8} \n\t" \ + /* Store carry back in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "mov r3, #0 \n\t" \ + "umaal r3, r4, r2, r12 \n\t" \ + "umaal r4, r5, r6, r12 \n\t" \ + "umaal r5, r1, r14, r12 \n\t" \ + \ + "mov r10, #0 \n\t" \ + "umaal r10, r5, r6, r2 \n\t" \ + "umaal r5, r1, r14, r2 \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umaal r11, r1, r14, r6 \n\t" \ + \ + /* Load carry from r7 */ \ + "lsrs r7, #1 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + "adc r7, r7, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r8, r9, r12, r12 \n\t" \ + "adds r9, r9, r3 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r2, r2 \n\t" \ + "adcs r8, r8, r4 \n\t" \ + "adcs r9, r9, r10 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r6, r6 \n\t" \ + "adcs r8, r8, r5 \n\t" \ + "adcs r9, r9, r11 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r14, r14 \n\t" \ + "adcs r8, r8, r1 \n\t" \ + "adcs r9, r9, r7 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + "pop {r1, r2} \n\t" + +#define FAST_SQUARE_ASM_7_TO_8 \ + "cmp r2, #7 \n\t" \ + "beq 1f \n\t" \ + \ + "sub r0, #28 \n\t" \ + "sub r1, #28 \n\t" \ + \ + /* Do off-center multiplication */ \ + "ldmia r1!, {r5,r6,r7,r8,r9,r10,r11,r14} \n\t" \ + "umull r3, r4, r5, r14 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r6, r14 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r7, r14 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r8, r14 \n\t" \ + "mov r8, #0 \n\t" \ + "umaal r7, r8, r9, r14 \n\t" \ + "mov r9, #0 \n\t" \ + "umaal r8, r9, r10, r14 \n\t" \ + "mov r10, #0 \n\t" \ + "umaal r9, r10, r11, r14 \n\t" \ + \ + /* Multiply by 2 */ \ + "mov r11, #0 \n\t" \ + "adds r3, r3, r3 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adcs r8, r8, r8 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r10, r10, r10 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + \ + /* Add into previous */ \ + "ldr r12, [r0], #4 \n\t" \ + "adds r3, r3, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r4, r4, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r5, r5, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r6, r6, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r7, r7, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "ldr r12, [r0], #4 \n\t" \ + "adcs r9, r9, r12 \n\t" \ + "adcs r10, r10, #0 \n\t" \ + "adcs r11, r11, #0 \n\t" \ + "sub r0, #28 \n\t" \ + \ + /* Perform center multiplication */ \ + "umlal r10, r11, r14, r14 \n\t" \ + "stmia r0!, {r3,r4,r5,r6,r7,r8,r9,r10,r11} \n\t" + +#define FAST_SQUARE_ASM_8 \ + "ldmia r1!, {r10,r11,r12,r14} \n\t" \ + "push {r2} \n\t" \ + \ + "umull r2, r3, r11, r10 \n\t" \ + "mov r4, #0 \n\t" \ + "umaal r3, r4, r12, r10 \n\t" \ + "mov r5, #0 \n\t" \ + "umaal r4, r5, r14, r10 \n\t" \ + \ + "mov r6, #0 \n\t" \ + "umaal r6, r4, r12, r11 \n\t" \ + "adds r2, r2, r2 \n\t" \ + "adcs r3, r3, r3 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + /* Store carry in r7 */ \ + "mov r7, #0 \n\t" \ + "adc r7, r7, #0 \n\t" \ + \ + "umull r8, r9, r10, r10 \n\t" \ + "adds r9, r9, r2 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + \ + "umull r8, r9, r11, r11 \n\t" \ + "adcs r8, r8, r3 \n\t" \ + "adcs r9, r9, r6 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + /* Store carry in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "ldmia r1!, {r2, r3} \n\t" \ + "push {r1} \n\t" \ + "umaal r4, r5, r2, r10 \n\t" \ + "mov r6, #0 \n\t" \ + "umaal r5, r6, r3, r10 \n\t" \ + \ + "mov r9, #0 \n\t" \ + "umaal r9, r4, r14, r11 \n\t" \ + "umaal r4, r5, r2, r11 \n\t" \ + \ + "mov r1, #0 \n\t" \ + "umaal r1, r4, r14, r12 \n\t" \ + \ + /* Load carry from r7 */ \ + "lsrs r7, #1 \n\t" \ + "adcs r9, r9, r9 \n\t" \ + "adcs r1, r1, r1 \n\t" \ + /* Store carry back in r7 */ \ + "adc r7, r7, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r8, r9, r12, r12 \n\t" \ + "adds r9, r9, r1 \n\t" \ + "stmia r0!, {r8,r9} \n\t" \ + /* Store carry back in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "pop {r1} \n\t" \ + /* TODO could fix up r1 value on stack here */ \ + /* and leave the value on the stack (rather */ \ + /* than popping) if supporting curves > 256 bits */ \ + "ldr r9, [r1], #4 \n\t" \ + "ldr r1, [r1] \n\t" \ + \ + "push {r7} \n\t" \ + "umaal r5, r6, r9, r10 \n\t" \ + "mov r7, #0 \n\t" \ + "umaal r6, r7, r1, r10 \n\t" \ + /* Carry now stored in r10 */ \ + "pop {r10} \n\t" \ + \ + "umaal r4, r5, r3, r11 \n\t" \ + "umaal r5, r6, r9, r11 \n\t" \ + "umaal r6, r7, r1, r11 \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umaal r11, r4, r2, r12 \n\t" \ + "umaal r4, r5, r3, r12 \n\t" \ + "umaal r5, r6, r9, r12 \n\t" \ + "umaal r6, r7, r1, r12 \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umaal r12, r4, r2, r14 \n\t" \ + "umaal r4, r5, r3, r14 \n\t" \ + "umaal r5, r6, r9, r14 \n\t" \ + "umaal r6, r7, r1, r14 \n\t" \ + \ + /* Load carry from r10 */ \ + "lsrs r10, #1 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adc r10, r10, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r8, r11, r14, r14 \n\t" \ + "adds r11, r11, r12 \n\t" \ + "stmia r0!, {r8,r11} \n\t" \ + /* Store carry back in r8 */ \ + "mov r8, #0 \n\t" \ + "adc r8, r8, #0 \n\t" \ + \ + "mov r11, #0 \n\t" \ + "umaal r11, r5, r3, r2 \n\t" \ + "umaal r5, r6, r9, r2 \n\t" \ + "umaal r6, r7, r1, r2 \n\t" \ + \ + "mov r12, #0 \n\t" \ + "umaal r12, r6, r9, r3 \n\t" \ + "umaal r6, r7, r1, r3 \n\t" \ + \ + "mov r14, #0 \n\t" \ + "umaal r14, r7, r1, r9 \n\t" \ + \ + /* Load carry from r10 */ \ + "lsrs r10, #1 \n\t" \ + "adcs r4, r4, r4 \n\t" \ + "adcs r11, r11, r11 \n\t" \ + "adcs r5, r5, r5 \n\t" \ + "adcs r12, r12, r12 \n\t" \ + "adcs r6, r6, r6 \n\t" \ + "adcs r14, r14, r14 \n\t" \ + "adcs r7, r7, r7 \n\t" \ + "adc r10, r10, #0 \n\t" \ + \ + /* Use carry from r8 */ \ + "umaal r4, r8, r2, r2 \n\t" \ + "adds r8, r8, r11 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + \ + "umull r4, r8, r3, r3 \n\t" \ + "adcs r4, r4, r5 \n\t" \ + "adcs r8, r8, r12 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + \ + "umull r4, r8, r9, r9 \n\t" \ + "adcs r4, r4, r6 \n\t" \ + "adcs r8, r8, r14 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + \ + "umull r4, r8, r1, r1 \n\t" \ + "adcs r4, r4, r7 \n\t" \ + "adcs r8, r8, r10 \n\t" \ + "stmia r0!, {r4,r8} \n\t" \ + /* TODO pop {r1, r2} if supporting curves > 256 bits */ \ + "pop {r2} \n\t" + +#endif /* _UECC_ASM_ARM_MULT_SQUARE_H_ */ diff --git a/core/embed/ble_bootloader/uecc/asm_avr.inc b/core/embed/ble_bootloader/uecc/asm_avr.inc new file mode 100644 index 000000000..c14bf5554 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/asm_avr.inc @@ -0,0 +1,1089 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_AVR_H_ +#define _UECC_ASM_AVR_H_ + +#if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #define uECC_MIN_WORDS 32 +#endif +#if uECC_SUPPORTS_secp224r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 28 +#endif +#if uECC_SUPPORTS_secp192r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 24 +#endif +#if uECC_SUPPORTS_secp160r1 + #undef uECC_MIN_WORDS + #define uECC_MIN_WORDS 20 +#endif + +#if __AVR_HAVE_EIJMP_EICALL__ + #define IJMP "eijmp \n\t" +#else + #define IJMP "ijmp \n\t" +#endif + +#if (uECC_OPTIMIZATION_LEVEL >= 2) + +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { + volatile uECC_word_t *v = vli; + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(1f) \n\t" + "ldi r31, pm_hi8(1f) \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + IJMP + #endif + + REPEAT(uECC_MAX_WORDS, "st x+, __zero_reg__ \n\t") + "1: \n\t" + : "+x" (v) + : [num] "r" (num_words) + : + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "r30", "r31", "cc" + #endif + ); +} +#define asm_clear 1 + +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { + volatile uECC_word_t *d = dest; + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(1f) \n\t" + "ldi r31, pm_hi8(1f) \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + IJMP + #endif + + REPEAT(uECC_MAX_WORDS, + "ld r0, y+ \n\t" + "st x+, r0 \n\t") + "1: \n\t" + : "+x" (d), "+y" (src) + : [num] "r" ((uint8_t)(num_words * 2)) + : "r0" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + , "r30", "r31", "cc" + #endif + ); +} +#define asm_set 1 + +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { + volatile uECC_word_t *v = vli; + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(1f) \n\t" + "ldi r31, pm_hi8(1f) \n\t" + "sub r30, %[jump] \n\t" + "sbc r31, __zero_reg__ \n\t" + #endif + + "add r26, %[num] \n\t" + "adc r27, __zero_reg__ \n\t" + "ld r0, -x \n\t" + "lsr r0 \n\t" + "st x, r0 \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + IJMP + #endif + + REPEAT(DEC(uECC_MAX_WORDS), + "ld r0, -x \n\t" + "ror r0 \n\t" + "st x, r0 \n\t") + "1: \n\t" + : "+x" (v) + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + : [num] "r" (num_words), [jump] "r" ((uint8_t)(3 * (num_words - 1))) + : "r0", "r30", "r31", "cc" + #else + : [num] "r" (num_words) + : "r0", "cc" + #endif + ); +} +#define asm_rshift1 1 + +#define ADD_RJPM_TABLE(N) \ + "movw r30, %A[result] \n\t" \ + "rjmp add_%=_" #N " \n\t" + +#define ADD_RJPM_DEST(N) \ + "add_%=_" #N ":" \ + "ld %[clb], x+ \n\t" \ + "ld %[rb], y+ \n\t" \ + "adc %[clb], %[rb] \n\t" \ + "st z+, %[clb] \n\t" + +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t carry; + uint8_t right_byte; + + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(add_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "ldi r31, pm_hi8(add_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + #endif + + "clc \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + IJMP + REPEATM(uECC_MAX_WORDS, ADD_RJPM_TABLE) + #endif + + REPEATM(uECC_MAX_WORDS, ADD_RJPM_DEST) + + "mov %[clb], __zero_reg__ \n\t" + "adc %[clb], %[clb] \n\t" /* Store carry bit. */ + + : "+x" (left), "+y" (right), + [clb] "=&r" (carry), [rb] "=&r" (right_byte) + : [result] "r" (r), [num] "r" ((uint8_t)(num_words * 2)) + : "r30", "r31", "cc" + ); + return carry; +} +#define asm_add 1 + +#define SUB_RJPM_TABLE(N) \ + "movw r30, %A[result] \n\t" \ + "rjmp sub_%=_" #N " \n\t" + +#define SUB_RJPM_DEST(N) \ + "sub_%=_" #N ":" \ + "ld %[clb], x+ \n\t" \ + "ld %[rb], y+ \n\t" \ + "sbc %[clb], %[rb] \n\t" \ + "st z+, %[clb] \n\t" + +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t carry; + uint8_t right_byte; + + __asm__ volatile ( + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + "ldi r30, pm_lo8(sub_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "ldi r31, pm_hi8(sub_%=_" STR(uECC_MAX_WORDS) ") \n\t" + "sub r30, %[num] \n\t" + "sbc r31, __zero_reg__ \n\t" + #endif + + "clc \n\t" + #if (uECC_MAX_WORDS != uECC_MIN_WORDS) + IJMP + REPEATM(uECC_MAX_WORDS, SUB_RJPM_TABLE) + #endif + + REPEATM(uECC_MAX_WORDS, SUB_RJPM_DEST) + + "mov %[clb], __zero_reg__ \n\t" + "adc %[clb], %[clb] \n\t" /* Store carry bit. */ + + : "+x" (left), "+y" (right), + [clb] "=&r" (carry), [rb] "=&r" (right_byte) + : [result] "r" (r), [num] "r" ((uint8_t)(num_words * 2)) + : "r30", "r31", "cc" + ); + return carry; +} +#define asm_sub 1 + +#if (uECC_OPTIMIZATION_LEVEL >= 3) + +#include "asm_avr_mult_square.inc" + +__attribute((noinline)) +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + /* num_words should already be in r18. */ + register wordcount_t r18 __asm__("r18") = num_words; + + __asm__ volatile ( + "push r18 \n\t" +#if (uECC_MIN_WORDS == 20) + FAST_MULT_ASM_20 + "pop r18 \n\t" + #if (uECC_MAX_WORDS > 20) + FAST_MULT_ASM_20_TO_24 + #endif + #if (uECC_MAX_WORDS > 24) + FAST_MULT_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_MULT_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 24) + FAST_MULT_ASM_24 + "pop r18 \n\t" + #if (uECC_MAX_WORDS > 24) + FAST_MULT_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_MULT_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 28) + FAST_MULT_ASM_28 + "pop r18 \n\t" + #if (uECC_MAX_WORDS > 28) + FAST_MULT_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 32) + FAST_MULT_ASM_32 + "pop r18 \n\t" +#endif + "2: \n\t" + "eor r1, r1 \n\t" + : "+x" (left), "+y" (right), "+z" (result) + : "r" (r18) + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r19", "r20", + "r21", "r22", "r23", "r24", "r25", "cc" + ); +} +#define asm_mult 1 + +#if uECC_SQUARE_FUNC +__attribute((noinline)) +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + /* num_words should already be in r20. */ + register wordcount_t r20 __asm__("r20") = num_words; + + __asm__ volatile ( + "push r20 \n\t" +#if (uECC_MIN_WORDS == 20) + FAST_SQUARE_ASM_20 + "pop r20 \n\t" + #if (uECC_MAX_WORDS > 20) + FAST_SQUARE_ASM_20_TO_24 + #endif + #if (uECC_MAX_WORDS > 24) + FAST_SQUARE_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_SQUARE_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 24) + FAST_SQUARE_ASM_24 + "pop r20 \n\t" + #if (uECC_MAX_WORDS > 24) + FAST_SQUARE_ASM_24_TO_28 + #endif + #if (uECC_MAX_WORDS > 28) + FAST_SQUARE_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 28) + FAST_SQUARE_ASM_28 + "pop r20 \n\t" + #if (uECC_MAX_WORDS > 28) + FAST_SQUARE_ASM_28_TO_32 + #endif +#elif (uECC_MIN_WORDS == 32) + FAST_SQUARE_ASM_32 + "pop r20 \n\t" +#endif + "2: \n\t" + "eor r1, r1 \n\t" + : "+x" (left), "+z" (result) + : "r" (r20) + : "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", + "r21", "r22", "r23", "r24", "r25", "r28", "r29", "cc" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC */ + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 3) */ + +#if uECC_SUPPORTS_secp160r1 +static const struct uECC_Curve_t curve_secp160r1; +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { + uint8_t carry = 0; + __asm__ volatile ( + "in r30, __SP_L__ \n\t" + "in r31, __SP_H__ \n\t" + "sbiw r30, 24 \n\t" + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + "adiw r30, 25 \n\t" /* we are shifting by 31 bits, so shift over 4 bytes + (+ 1 since z initially points below the stack) */ + "adiw r26, 40 \n\t" /* end of product */ + "ld r18, -x \n\t" /* Load word. */ + "lsr r18 \n\t" /* Shift. */ + "st -z, r18 \n\t" /* Store the first result word. */ + + /* Now we just do the remaining words with the carry bit (using ROR) */ + REPEAT(19, + "ld r18, -x \n\t" + "ror r18 \n\t" + "st -z, r18 \n\t") + + "eor r18, r18 \n\t" /* r18 = 0 */ + "ror r18 \n\t" /* get last bit */ + "st -z, r18 \n\t" /* store it */ + + "sbiw r30, 3 \n\t" /* move z back to point at tmp */ + /* now we add right */ + "ld r18, x+ \n\t" + "st z+, r18 \n\t" /* the first 3 bytes do not need to be added */ + "ld r18, x+ \n\t" + "st z+, r18 \n\t" + "ld r18, x+ \n\t" + "st z+, r18 \n\t" + + "ld r18, x+ \n\t" + "ld r19, z \n\t" + "add r18, r19 \n\t" + "st z+, r18 \n\t" + + /* Now we just do the remaining words with the carry bit (using ADC) */ + REPEAT(16, + "ld r18, x+ \n\t" + "ld r19, z \n\t" + "adc r18, r19 \n\t" + "st z+, r18 \n\t") + + /* Propagate over the remaining bytes of result */ + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "ld r18, z \n\t" + "adc r18, r1 \n\t" + "st z+, r18 \n\t" + + "sbiw r30, 24 \n\t" /* move z back to point at tmp */ + "sbiw r26, 40 \n\t" /* move x back to point at product */ + + /* add low bytes of tmp to product, storing in result */ + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(19, + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + /* at this point x is at the end of product, y is at the end of result, + z is 20 bytes into tmp */ + "sbiw r28, 20 \n\t" /* move y back to point at result */ + "adiw r30, 4 \n\t" /* move z to point to the end of tmp */ + + /* do omega_mult again with the 4 relevant bytes */ + /* z points to the end of tmp, x points to the end of product */ + "ld r18, -z \n\t" /* Load word. */ + "lsr r18 \n\t" /* Shift. */ + "st -x, r18 \n\t" /* Store the first result word. */ + + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + "ld r18, -z \n\t" + "ror r18 \n\t" + "st -x, r18 \n\t" + + "eor r18, r18 \n\t" /* r18 = 0 */ + "ror r18 \n\t" /* get last bit */ + "st -x, r18 \n\t" /* store it */ + + "sbiw r26, 3 \n\t" /* move x back to point at beginning */ + /* now we add a copy of the 4 bytes */ + "ld r18, z+ \n\t" + "st x+, r18 \n\t" /* the first 3 bytes do not need to be added */ + "ld r18, z+ \n\t" + "st x+, r18 \n\t" + "ld r18, z+ \n\t" + "st x+, r18 \n\t" + + "ld r18, z+ \n\t" + "ld r19, x \n\t" + "add r18, r19 \n\t" + "st x+, r18 \n\t" + + /* Propagate over the remaining bytes */ + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + "ld r18, x \n\t" + "adc r18, r1 \n\t" + "st x+, r18 \n\t" + + /* now z points to the end of tmp, x points to the end of product + (y still points at result) */ + "sbiw r26, 8 \n\t" /* move x back to point at beginning of actual data */ + /* add into result */ + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(7, + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + /* Done adding, now propagate carry bit */ + REPEAT(12, + "ld r18, y \n\t" + "adc r18, __zero_reg__ \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + "sbiw r28, 20 \n\t" /* move y back to point at result */ + + "sbiw r30, 1 \n\t" /* fix stack pointer */ + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + : "+x" (product), [carry] "+r" (carry) + : "y" (result) + : "r0", "r18", "r19", "r30", "r31", "cc" + ); + + if (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp160r1.p, 20); + } + if (carry > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, 20); + } + if (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, 20) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, 20); + } +} +#define asm_mmod_fast_secp160r1 1 +#endif /* uECC_SUPPORTS_secp160r1 */ + +#if uECC_SUPPORTS_secp256k1 +static const struct uECC_Curve_t curve_secp256k1; +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { + uint8_t carry = 0; + __asm__ volatile ( + "in r30, __SP_L__ \n\t" + "in r31, __SP_H__ \n\t" + "sbiw r30, 37 \n\t" + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + "adiw r30, 1 \n\t" /* add 1 since z initially points below the stack */ + "adiw r26, 32 \n\t" /* product + uECC_WORDS */ + "ldi r25, 0x03 \n\t" + "ldi r24, 0xD1 \n\t" + "ld r18, x+ \n\t" + "ld r19, x+ \n\t" + "ld r20, x+ \n\t" + "ld r21, x+ \n\t" + + "mul r24, r18 \n\t" + "st z+, r0 \n\t" + "mov r22, r1 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + /* now we start adding the 2^32 part as well */ + "add r23, r18 \n\t" // 28 + "adc r22, r22 \n\t" + "ld r18, x+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" // 27 + "adc r23, r23 \n\t" + "ld r19, x+ \n\t" + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + REPEAT(6, // 26 - 3 + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "ld r20, x+ \n\t" + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "ld r21, x+ \n\t" + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "ld r18, x+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "ld r19, x+ \n\t" + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t") + + "add r23, r20 \n\t" // 2 + "adc r22, r22 \n\t" + "ld r20, x+ \n\t" + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" // 1 + "adc r23, r23 \n\t" + "ld r21, x+ \n\t" + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + /* Now finish the carries etc */ + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "st z+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "st z+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "st z+, r22 \n\t" + "st z+, r23 \n\t" + "eor r1, r1 \n\t" /* make r1 be 0 again */ + + "sbiw r30, 37 \n\t" /* move z back to point at tmp */ + "subi r26, 64 \n\t" /* move x back to point at product */ + "sbc r27, __zero_reg__ \n\t" + + /* add low bytes of tmp to product, storing in result */ + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(31, + "ld r18, z+ \n\t" + "ld r19, x+ \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + /* at this point x is at the end of product, y is at the end of result, + z is 32 bytes into tmp */ + "sbiw r28, 32 \n\t" /* move y back to point at result */ + + /* do omega_mult again with the 5 relevant bytes */ + /* z points to tmp + uECC_WORDS, x points to the end of product */ + "sbiw r26, 32 \n\t" /* shift x back to point into the product buffer + (we can overwrite it now) */ + "ld r18, z+ \n\t" + "ld r19, z+ \n\t" + "ld r20, z+ \n\t" + "ld r21, z+ \n\t" + + "mul r24, r18 \n\t" + "st x+, r0 \n\t" + "mov r22, r1 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r19 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" /* can't overflow */ + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "mul r24, r20 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r19 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + "mul r24, r21 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "mul r25, r20 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "ld r18, z+ \n\t" + "mul r24, r18 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "mul r25, r21 \n\t" + "add r23, r0 \n\t" + "adc r22, r1 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + /* Now finish the carries etc */ + "add r22, r19 \n\t" + "adc r23, r23 \n\t" + "mul r25, r18 \n\t" + "add r22, r0 \n\t" + "adc r23, r1 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r20 \n\t" + "adc r22, r22 \n\t" + "st x+, r23 \n\t" + "ldi r23, 0 \n\t" + + "add r22, r21 \n\t" + "adc r23, r23 \n\t" + "st x+, r22 \n\t" + "ldi r22, 0 \n\t" + + "add r23, r18 \n\t" + "adc r22, r22 \n\t" + "st x+, r23 \n\t" + "st x+, r22 \n\t" + "eor r1, r1 \n\t" /* make r1 be 0 again */ + + /* now z points to the end of tmp, x points to the end of product + (y still points at result) */ + "sbiw r26, 10 \n\t" /* move x back to point at beginning of actual data */ + /* add into result */ + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "add r18, r19 \n\t" + "st y+, r18 \n\t" + REPEAT(9, + "ld r18, x+ \n\t" + "ld r19, y \n\t" + "adc r18, r19 \n\t" + "st y+, r18 \n\t") + + /* Done adding, now propagate carry bit */ + REPEAT(22, + "ld r18, y \n\t" + "adc r18, __zero_reg__ \n\t" + "st y+, r18 \n\t") + + "adc %[carry], __zero_reg__ \n\t" /* Store carry bit (carry flag is cleared). */ + "sbiw r28, 32 \n\t" /* move y back to point at result */ + + "sbiw r30, 1 \n\t" /* fix stack pointer */ + "in r0, __SREG__ \n\t" + "cli \n\t" + "out __SP_H__, r31 \n\t" + "out __SREG__, r0 \n\t" + "out __SP_L__, r30 \n\t" + + : "+x" (product), [carry] "+r" (carry) + : "y" (result) + : "r0", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r30", "r31", "cc" + ); + + if (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp256k1.p, 32); + } + if (carry > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, 32); + } + if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, 32) > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, 32); + } +} +#define asm_mmod_fast_secp256k1 1 +#endif /* uECC_SUPPORTS_secp256k1 */ + +#endif /* (uECC_OPTIMIZATION_LEVEL >= 2) */ + +/* ---- "Small" implementations ---- */ + +#if !asm_add +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t carry = 0; + uint8_t left_byte; + uint8_t right_byte; + + __asm__ volatile ( + "clc \n\t" + + "1: \n\t" + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "adc %[left], %[right] \n\t" /* Add. */ + "st z+, %[left] \n\t" /* Store the result. */ + "dec %[i] \n\t" + "brne 1b \n\t" + + "adc %[carry], %[carry] \n\t" /* Store carry bit. */ + + : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (num_words), + [carry] "+r" (carry), [left] "=&r" (left_byte), [right] "=&r" (right_byte) + : + : "cc" + ); + return carry; +} +#define asm_add 1 +#endif + +#if !asm_sub +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t borrow = 0; + uint8_t left_byte; + uint8_t right_byte; + + __asm__ volatile ( + "clc \n\t" + + "1: \n\t" + "ld %[left], x+ \n\t" /* Load left byte. */ + "ld %[right], y+ \n\t" /* Load right byte. */ + "sbc %[left], %[right] \n\t" /* Subtract. */ + "st z+, %[left] \n\t" /* Store the result. */ + "dec %[i] \n\t" + "brne 1b \n\t" + + "adc %[borrow], %[borrow] \n\t" /* Store carry bit in borrow. */ + + : "+z" (r), "+x" (left), "+y" (right), [i] "+r" (num_words), + [borrow] "+r" (borrow), [left] "=&r" (left_byte), [right] "=&r" (right_byte) + : + : "cc" + ); + return borrow; +} +#define asm_sub 1 +#endif + +#if !asm_mult +__attribute((noinline)) +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t r0 = 0; + uint8_t r1 = 0; + uint8_t r2 = 0; + uint8_t zero = 0; + uint8_t k, i; + + __asm__ volatile ( + "ldi %[k], 1 \n\t" /* k = 1; k < num_words; ++k */ + + "1: \n\t" + "ldi %[i], 0 \n\t" /* i = 0; i < k; ++i */ + + "add r28, %[k] \n\t" /* pre-add right ptr */ + "adc r29, %[zero] \n\t" + + "2: \n\t" + "ld r0, x+ \n\t" + "ld r1, -y \n\t" + "mul r0, r1 \n\t" + + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "inc %[i] \n\t" + "cp %[i], %[k] \n\t" + "brlo 2b \n\t" /* loop if i < k */ + + "sub r26, %[k] \n\t" /* fix up left ptr */ + "sbc r27, %[zero] \n\t" + + "st z+, %[r0] \n\t" /* Store the result. */ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "inc %[k] \n\t" + "cp %[k], %[num] \n\t" + "brlo 1b \n\t" /* loop if k < num_words */ + + /* second half */ + "mov %[k], %[num] \n\t" /* k = num_words; k > 0; --k */ + "add r28, %[num] \n\t" /* move right ptr to point at the end of right */ + "adc r29, %[zero] \n\t" + + "1: \n\t" + "ldi %[i], 0 \n\t" /* i = 0; i < k; ++i */ + + "2: \n\t" + "ld r0, x+ \n\t" + "ld r1, -y \n\t" + "mul r0, r1 \n\t" + + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "inc %[i] \n\t" + "cp %[i], %[k] \n\t" + "brlo 2b \n\t" /* loop if i < k */ + + "add r28, %[k] \n\t" /* fix up right ptr */ + "adc r29, %[zero] \n\t" + + "st z+, %[r0] \n\t" /* Store the result. */ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "dec %[k] \n\t" + "sub r26, %[k] \n\t" /* fix up left ptr (after k is decremented, so next time + we start 1 higher) */ + "sbc r27, %[zero] \n\t" + + "cp %[k], %[zero] \n\t" + "brne 1b \n\t" /* loop if k > 0 */ + + "st z+, %[r0] \n\t" /* Store last result byte. */ + "eor r1, r1 \n\t" /* fix r1 to be 0 again */ + + : "+z" (result), "+x" (left), "+y" (right), + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), + [zero] "+r" (zero), [num] "+r" (num_words), + [k] "=&r" (k), [i] "=&r" (i) + : + : "r0", "cc" + ); +} +#define asm_mult 1 +#endif + +#if (uECC_SQUARE_FUNC && !asm_square) +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + volatile uECC_word_t *r = result; + uint8_t r0 = 0; + uint8_t r1 = 0; + uint8_t r2 = 0; + uint8_t zero = 0; + uint8_t k; + + __asm__ volatile ( + "ldi %[k], 1 \n\t" /* k = 1; k < num_words * 2; ++k */ + + "1: \n\t" + + "movw r26, %[orig] \n\t" /* copy orig ptr to 'left' ptr */ + "movw r30, %[orig] \n\t" /* copy orig ptr to 'right' ptr */ + "cp %[k], %[num] \n\t" + "brlo 2f \n\t" + "breq 2f \n\t" + + /* when k > num_words, we start from (k - num_words) on the 'left' ptr */ + "add r26, %[k] \n\t" + "adc r27, %[zero] \n\t" + "sub r26, %[num] \n\t" + "sbc r27, %[zero] \n\t" + "add r30, %[num] \n\t" /* move right ptr to point at the end */ + "adc r31, %[zero] \n\t" + "rjmp 3f \n\t" + + "2: \n\t" /* when k <= num_words, we add k to the 'right' ptr */ + "add r30, %[k] \n\t" /* pre-add 'right' ptr */ + "adc r31, %[zero] \n\t" + + "3: \n\t" + "ld r0, x+ \n\t" + "cp r26, r30 \n\t" /* if left == right here, then we are done after this mult + (and we don't need to double) */ + "breq 4f \n\t" + "ld r1, -z \n\t" + "mul r0, r1 \n\t" + + /* add twice since it costs the same as doubling */ + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "cpse r26, r30 \n\t" /* if left == right here, then we are done */ + "rjmp 3b \n\t" + "rjmp 5f \n\t" /* skip code for non-doubled mult */ + + "4: \n\t" + "ld r1, -z \n\t" + "mul r0, r1 \n\t" + "add %[r0], r0 \n\t" + "adc %[r1], r1 \n\t" + "adc %[r2], %[zero] \n\t" + + "5: \n\t" + "movw r30, %[result] \n\t" /* make z point to result */ + "st z+, %[r0] \n\t" /* Store the result. */ + "movw %[result], r30 \n\t" /* update result ptr*/ + "mov %[r0], %[r1] \n\t" + "mov %[r1], %[r2] \n\t" + "mov %[r2], %[zero] \n\t" + + "inc %[k] \n\t" + "cp %[k], %[max] \n\t" + "brlo 1b \n\t" /* loop if k < num_words * 2 */ + + "movw r30, %[result] \n\t" /* make z point to result */ + "st z+, %[r0] \n\t" /* Store last result byte. */ + "eor r1, r1 \n\t" /* fix r1 to be 0 again */ + + : [result] "+r" (r), + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [zero] "+r" (zero), + [k] "=&a" (k) + : [orig] "r" (left), [max] "r" ((uint8_t)(2 * num_words)), + [num] "r" (num_words) + : "r0", "r26", "r27", "r30", "r31", "cc" + ); +} +#define asm_square 1 +#endif /* uECC_SQUARE_FUNC && !asm_square */ + +#endif /* _UECC_ASM_AVR_H_ */ diff --git a/core/embed/ble_bootloader/uecc/asm_avr_mult_square.inc b/core/embed/ble_bootloader/uecc/asm_avr_mult_square.inc new file mode 100644 index 000000000..7ae08bce6 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/asm_avr_mult_square.inc @@ -0,0 +1,26311 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_ASM_AVR_MULT_SQUARE_H_ +#define _UECC_ASM_AVR_MULT_SQUARE_H_ + +#define FAST_MULT_ASM_20 \ + "adiw r30, 10 \n\t" \ + "adiw r28, 10 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r30, 30 \n\t" \ + "sbiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" + +#define FAST_MULT_ASM_20_TO_24 \ + "cpi r18, 20 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r6, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r7, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r8, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r9, y+ \n\t" \ + "sbiw r26, 24 \n\t" \ + "sbiw r28, 24 \n\t" \ + "sbiw r30, 20 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + \ + "mul r2, r14 \n\t" \ + "mov r19, r0 \n\t" \ + "mov r20, r1 \n\t" \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r12, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "st z+, r21 \n\t" \ + "st z+, r19 \n\t" \ + "adiw r26, 4 \n\t" \ + "adiw r28, 4 \n\t" + +#define FAST_MULT_ASM_24 \ + "adiw r30, 20 \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r30, 18 \n\t" \ + "sbiw r28, 14 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r30, 38 \n\t" \ + "sbiw r28, 24 \n\t" \ + "sbiw r26, 14 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" + +#define FAST_MULT_ASM_24_TO_28 \ + "cpi r18, 24 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r6, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r7, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r8, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r9, y+ \n\t" \ + "sbiw r26, 28 \n\t" \ + "sbiw r28, 28 \n\t" \ + "sbiw r30, 24 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + \ + "mul r2, r14 \n\t" \ + "mov r19, r0 \n\t" \ + "mov r20, r1 \n\t" \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r12, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "mul r5, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "st z+, r19 \n\t" \ + "st z+, r20 \n\t" \ + "adiw r26, 4 \n\t" \ + "adiw r28, 4 \n\t" + +#define FAST_MULT_ASM_28 \ + "adiw r30, 20 \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r30, 26 \n\t" \ + "sbiw r28, 18 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + \ + "sbiw r30, 46 \n\t" \ + "sbiw r28, 28 \n\t" \ + "sbiw r26, 18 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" + +#define FAST_MULT_ASM_28_TO_32 \ + "cpi r18, 28 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r6, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r7, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r8, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r9, y+ \n\t" \ + "sbiw r26, 32 \n\t" \ + "sbiw r28, 32 \n\t" \ + "sbiw r30, 28 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + \ + "mul r2, r14 \n\t" \ + "mov r19, r0 \n\t" \ + "mov r20, r1 \n\t" \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r10, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "mul r2, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r25 \n\t" \ + "ld r11, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "mul r2, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r25 \n\t" \ + "ld r12, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "mul r2, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "ld r0, z \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r25 \n\t" \ + "ld r13, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "mul r2, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r12, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "ldi r19, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "st z+, r20 \n\t" \ + \ + "ldi r20, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r20, r25 \n\t" \ + "st z+, r21 \n\t" \ + \ + "ldi r21, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r20, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "st z+, r19 \n\t" \ + \ + "mul r5, r9 \n\t" \ + "add r20, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "st z+, r20 \n\t" \ + "st z+, r21 \n\t" + /* Not necessary to move ptrs since we don't support sizes > 32 */ + +#define FAST_MULT_ASM_32 \ + "adiw r30, 30 \n\t" \ + "adiw r28, 30 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r30, 14 \n\t" \ + "sbiw r28, 12 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r21, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + \ + "sbiw r30, 34 \n\t" \ + "sbiw r28, 22 \n\t" \ + "sbiw r26, 12 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r30, 54 \n\t" \ + "sbiw r28, 32 \n\t" \ + "sbiw r26, 22 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r12, y+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r17, y+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r18, y+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r19, y+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r20, y+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r21, y+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r18, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r19, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r20, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r21, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r25 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r19 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r18 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r20 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r19 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r21 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" + +#define FAST_SQUARE_ASM_20 \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "ldi r25, 0 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r4, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r6, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r8, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r10, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r12, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r13, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r14, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r16, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r27 \n\t" \ + "adc r24, r26 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r26, 0 \n\t" \ + "mul r18, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r27, r1 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "adc r26, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r27 \n\t" \ + "rol r26 \n\t" \ + "add r23, r24 \n\t" \ + "adc r27, r22 \n\t" \ + "adc r26, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r19, r21 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r27, r0 \n\t" \ + "adc r26, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r20, r20 \n\t" \ + "add r27, r0 \n\t" \ + "adc r26, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r27 \n\t" \ + \ + "ldi r27, 0 \n\t" \ + "mul r20, r21 \n\t" \ + "lsl r0 \n\t" \ + "rol r1 \n\t" \ + "adc r27, r25 \n\t" \ + "add r26, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r27, r25 \n\t" \ + "st z+, r26 \n\t" \ + \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r27, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r27 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" + +#define FAST_SQUARE_ASM_20_TO_24 \ + "cpi r20, 20 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "sbiw r26, 24 \n\t" \ + "sbiw r30, 20 \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + \ + "mul r2, r6 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r28, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + \ + "lsl r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "ld r0, z \n\t" \ + "add r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "ld r0, z \n\t" \ + "adc r23, r0 \n\t" \ + "st z+, r23 \n\t" \ + "ld r0, z \n\t" \ + "adc r24, r0 \n\t" \ + "st z+, r24 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "bst r28, 0 \n\t" \ + "lsr r29 \n\t" \ + "ror r28 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r10, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r12, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "lsl r28 \n\t" \ + "bld r28, 0 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "ld r0, z \n\t" \ + "add r28, r0 \n\t" \ + "st z+, r28 \n\t" \ + "ld r0, z \n\t" \ + "adc r29, r0 \n\t" \ + "st z+, r29 \n\t" \ + "ld r0, z \n\t" \ + "adc r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "adc r14, r25 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "mul r2, r2 \n\t" \ + "mov r16, r0 \n\t" \ + "mov r17, r1 \n\t" \ + "mul r3, r3 \n\t" \ + "mov r18, r0 \n\t" \ + "mov r19, r1 \n\t" \ + "mul r4, r4 \n\t" \ + "mov r21, r0 \n\t" \ + "mov r22, r1 \n\t" \ + "mul r5, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "add r16, r14 \n\t" \ + "adc r17, r15 \n\t" \ + "adc r18, r25 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "mul r7, r5 \n\t" \ + "mov r14, r0 \n\t" \ + "mov r15, r1 \n\t" \ + "mov r28, r25 \n\t" \ + "mul r8, r4 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mov r29, r25 \n\t" \ + "mul r8, r5 \n\t" \ + "add r15, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r15, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r15, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mov r10, r25 \n\t" \ + "mul r9, r5 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mov r12, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + \ + "lsl r14 \n\t" \ + "rol r15 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "adc r24, r25 \n\t" \ + "add r16, r14 \n\t" \ + "adc r17, r15 \n\t" \ + "adc r18, r28 \n\t" \ + "adc r19, r29 \n\t" \ + "adc r21, r10 \n\t" \ + "adc r22, r11 \n\t" \ + "adc r23, r12 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "st z+, r16 \n\t" \ + "st z+, r17 \n\t" \ + "st z+, r18 \n\t" \ + "st z+, r19 \n\t" \ + "st z+, r21 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + "adiw r26, 4 \n\t" + +#define FAST_SQUARE_ASM_24 \ + "ldi r25, 0 \n\t" \ + "movw r28, r26 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "adiw r30, 20 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul 2, 12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r22 \n\t" \ + \ + "sbiw r26, 4 \n\t" \ + "sbiw r30, 28 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r3, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r5, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r6, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r7, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r12, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r13, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r13, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r14, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r15, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r20, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r16, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r17, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r18, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r19, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r19, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r20, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r2, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r20, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r21, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r21, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r5 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r4 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r28 \n\t" \ + \ + "ldi r28, 0 \n\t" \ + "mul r4, r5 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "st z+, r29 \n\t" \ + \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r28 \n\t" + +#define FAST_SQUARE_ASM_24_TO_28 \ + "cpi r20, 24 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "sbiw r26, 28 \n\t" \ + "sbiw r30, 24 \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + \ + "mul r2, r6 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r28, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + \ + "lsl r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "ld r0, z \n\t" \ + "add r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "ld r0, z \n\t" \ + "adc r23, r0 \n\t" \ + "st z+, r23 \n\t" \ + "ld r0, z \n\t" \ + "adc r24, r0 \n\t" \ + "st z+, r24 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "bst r28, 0 \n\t" \ + "lsr r29 \n\t" \ + "ror r28 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r10, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r12, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "lsl r28 \n\t" \ + "bld r28, 0 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "ld r0, z \n\t" \ + "add r28, r0 \n\t" \ + "st z+, r28 \n\t" \ + "ld r0, z \n\t" \ + "adc r29, r0 \n\t" \ + "st z+, r29 \n\t" \ + "ld r0, z \n\t" \ + "adc r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "adc r18, r25 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "mul r2, r2 \n\t" \ + "mov r21, r0 \n\t" \ + "mov r22, r1 \n\t" \ + "mul r3, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r4 \n\t" \ + "mov r28, r0 \n\t" \ + "mov r29, r1 \n\t" \ + "mul r5, r5 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "add r21, r18 \n\t" \ + "adc r22, r19 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "mul r7, r5 \n\t" \ + "mov r18, r0 \n\t" \ + "mov r19, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mul r8, r4 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r8, r5 \n\t" \ + "add r19, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r19, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r19, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mov r14, r25 \n\t" \ + "mul r9, r5 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mov r16, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + \ + "lsl r18 \n\t" \ + "rol r19 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "adc r11, r25 \n\t" \ + "add r21, r18 \n\t" \ + "adc r22, r19 \n\t" \ + "adc r23, r12 \n\t" \ + "adc r24, r13 \n\t" \ + "adc r28, r14 \n\t" \ + "adc r29, r15 \n\t" \ + "adc r10, r16 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "st z+, r21 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + "st z+, r28 \n\t" \ + "st z+, r29 \n\t" \ + "st z+, r10 \n\t" \ + "st z+, r11 \n\t" \ + "adiw r26, 4 \n\t" + +#define FAST_SQUARE_ASM_28 \ + "ldi r25, 0 \n\t" \ + "movw r28, r26 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "adiw r30, 20 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul 2, 12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r5, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r24 \n\t" \ + \ + "sbiw r26, 8 \n\t" \ + "sbiw r30, 36 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r3, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r5, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r6, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r7, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r7, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r8, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r8, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r9, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r9, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r10, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r11, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r20, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r12, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r13, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r13, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r14, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r15, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r2, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r16, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r17, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r18, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r19, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r19, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r20, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r20, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r21, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r21, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r2, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r7, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r8, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r28 \n\t" \ + \ + "ldi r28, 0 \n\t" \ + "mul r8, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "st z+, r29 \n\t" \ + \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r28 \n\t" + +#define FAST_SQUARE_ASM_28_TO_32 \ + "cpi r20, 28 \n\t" \ + "brne 1f \n\t" \ + "jmp 2f \n\t" \ + "1: \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "sbiw r26, 32 \n\t" \ + "sbiw r30, 28 \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + \ + "mul r2, r6 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mov r12, r25 \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r28, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r28, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r24, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + \ + "lsl r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "ld r0, z \n\t" \ + "add r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "ld r0, z \n\t" \ + "adc r23, r0 \n\t" \ + "st z+, r23 \n\t" \ + "ld r0, z \n\t" \ + "adc r24, r0 \n\t" \ + "st z+, r24 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "bst r28, 0 \n\t" \ + "lsr r29 \n\t" \ + "ror r28 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r10, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r10, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r11, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r29, r0 \n\t" \ + "adc r10, r1 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r12, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r10, r0 \n\t" \ + "adc r11, r1 \n\t" \ + "adc r12, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r13, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r11, r0 \n\t" \ + "adc r12, r1 \n\t" \ + "adc r13, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r14, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r12, r0 \n\t" \ + "adc r13, r1 \n\t" \ + "adc r14, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r15, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r13, r0 \n\t" \ + "adc r14, r1 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r16, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r14, r0 \n\t" \ + "adc r15, r1 \n\t" \ + "adc r16, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r17, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r15, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r18, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "mov r21, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "mov r22, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + "adc r22, r25 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "mov r23, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r21, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "mov r24, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "lsl r28 \n\t" \ + "bld r28, 0 \n\t" \ + "rol r29 \n\t" \ + "rol r10 \n\t" \ + "rol r11 \n\t" \ + "rol r12 \n\t" \ + "rol r13 \n\t" \ + "rol r14 \n\t" \ + "rol r15 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "rol r22 \n\t" \ + "rol r23 \n\t" \ + "rol r24 \n\t" \ + "ld r0, z \n\t" \ + "add r28, r0 \n\t" \ + "st z+, r28 \n\t" \ + "ld r0, z \n\t" \ + "adc r29, r0 \n\t" \ + "st z+, r29 \n\t" \ + "ld r0, z \n\t" \ + "adc r10, r0 \n\t" \ + "st z+, r10 \n\t" \ + "ld r0, z \n\t" \ + "adc r11, r0 \n\t" \ + "st z+, r11 \n\t" \ + "ld r0, z \n\t" \ + "adc r12, r0 \n\t" \ + "st z+, r12 \n\t" \ + "ld r0, z \n\t" \ + "adc r13, r0 \n\t" \ + "st z+, r13 \n\t" \ + "ld r0, z \n\t" \ + "adc r14, r0 \n\t" \ + "st z+, r14 \n\t" \ + "ld r0, z \n\t" \ + "adc r15, r0 \n\t" \ + "st z+, r15 \n\t" \ + "ld r0, z \n\t" \ + "adc r16, r0 \n\t" \ + "st z+, r16 \n\t" \ + "ld r0, z \n\t" \ + "adc r17, r0 \n\t" \ + "st z+, r17 \n\t" \ + "ld r0, z \n\t" \ + "adc r18, r0 \n\t" \ + "st z+, r18 \n\t" \ + "ld r0, z \n\t" \ + "adc r19, r0 \n\t" \ + "st z+, r19 \n\t" \ + "ld r0, z \n\t" \ + "adc r21, r0 \n\t" \ + "st z+, r21 \n\t" \ + "ld r0, z \n\t" \ + "adc r22, r0 \n\t" \ + "st z+, r22 \n\t" \ + "adc r23, r25 \n\t" \ + "adc r24, r25 \n\t" \ + \ + "mul r2, r2 \n\t" \ + "mov r28, r0 \n\t" \ + "mov r29, r1 \n\t" \ + "mul r3, r3 \n\t" \ + "mov r10, r0 \n\t" \ + "mov r11, r1 \n\t" \ + "mul r4, r4 \n\t" \ + "mov r12, r0 \n\t" \ + "mov r13, r1 \n\t" \ + "mul r5, r5 \n\t" \ + "mov r14, r0 \n\t" \ + "mov r15, r1 \n\t" \ + "add r28, r23 \n\t" \ + "adc r29, r24 \n\t" \ + "adc r10, r25 \n\t" \ + "adc r11, r25 \n\t" \ + \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mov r16, r25 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r16, r25 \n\t" \ + "mov r17, r25 \n\t" \ + "mul r8, r5 \n\t" \ + "add r24, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r24, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r24, r0 \n\t" \ + "adc r16, r1 \n\t" \ + "adc r17, r25 \n\t" \ + "mov r18, r25 \n\t" \ + "mul r9, r5 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r16, r0 \n\t" \ + "adc r17, r1 \n\t" \ + "adc r18, r25 \n\t" \ + "mov r19, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r17, r0 \n\t" \ + "adc r18, r1 \n\t" \ + "adc r19, r25 \n\t" \ + "mov r21, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r18, r0 \n\t" \ + "adc r19, r1 \n\t" \ + "adc r21, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r19, r0 \n\t" \ + "adc r21, r1 \n\t" \ + \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r16 \n\t" \ + "rol r17 \n\t" \ + "rol r18 \n\t" \ + "rol r19 \n\t" \ + "rol r21 \n\t" \ + "adc r15, r25 \n\t" \ + "add r28, r23 \n\t" \ + "adc r29, r24 \n\t" \ + "adc r10, r16 \n\t" \ + "adc r11, r17 \n\t" \ + "adc r12, r18 \n\t" \ + "adc r13, r19 \n\t" \ + "adc r14, r21 \n\t" \ + "adc r15, r25 \n\t" \ + \ + "st z+, r28 \n\t" \ + "st z+, r29 \n\t" \ + "st z+, r10 \n\t" \ + "st z+, r11 \n\t" \ + "st z+, r12 \n\t" \ + "st z+, r13 \n\t" \ + "st z+, r14 \n\t" \ + "st z+, r15 \n\t" \ + "adiw r26, 4 \n\t" + +#define FAST_SQUARE_ASM_32 \ + "ldi r25, 0 \n\t" \ + "movw r28, r26 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "adiw r28, 20 \n\t" \ + "ld r12, y+ \n\t" \ + "ld r13, y+ \n\t" \ + "ld r14, y+ \n\t" \ + "ld r15, y+ \n\t" \ + "ld r16, y+ \n\t" \ + "ld r17, y+ \n\t" \ + "adiw r30, 20 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul 2, 12 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r13, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r14, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r15, y+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r16, y+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r17, y+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r12 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r13 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r23, 0 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r2, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r3, r14 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r24, 0 \n\t" \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r2, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r3, r15 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r3, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r4, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r6, r17 \n\t" \ + "add r24, r0 \n\t" \ + "adc r22, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r24 \n\t" \ + \ + "mul r7, r17 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "st z+, r22 \n\t" \ + "st z+, r23 \n\t" \ + \ + "sbiw r26, 12 \n\t" \ + "sbiw r30, 44 \n\t" \ + "ld r2, x+ \n\t" \ + "ld r3, x+ \n\t" \ + "ld r4, x+ \n\t" \ + "ld r5, x+ \n\t" \ + "ld r6, x+ \n\t" \ + "ld r7, x+ \n\t" \ + "ld r8, x+ \n\t" \ + "ld r9, x+ \n\t" \ + "ld r10, x+ \n\t" \ + "ld r11, x+ \n\t" \ + "ld r12, x+ \n\t" \ + "ld r13, x+ \n\t" \ + "ld r14, x+ \n\t" \ + "ld r15, x+ \n\t" \ + "ld r16, x+ \n\t" \ + "ld r17, x+ \n\t" \ + "ld r18, x+ \n\t" \ + "ld r19, x+ \n\t" \ + "ld r20, x+ \n\t" \ + "ld r21, x+ \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r2, r2 \n\t" \ + "st z+, r0 \n\t" \ + "mov r22, r1 \n\t" \ + \ + "ldi r24, 0 \n\t" \ + "mul r2, r3 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "add r22, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r24, r25 \n\t" \ + "st z+, r22 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r14 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r15 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r16 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r17 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r18 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r19 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r2, r20 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r3, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r2, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r3, r21 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r12, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r3, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r4, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r3, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r4, r2 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r5, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r4, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r5, r3 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r14, r14 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r5, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r6, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r5, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r6, r4 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r7, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r15, r15 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r6, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r7, r5 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r16, r16 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r7, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r8, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r7, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r8, r6 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r9, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r10, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r17, r17 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r8, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r9, r7 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r11, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r18, r18 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r9, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r10, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r11, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r9, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r10, r8 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r11, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r12, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r19, r19 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r12, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r10, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r11, r9 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r12, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r13, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r20, r20 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r11, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r12, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r13, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r11, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r12, r10 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r13, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r14, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r21, r21 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r12, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r13, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r14, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r12, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r13, r11 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r14, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r15, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r2, r2 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r13, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r14, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r15, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ld r13, x+ \n\t" \ + "ldi r22, 0 \n\t" \ + "mul r14, r12 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r15, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r16, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r25 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r3, r3 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r14, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r15, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r16, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r17, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "ld r0, z \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r25 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r15, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r16, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r17, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r18, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r4, r4 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r16, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r17, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r18, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r19, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r17, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r18, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r19, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r20, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r5, r5 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r18, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r19, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r20, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r21, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r19, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r20, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r21, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r2, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r6, r6 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r20, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r21, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r2, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r3, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r21, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r2, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r3, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r4, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r7, r7 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r2, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r3, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r4, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r5, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r3, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r4, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r5, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r6, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r8, r8 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r4, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r5, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r6, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r7, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r5, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r6, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r7, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r8, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r9, r9 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r6, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r7, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r8, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r9, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r7, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r8, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "mul r9, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r10, r10 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r8, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r9, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "mul r10, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r22, 0 \n\t" \ + "mul r9, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r24, r1 \n\t" \ + "mul r10, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r24 \n\t" \ + "rol r22 \n\t" \ + "mul r11, r11 \n\t" \ + "add r23, r0 \n\t" \ + "adc r24, r1 \n\t" \ + "adc r22, r25 \n\t" \ + "add r23, r28 \n\t" \ + "adc r24, r29 \n\t" \ + "adc r22, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r29, 0 \n\t" \ + "mul r10, r13 \n\t" \ + "mov r23, r0 \n\t" \ + "mov r28, r1 \n\t" \ + "mul r11, r12 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "adc r29, r25 \n\t" \ + "lsl r23 \n\t" \ + "rol r28 \n\t" \ + "rol r29 \n\t" \ + "add r23, r24 \n\t" \ + "adc r28, r22 \n\t" \ + "adc r29, r25 \n\t" \ + "st z+, r23 \n\t" \ + \ + "ldi r23, 0 \n\t" \ + "mul r11, r13 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "mul r12, r12 \n\t" \ + "add r28, r0 \n\t" \ + "adc r29, r1 \n\t" \ + "adc r23, r25 \n\t" \ + "st z+, r28 \n\t" \ + \ + "ldi r28, 0 \n\t" \ + "mul r12, r13 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "add r29, r0 \n\t" \ + "adc r23, r1 \n\t" \ + "adc r28, r25 \n\t" \ + "st z+, r29 \n\t" \ + \ + "mul r13, r13 \n\t" \ + "add r23, r0 \n\t" \ + "adc r28, r1 \n\t" \ + "st z+, r23 \n\t" \ + "st z+, r28 \n\t" + +#endif /* _UECC_ASM_AVR_MULT_SQUARE_H_ */ diff --git a/core/embed/ble_bootloader/uecc/curve-specific.inc b/core/embed/ble_bootloader/uecc/curve-specific.inc new file mode 100644 index 000000000..0453b212c --- /dev/null +++ b/core/embed/ble_bootloader/uecc/curve-specific.inc @@ -0,0 +1,1248 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_CURVE_SPECIFIC_H_ +#define _UECC_CURVE_SPECIFIC_H_ + +#define num_bytes_secp160r1 20 +#define num_bytes_secp192r1 24 +#define num_bytes_secp224r1 28 +#define num_bytes_secp256r1 32 +#define num_bytes_secp256k1 32 + +#if (uECC_WORD_SIZE == 1) + +#define num_words_secp160r1 20 +#define num_words_secp192r1 24 +#define num_words_secp224r1 28 +#define num_words_secp256r1 32 +#define num_words_secp256k1 32 + +#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \ + 0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h +#define BYTES_TO_WORDS_4(a, b, c, d) 0x##a, 0x##b, 0x##c, 0x##d + +#elif (uECC_WORD_SIZE == 4) + +#define num_words_secp160r1 5 +#define num_words_secp192r1 6 +#define num_words_secp224r1 7 +#define num_words_secp256r1 8 +#define num_words_secp256k1 8 + +#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e +#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a + +#elif (uECC_WORD_SIZE == 8) + +#define num_words_secp160r1 3 +#define num_words_secp192r1 3 +#define num_words_secp224r1 4 +#define num_words_secp256r1 4 +#define num_words_secp256k1 4 + +#define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##ull +#define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##ull + +#endif /* uECC_WORD_SIZE */ + +#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \ + uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1 +static void double_jacobian_default(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve) { + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[uECC_MAX_WORDS]; + uECC_word_t t5[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + if (uECC_vli_isZero(Z1, num_words)) { + return; + } + + uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ + uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ + uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ + uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ + + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ + uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */ + uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */ + uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ + + uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */ + uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */ + if (uECC_vli_testBit(X1, 0)) { + uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); + uECC_vli_rshift1(X1, num_words); + X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); + } else { + uECC_vli_rshift1(X1, num_words); + } + /* t1 = 3/2*(x1^2 - z1^4) = B */ + + uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */ + uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */ + uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ + uECC_vli_modSub(t4, X1, t4, curve->p, num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ + + uECC_vli_set(X1, Z1, num_words); + uECC_vli_set(Z1, Y1, num_words); + uECC_vli_set(Y1, t4, num_words); +} + +/* Computes result = x^3 + ax + b. result must not overlap x. */ +static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ + wordcount_t num_words = curve->num_words; + + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */ +} +#endif /* uECC_SUPPORTS_secp... */ + +#if uECC_SUPPORT_COMPRESSED_POINT +#if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \ + uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1 +/* Compute a = sqrt(a) (mod curve_p). */ +static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { + bitcount_t i; + uECC_word_t p1[uECC_MAX_WORDS] = {1}; + uECC_word_t l_result[uECC_MAX_WORDS] = {1}; + wordcount_t num_words = curve->num_words; + + /* When curve->p == 3 (mod 4), we can compute + sqrt(a) = a^((curve->p + 1) / 4) (mod curve->p). */ + uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ + for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { + uECC_vli_modSquare_fast(l_result, l_result, curve); + if (uECC_vli_testBit(p1, i)) { + uECC_vli_modMult_fast(l_result, l_result, a, curve); + } + } + uECC_vli_set(a, l_result, num_words); +} +#endif /* uECC_SUPPORTS_secp... */ +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +#if uECC_SUPPORTS_secp160r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp160r1 = { + num_words_secp160r1, + num_bytes_secp160r1, + 161, /* num_n_bits */ + { BYTES_TO_WORDS_8(FF, FF, FF, 7F, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_4(FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(57, 22, 75, CA, D3, AE, 27, F9), + BYTES_TO_WORDS_8(C8, F4, 01, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 01, 00, 00, 00) }, + { BYTES_TO_WORDS_8(82, FC, CB, 13, B9, 8B, C3, 68), + BYTES_TO_WORDS_8(89, 69, 64, 46, 28, 73, F5, 8E), + BYTES_TO_WORDS_4(68, B5, 96, 4A), + + BYTES_TO_WORDS_8(32, FB, C5, 7A, 37, 51, 23, 04), + BYTES_TO_WORDS_8(12, C9, DC, 59, 7D, 94, 68, 31), + BYTES_TO_WORDS_4(55, 28, A6, 23) }, + { BYTES_TO_WORDS_8(45, FA, 65, C5, AD, D4, D4, 81), + BYTES_TO_WORDS_8(9F, F8, AC, 65, 8B, 7A, BD, 54), + BYTES_TO_WORDS_4(FC, BE, 97, 1C) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp160r1 +#endif +}; + +uECC_Curve uECC_secp160r1(void) { return &curve_secp160r1; } + +#if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) +/* Computes result = product % curve_p + see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354 + + Note that this only works if log2(omega) < log2(p) / 2 */ +static void omega_mult_secp160r1(uECC_word_t *result, const uECC_word_t *right); +#if uECC_WORD_SIZE == 8 +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[2 * num_words_secp160r1]; + uECC_word_t copy; + + uECC_vli_clear(tmp, num_words_secp160r1); + uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); + + omega_mult_secp160r1(tmp, product + num_words_secp160r1 - 1); /* (Rq, q) = q * c */ + + product[num_words_secp160r1 - 1] &= 0xffffffff; + copy = tmp[num_words_secp160r1 - 1]; + tmp[num_words_secp160r1 - 1] &= 0xffffffff; + uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp160r1); + tmp[num_words_secp160r1 - 1] = copy; + omega_mult_secp160r1(product, tmp + num_words_secp160r1 - 1); /* Rq*c */ + uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ + + while (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } +} + +static void omega_mult_secp160r1(uint64_t *result, const uint64_t *right) { + uint32_t carry; + unsigned i; + + /* Multiply by (2^31 + 1). */ + carry = 0; + for (i = 0; i < num_words_secp160r1; ++i) { + uint64_t tmp = (right[i] >> 32) | (right[i + 1] << 32); + result[i] = (tmp << 31) + tmp + carry; + carry = (tmp >> 33) + (result[i] < tmp || (carry && result[i] == tmp)); + } + result[i] = carry; +} +#else +static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[2 * num_words_secp160r1]; + uECC_word_t carry; + + uECC_vli_clear(tmp, num_words_secp160r1); + uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); + + omega_mult_secp160r1(tmp, product + num_words_secp160r1); /* (Rq, q) = q * c */ + + carry = uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp160r1); + omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */ + carry += uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ + + while (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } + if (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) > 0) { + uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); + } +} +#endif + +#if uECC_WORD_SIZE == 1 +static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) { + uint8_t carry; + uint8_t i; + + /* Multiply by (2^31 + 1). */ + uECC_vli_set(result + 4, right, num_words_secp160r1); /* 2^32 */ + uECC_vli_rshift1(result + 4, num_words_secp160r1); /* 2^31 */ + result[3] = right[0] << 7; /* get last bit from shift */ + + carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ + for (i = num_words_secp160r1; carry; ++i) { + uint16_t sum = (uint16_t)result[i] + carry; + result[i] = (uint8_t)sum; + carry = sum >> 8; + } +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) { + uint32_t carry; + unsigned i; + + /* Multiply by (2^31 + 1). */ + uECC_vli_set(result + 1, right, num_words_secp160r1); /* 2^32 */ + uECC_vli_rshift1(result + 1, num_words_secp160r1); /* 2^31 */ + result[0] = right[0] << 31; /* get last bit from shift */ + + carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ + for (i = num_words_secp160r1; carry; ++i) { + uint64_t sum = (uint64_t)result[i] + carry; + result[i] = (uint32_t)sum; + carry = sum >> 32; + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) */ + +#endif /* uECC_SUPPORTS_secp160r1 */ + +#if uECC_SUPPORTS_secp192r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp192r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp192r1 = { + num_words_secp192r1, + num_bytes_secp192r1, + 192, /* num_n_bits */ + { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(31, 28, D2, B4, B1, C9, 6B, 14), + BYTES_TO_WORDS_8(36, F8, DE, 99, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(12, 10, FF, 82, FD, 0A, FF, F4), + BYTES_TO_WORDS_8(00, 88, A1, 43, EB, 20, BF, 7C), + BYTES_TO_WORDS_8(F6, 90, 30, B0, 0E, A8, 8D, 18), + + BYTES_TO_WORDS_8(11, 48, 79, 1E, A1, 77, F9, 73), + BYTES_TO_WORDS_8(D5, CD, 24, 6B, ED, 11, 10, 63), + BYTES_TO_WORDS_8(78, DA, C8, FF, 95, 2B, 19, 07) }, + { BYTES_TO_WORDS_8(B1, B9, 46, C1, EC, DE, B8, FE), + BYTES_TO_WORDS_8(49, 30, 24, 72, AB, E9, A7, 0F), + BYTES_TO_WORDS_8(E7, 80, 9C, E5, 19, 05, 21, 64) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp192r1 +#endif +}; + +uECC_Curve uECC_secp192r1(void) { return &curve_secp192r1; } + +#if (uECC_OPTIMIZATION_LEVEL > 0) +/* Computes result = product % curve_p. + See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast_secp192r1(uint8_t *result, uint8_t *product) { + uint8_t tmp[num_words_secp192r1]; + uint8_t carry; + + uECC_vli_set(result, product, num_words_secp192r1); + + uECC_vli_set(tmp, &product[24], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; + tmp[8] = product[24]; tmp[9] = product[25]; tmp[10] = product[26]; tmp[11] = product[27]; + tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; + tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; + tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[8] = product[40]; + tmp[1] = tmp[9] = product[41]; + tmp[2] = tmp[10] = product[42]; + tmp[3] = tmp[11] = product[43]; + tmp[4] = tmp[12] = product[44]; + tmp[5] = tmp[13] = product[45]; + tmp[6] = tmp[14] = product[46]; + tmp[7] = tmp[15] = product[47]; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast_secp192r1(uint32_t *result, uint32_t *product) { + uint32_t tmp[num_words_secp192r1]; + int carry; + + uECC_vli_set(result, product, num_words_secp192r1); + + uECC_vli_set(tmp, &product[6], num_words_secp192r1); + carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[1] = 0; + tmp[2] = product[6]; + tmp[3] = product[7]; + tmp[4] = product[8]; + tmp[5] = product[9]; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[2] = product[10]; + tmp[1] = tmp[3] = product[11]; + tmp[4] = tmp[5] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#else +static void vli_mmod_fast_secp192r1(uint64_t *result, uint64_t *product) { + uint64_t tmp[num_words_secp192r1]; + int carry; + + uECC_vli_set(result, product, num_words_secp192r1); + + uECC_vli_set(tmp, &product[3], num_words_secp192r1); + carry = (int)uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = 0; + tmp[1] = product[3]; + tmp[2] = product[4]; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + tmp[0] = tmp[1] = product[5]; + tmp[2] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); + + while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp192r1 */ + +#if uECC_SUPPORTS_secp224r1 + +#if uECC_SUPPORT_COMPRESSED_POINT +static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve); +#endif +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp224r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp224r1 = { + num_words_secp224r1, + num_bytes_secp224r1, + 224, /* num_n_bits */ + { BYTES_TO_WORDS_8(01, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_4(FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(3D, 2A, 5C, 5C, 45, 29, DD, 13), + BYTES_TO_WORDS_8(3E, F0, B8, E0, A2, 16, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_4(FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(21, 1D, 5C, 11, D6, 80, 32, 34), + BYTES_TO_WORDS_8(22, 11, C2, 56, D3, C1, 03, 4A), + BYTES_TO_WORDS_8(B9, 90, 13, 32, 7F, BF, B4, 6B), + BYTES_TO_WORDS_4(BD, 0C, 0E, B7), + + BYTES_TO_WORDS_8(34, 7E, 00, 85, 99, 81, D5, 44), + BYTES_TO_WORDS_8(64, 47, 07, 5A, A0, 75, 43, CD), + BYTES_TO_WORDS_8(E6, DF, 22, 4C, FB, 23, F7, B5), + BYTES_TO_WORDS_4(88, 63, 37, BD) }, + { BYTES_TO_WORDS_8(B4, FF, 55, 23, 43, 39, 0B, 27), + BYTES_TO_WORDS_8(BA, D8, BF, D7, B7, B0, 44, 50), + BYTES_TO_WORDS_8(56, 32, 41, F5, AB, B3, 04, 0C), + BYTES_TO_WORDS_4(85, 0A, 05, B4) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_secp224r1, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp224r1 +#endif +}; + +uECC_Curve uECC_secp224r1(void) { return &curve_secp224r1; } + + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Routine 3.2.4 RS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rs(uECC_word_t *d1, + uECC_word_t *e1, + uECC_word_t *f1, + const uECC_word_t *d0, + const uECC_word_t *e0, + const uECC_word_t *f0) { + uECC_word_t t[num_words_secp224r1]; + + uECC_vli_modSquare_fast(t, d0, &curve_secp224r1); /* t <-- d0 ^ 2 */ + uECC_vli_modMult_fast(e1, d0, e0, &curve_secp224r1); /* e1 <-- d0 * e0 */ + uECC_vli_modAdd(d1, t, f0, curve_secp224r1.p, num_words_secp224r1); /* d1 <-- t + f0 */ + uECC_vli_modAdd(e1, e1, e1, curve_secp224r1.p, num_words_secp224r1); /* e1 <-- e1 + e1 */ + uECC_vli_modMult_fast(f1, t, f0, &curve_secp224r1); /* f1 <-- t * f0 */ + uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ + uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ +} + +/* Routine 3.2.5 RSS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rss(uECC_word_t *d1, + uECC_word_t *e1, + uECC_word_t *f1, + const uECC_word_t *d0, + const uECC_word_t *e0, + const uECC_word_t *f0, + const bitcount_t j) { + bitcount_t i; + + uECC_vli_set(d1, d0, num_words_secp224r1); /* d1 <-- d0 */ + uECC_vli_set(e1, e0, num_words_secp224r1); /* e1 <-- e0 */ + uECC_vli_set(f1, f0, num_words_secp224r1); /* f1 <-- f0 */ + for (i = 1; i <= j; i++) { + mod_sqrt_secp224r1_rs(d1, e1, f1, d1, e1, f1); /* RS (d1,e1,f1,d1,e1,f1) */ + } +} + +/* Routine 3.2.6 RM; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rm(uECC_word_t *d2, + uECC_word_t *e2, + uECC_word_t *f2, + const uECC_word_t *c, + const uECC_word_t *d0, + const uECC_word_t *e0, + const uECC_word_t *d1, + const uECC_word_t *e1) { + uECC_word_t t1[num_words_secp224r1]; + uECC_word_t t2[num_words_secp224r1]; + + uECC_vli_modMult_fast(t1, e0, e1, &curve_secp224r1); /* t1 <-- e0 * e1 */ + uECC_vli_modMult_fast(t1, t1, c, &curve_secp224r1); /* t1 <-- t1 * c */ + /* t1 <-- p - t1 */ + uECC_vli_modSub(t1, curve_secp224r1.p, t1, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_modMult_fast(t2, d0, d1, &curve_secp224r1); /* t2 <-- d0 * d1 */ + uECC_vli_modAdd(t2, t2, t1, curve_secp224r1.p, num_words_secp224r1); /* t2 <-- t2 + t1 */ + uECC_vli_modMult_fast(t1, d0, e1, &curve_secp224r1); /* t1 <-- d0 * e1 */ + uECC_vli_modMult_fast(e2, d1, e0, &curve_secp224r1); /* e2 <-- d1 * e0 */ + uECC_vli_modAdd(e2, e2, t1, curve_secp224r1.p, num_words_secp224r1); /* e2 <-- e2 + t1 */ + uECC_vli_modSquare_fast(f2, e2, &curve_secp224r1); /* f2 <-- e2^2 */ + uECC_vli_modMult_fast(f2, f2, c, &curve_secp224r1); /* f2 <-- f2 * c */ + /* f2 <-- p - f2 */ + uECC_vli_modSub(f2, curve_secp224r1.p, f2, curve_secp224r1.p, num_words_secp224r1); + uECC_vli_set(d2, t2, num_words_secp224r1); /* d2 <-- t2 */ +} + +/* Routine 3.2.7 RP; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1_rp(uECC_word_t *d1, + uECC_word_t *e1, + uECC_word_t *f1, + const uECC_word_t *c, + const uECC_word_t *r) { + wordcount_t i; + wordcount_t pow2i = 1; + uECC_word_t d0[num_words_secp224r1]; + uECC_word_t e0[num_words_secp224r1] = {1}; /* e0 <-- 1 */ + uECC_word_t f0[num_words_secp224r1]; + + uECC_vli_set(d0, r, num_words_secp224r1); /* d0 <-- r */ + /* f0 <-- p - c */ + uECC_vli_modSub(f0, curve_secp224r1.p, c, curve_secp224r1.p, num_words_secp224r1); + for (i = 0; i <= 6; i++) { + mod_sqrt_secp224r1_rss(d1, e1, f1, d0, e0, f0, pow2i); /* RSS (d1,e1,f1,d0,e0,f0,2^i) */ + mod_sqrt_secp224r1_rm(d1, e1, f1, c, d1, e1, d0, e0); /* RM (d1,e1,f1,c,d1,e1,d0,e0) */ + uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ + uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ + uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ + pow2i *= 2; + } +} + +/* Compute a = sqrt(a) (mod curve_p). */ +/* Routine 3.2.8 mp_mod_sqrt_224; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) { + bitcount_t i; + uECC_word_t e1[num_words_secp224r1]; + uECC_word_t f1[num_words_secp224r1]; + uECC_word_t d0[num_words_secp224r1]; + uECC_word_t e0[num_words_secp224r1]; + uECC_word_t f0[num_words_secp224r1]; + uECC_word_t d1[num_words_secp224r1]; + + /* s = a; using constant instead of random value */ + mod_sqrt_secp224r1_rp(d0, e0, f0, a, a); /* RP (d0, e0, f0, c, s) */ + mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ + for (i = 1; i <= 95; i++) { + uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ + uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ + uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ + mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ + if (uECC_vli_isZero(d1, num_words_secp224r1)) { /* if d1 == 0 */ + break; + } + } + uECC_vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */ + uECC_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */ +} +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +#if (uECC_OPTIMIZATION_LEVEL > 0) +/* Computes result = product % curve_p + from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { + uint8_t tmp[num_words_secp224r1]; + int8_t carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp224r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; + tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; + tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; + tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; + tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; + tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; + tmp[24] = product[40]; tmp[25] = product[41]; tmp[26] = product[42]; tmp[27] = product[43]; + carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* s2 */ + tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; + tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; + tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* d1 */ + tmp[0] = product[28]; tmp[1] = product[29]; tmp[2] = product[30]; tmp[3] = product[31]; + tmp[4] = product[32]; tmp[5] = product[33]; tmp[6] = product[34]; tmp[7] = product[35]; + tmp[8] = product[36]; tmp[9] = product[37]; tmp[10] = product[38]; tmp[11] = product[39]; + tmp[12] = product[40]; tmp[13] = product[41]; tmp[14] = product[42]; tmp[15] = product[43]; + tmp[16] = product[44]; tmp[17] = product[45]; tmp[18] = product[46]; tmp[19] = product[47]; + tmp[20] = product[48]; tmp[21] = product[49]; tmp[22] = product[50]; tmp[23] = product[51]; + tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + /* d2 */ + tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; + tmp[4] = product[48]; tmp[5] = product[49]; tmp[6] = product[50]; tmp[7] = product[51]; + tmp[8] = product[52]; tmp[9] = product[53]; tmp[10] = product[54]; tmp[11] = product[55]; + tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + } + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) +{ + uint32_t tmp[num_words_secp224r1]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp224r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = 0; + tmp[3] = product[7]; + tmp[4] = product[8]; + tmp[5] = product[9]; + tmp[6] = product[10]; + carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* s2 */ + tmp[3] = product[11]; + tmp[4] = product[12]; + tmp[5] = product[13]; + tmp[6] = 0; + carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* d1 */ + tmp[0] = product[7]; + tmp[1] = product[8]; + tmp[2] = product[9]; + tmp[3] = product[10]; + tmp[4] = product[11]; + tmp[5] = product[12]; + tmp[6] = product[13]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + /* d2 */ + tmp[0] = product[11]; + tmp[1] = product[12]; + tmp[2] = product[13]; + tmp[3] = tmp[4] = tmp[5] = tmp[6] = 0; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + } + } +} +#else +static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) +{ + uint64_t tmp[num_words_secp224r1]; + int carry = 0; + + /* t */ + uECC_vli_set(result, product, num_words_secp224r1); + result[num_words_secp224r1 - 1] &= 0xffffffff; + + /* s1 */ + tmp[0] = 0; + tmp[1] = product[3] & 0xffffffff00000000ull; + tmp[2] = product[4]; + tmp[3] = product[5] & 0xffffffff; + uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* s2 */ + tmp[1] = product[5] & 0xffffffff00000000ull; + tmp[2] = product[6]; + tmp[3] = 0; + uECC_vli_add(result, result, tmp, num_words_secp224r1); + + /* d1 */ + tmp[0] = (product[3] >> 32) | (product[4] << 32); + tmp[1] = (product[4] >> 32) | (product[5] << 32); + tmp[2] = (product[5] >> 32) | (product[6] << 32); + tmp[3] = product[6] >> 32; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + /* d2 */ + tmp[0] = (product[5] >> 32) | (product[6] << 32); + tmp[1] = product[6] >> 32; + tmp[2] = tmp[3] = 0; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); + } while (carry < 0); + } else { + while (uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { + uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); + } + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ + +#endif /* uECC_SUPPORTS_secp224r1 */ + +#if uECC_SUPPORTS_secp256r1 + +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp256r1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp256r1 = { + num_words_secp256r1, + num_bytes_secp256r1, + 256, /* num_n_bits */ + { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3), + BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4), + BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77), + BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8), + BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B), + + BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB), + BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B), + BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E), + BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F) }, + { BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B), + BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65), + BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3), + BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A) }, + &double_jacobian_default, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_default, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp256r1 +#endif +}; + +uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } + + +#if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) +/* Computes result = product % curve_p + from http://www.nsa.gov/ia/_files/nist-routines.pdf */ +#if uECC_WORD_SIZE == 1 +static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { + uint8_t tmp[num_words_secp256r1]; + int8_t carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp256r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; + tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; + tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; + tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; + tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; + tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; + tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; + tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s2 */ + tmp[12] = product[48]; tmp[13] = product[49]; tmp[14] = product[50]; tmp[15] = product[51]; + tmp[16] = product[52]; tmp[17] = product[53]; tmp[18] = product[54]; tmp[19] = product[55]; + tmp[20] = product[56]; tmp[21] = product[57]; tmp[22] = product[58]; tmp[23] = product[59]; + tmp[24] = product[60]; tmp[25] = product[61]; tmp[26] = product[62]; tmp[27] = product[63]; + tmp[28] = tmp[29] = tmp[30] = tmp[31] = 0; + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s3 */ + tmp[0] = product[32]; tmp[1] = product[33]; tmp[2] = product[34]; tmp[3] = product[35]; + tmp[4] = product[36]; tmp[5] = product[37]; tmp[6] = product[38]; tmp[7] = product[39]; + tmp[8] = product[40]; tmp[9] = product[41]; tmp[10] = product[42]; tmp[11] = product[43]; + tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; + tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s4 */ + tmp[0] = product[36]; tmp[1] = product[37]; tmp[2] = product[38]; tmp[3] = product[39]; + tmp[4] = product[40]; tmp[5] = product[41]; tmp[6] = product[42]; tmp[7] = product[43]; + tmp[8] = product[44]; tmp[9] = product[45]; tmp[10] = product[46]; tmp[11] = product[47]; + tmp[12] = product[52]; tmp[13] = product[53]; tmp[14] = product[54]; tmp[15] = product[55]; + tmp[16] = product[56]; tmp[17] = product[57]; tmp[18] = product[58]; tmp[19] = product[59]; + tmp[20] = product[60]; tmp[21] = product[61]; tmp[22] = product[62]; tmp[23] = product[63]; + tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; + tmp[28] = product[32]; tmp[29] = product[33]; tmp[30] = product[34]; tmp[31] = product[35]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* d1 */ + tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; + tmp[4] = product[48]; tmp[5] = product[49]; tmp[6] = product[50]; tmp[7] = product[51]; + tmp[8] = product[52]; tmp[9] = product[53]; tmp[10] = product[54]; tmp[11] = product[55]; + tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = product[32]; tmp[25] = product[33]; tmp[26] = product[34]; tmp[27] = product[35]; + tmp[28] = product[40]; tmp[29] = product[41]; tmp[30] = product[42]; tmp[31] = product[43]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d2 */ + tmp[0] = product[48]; tmp[1] = product[49]; tmp[2] = product[50]; tmp[3] = product[51]; + tmp[4] = product[52]; tmp[5] = product[53]; tmp[6] = product[54]; tmp[7] = product[55]; + tmp[8] = product[56]; tmp[9] = product[57]; tmp[10] = product[58]; tmp[11] = product[59]; + tmp[12] = product[60]; tmp[13] = product[61]; tmp[14] = product[62]; tmp[15] = product[63]; + tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; + tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; + tmp[24] = product[36]; tmp[25] = product[37]; tmp[26] = product[38]; tmp[27] = product[39]; + tmp[28] = product[44]; tmp[29] = product[45]; tmp[30] = product[46]; tmp[31] = product[47]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d3 */ + tmp[0] = product[52]; tmp[1] = product[53]; tmp[2] = product[54]; tmp[3] = product[55]; + tmp[4] = product[56]; tmp[5] = product[57]; tmp[6] = product[58]; tmp[7] = product[59]; + tmp[8] = product[60]; tmp[9] = product[61]; tmp[10] = product[62]; tmp[11] = product[63]; + tmp[12] = product[32]; tmp[13] = product[33]; tmp[14] = product[34]; tmp[15] = product[35]; + tmp[16] = product[36]; tmp[17] = product[37]; tmp[18] = product[38]; tmp[19] = product[39]; + tmp[20] = product[40]; tmp[21] = product[41]; tmp[22] = product[42]; tmp[23] = product[43]; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + tmp[28] = product[48]; tmp[29] = product[49]; tmp[30] = product[50]; tmp[31] = product[51]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d4 */ + tmp[0] = product[56]; tmp[1] = product[57]; tmp[2] = product[58]; tmp[3] = product[59]; + tmp[4] = product[60]; tmp[5] = product[61]; tmp[6] = product[62]; tmp[7] = product[63]; + tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; + tmp[12] = product[36]; tmp[13] = product[37]; tmp[14] = product[38]; tmp[15] = product[39]; + tmp[16] = product[40]; tmp[17] = product[41]; tmp[18] = product[42]; tmp[19] = product[43]; + tmp[20] = product[44]; tmp[21] = product[45]; tmp[22] = product[46]; tmp[23] = product[47]; + tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; + tmp[28] = product[52]; tmp[29] = product[53]; tmp[30] = product[54]; tmp[31] = product[55]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + } + } +} +#elif uECC_WORD_SIZE == 4 +static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { + uint32_t tmp[num_words_secp256r1]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp256r1); + + /* s1 */ + tmp[0] = tmp[1] = tmp[2] = 0; + tmp[3] = product[11]; + tmp[4] = product[12]; + tmp[5] = product[13]; + tmp[6] = product[14]; + tmp[7] = product[15]; + carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s2 */ + tmp[3] = product[12]; + tmp[4] = product[13]; + tmp[5] = product[14]; + tmp[6] = product[15]; + tmp[7] = 0; + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s3 */ + tmp[0] = product[8]; + tmp[1] = product[9]; + tmp[2] = product[10]; + tmp[3] = tmp[4] = tmp[5] = 0; + tmp[6] = product[14]; + tmp[7] = product[15]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s4 */ + tmp[0] = product[9]; + tmp[1] = product[10]; + tmp[2] = product[11]; + tmp[3] = product[13]; + tmp[4] = product[14]; + tmp[5] = product[15]; + tmp[6] = product[13]; + tmp[7] = product[8]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* d1 */ + tmp[0] = product[11]; + tmp[1] = product[12]; + tmp[2] = product[13]; + tmp[3] = tmp[4] = tmp[5] = 0; + tmp[6] = product[8]; + tmp[7] = product[10]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d2 */ + tmp[0] = product[12]; + tmp[1] = product[13]; + tmp[2] = product[14]; + tmp[3] = product[15]; + tmp[4] = tmp[5] = 0; + tmp[6] = product[9]; + tmp[7] = product[11]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d3 */ + tmp[0] = product[13]; + tmp[1] = product[14]; + tmp[2] = product[15]; + tmp[3] = product[8]; + tmp[4] = product[9]; + tmp[5] = product[10]; + tmp[6] = 0; + tmp[7] = product[12]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d4 */ + tmp[0] = product[14]; + tmp[1] = product[15]; + tmp[2] = 0; + tmp[3] = product[9]; + tmp[4] = product[10]; + tmp[5] = product[11]; + tmp[6] = 0; + tmp[7] = product[13]; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + } + } +} +#else +static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) { + uint64_t tmp[num_words_secp256r1]; + int carry; + + /* t */ + uECC_vli_set(result, product, num_words_secp256r1); + + /* s1 */ + tmp[0] = 0; + tmp[1] = product[5] & 0xffffffff00000000ull; + tmp[2] = product[6]; + tmp[3] = product[7]; + carry = (int)uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s2 */ + tmp[1] = product[6] << 32; + tmp[2] = (product[6] >> 32) | (product[7] << 32); + tmp[3] = product[7] >> 32; + carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s3 */ + tmp[0] = product[4]; + tmp[1] = product[5] & 0xffffffff; + tmp[2] = 0; + tmp[3] = product[7]; + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* s4 */ + tmp[0] = (product[4] >> 32) | (product[5] << 32); + tmp[1] = (product[5] >> 32) | (product[6] & 0xffffffff00000000ull); + tmp[2] = product[7]; + tmp[3] = (product[6] >> 32) | (product[4] << 32); + carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); + + /* d1 */ + tmp[0] = (product[5] >> 32) | (product[6] << 32); + tmp[1] = (product[6] >> 32); + tmp[2] = 0; + tmp[3] = (product[4] & 0xffffffff) | (product[5] << 32); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d2 */ + tmp[0] = product[6]; + tmp[1] = product[7]; + tmp[2] = 0; + tmp[3] = (product[4] >> 32) | (product[5] & 0xffffffff00000000ull); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d3 */ + tmp[0] = (product[6] >> 32) | (product[7] << 32); + tmp[1] = (product[7] >> 32) | (product[4] << 32); + tmp[2] = (product[4] >> 32) | (product[5] << 32); + tmp[3] = (product[6] << 32); + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + /* d4 */ + tmp[0] = product[7]; + tmp[1] = product[4] & 0xffffffff00000000ull; + tmp[2] = product[5]; + tmp[3] = product[6] & 0xffffffff00000000ull; + carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); + + if (carry < 0) { + do { + carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); + } while (carry < 0); + } else { + while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { + carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); + } + } +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) */ + +#endif /* uECC_SUPPORTS_secp256r1 */ + +#if uECC_SUPPORTS_secp256k1 + +static void double_jacobian_secp256k1(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve); +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product); +#endif + +static const struct uECC_Curve_t curve_secp256k1 = { + num_words_secp256k1, + num_bytes_secp256k1, + 256, /* num_n_bits */ + { BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(41, 41, 36, D0, 8C, 5E, D2, BF), + BYTES_TO_WORDS_8(3B, A0, 48, AF, E6, DC, AE, BA), + BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), + BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, + { BYTES_TO_WORDS_8(98, 17, F8, 16, 5B, 81, F2, 59), + BYTES_TO_WORDS_8(D9, 28, CE, 2D, DB, FC, 9B, 02), + BYTES_TO_WORDS_8(07, 0B, 87, CE, 95, 62, A0, 55), + BYTES_TO_WORDS_8(AC, BB, DC, F9, 7E, 66, BE, 79), + + BYTES_TO_WORDS_8(B8, D4, 10, FB, 8F, D0, 47, 9C), + BYTES_TO_WORDS_8(19, 54, 85, A6, 48, B4, 17, FD), + BYTES_TO_WORDS_8(A8, 08, 11, 0E, FC, FB, A4, 5D), + BYTES_TO_WORDS_8(65, C4, A3, 26, 77, DA, 3A, 48) }, + { BYTES_TO_WORDS_8(07, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), + BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00) }, + &double_jacobian_secp256k1, +#if uECC_SUPPORT_COMPRESSED_POINT + &mod_sqrt_default, +#endif + &x_side_secp256k1, +#if (uECC_OPTIMIZATION_LEVEL > 0) + &vli_mmod_fast_secp256k1 +#endif +}; + +uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } + + +/* Double in place */ +static void double_jacobian_secp256k1(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve) { + /* t1 = X, t2 = Y, t3 = Z */ + uECC_word_t t4[num_words_secp256k1]; + uECC_word_t t5[num_words_secp256k1]; + + if (uECC_vli_isZero(Z1, num_words_secp256k1)) { + return; + } + + uECC_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ + uECC_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ + uECC_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ + uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ + + uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ + uECC_vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ + if (uECC_vli_testBit(Y1, 0)) { + uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); + uECC_vli_rshift1(Y1, num_words_secp256k1); + Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); + } else { + uECC_vli_rshift1(Y1, num_words_secp256k1); + } + /* t2 = 3/2*(x1^2) = B */ + + uECC_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ + uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ + + uECC_vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ + uECC_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ + uECC_vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ +} + +/* Computes result = x^3 + b. result must not overlap x. */ +static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { + uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ + uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 */ + uECC_vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ +} + +#if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256k1) +static void omega_mult_secp256k1(uECC_word_t *result, const uECC_word_t *right); +static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { + uECC_word_t tmp[2 * num_words_secp256k1]; + uECC_word_t carry; + + uECC_vli_clear(tmp, num_words_secp256k1); + uECC_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); + + omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ + + carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ + uECC_vli_clear(product, num_words_secp256k1); + omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */ + carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ + + while (carry > 0) { + --carry; + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + } + if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, num_words_secp256k1) > 0) { + uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); + } +} + +#if uECC_WORD_SIZE == 1 +static void omega_mult_secp256k1(uint8_t * result, const uint8_t * right) { + /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t k; + + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + muladd(0xD1, right[0], &r0, &r1, &r2); + result[0] = r0; + r0 = r1; + r1 = r2; + /* r2 is still 0 */ + + for (k = 1; k < num_words_secp256k1; ++k) { + muladd(0x03, right[k - 1], &r0, &r1, &r2); + muladd(0xD1, right[k], &r0, &r1, &r2); + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + muladd(0x03, right[num_words_secp256k1 - 1], &r0, &r1, &r2); + result[num_words_secp256k1] = r0; + result[num_words_secp256k1 + 1] = r1; + /* add the 2^32 multiple */ + result[4 + num_words_secp256k1] = + uECC_vli_add(result + 4, result + 4, right, num_words_secp256k1); +} +#elif uECC_WORD_SIZE == 4 +static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { + /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + uint32_t carry = 0; + wordcount_t k; + + for (k = 0; k < num_words_secp256k1; ++k) { + uint64_t p = (uint64_t)0x3D1 * right[k] + carry; + result[k] = (uint32_t) p; + carry = p >> 32; + } + result[num_words_secp256k1] = carry; + /* add the 2^32 multiple */ + result[1 + num_words_secp256k1] = + uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); +} +#else +static void omega_mult_secp256k1(uint64_t * result, const uint64_t * right) { + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t k; + + /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ + for (k = 0; k < num_words_secp256k1; ++k) { + muladd(0x1000003D1ull, right[k], &r0, &r1, &r2); + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + result[num_words_secp256k1] = r0; +} +#endif /* uECC_WORD_SIZE */ +#endif /* (uECC_OPTIMIZATION_LEVEL > 0 && && !asm_mmod_fast_secp256k1) */ + +#endif /* uECC_SUPPORTS_secp256k1 */ + +#endif /* _UECC_CURVE_SPECIFIC_H_ */ diff --git a/core/embed/ble_bootloader/uecc/emk_project.py b/core/embed/ble_bootloader/uecc/emk_project.py new file mode 100644 index 000000000..957dd7920 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/emk_project.py @@ -0,0 +1,132 @@ +import os + +c, link, asm, utils = emk.module("c", "link", "asm", "utils") + +default_compile_flags = ["-fvisibility=hidden", "-Wall", "-Wextra", "-Wshadow", "-Werror", "-Wno-missing-field-initializers", "-Wno-unused-parameter", \ + "-Wno-comment", "-Wno-unused", "-Wno-unknown-pragmas"] +default_link_flags = [] +opt_flags = {"dbg":["-g"], "std":["-O2"], "max":["-O3"], "small":["-Os"]} +opt_link_flags = {"dbg":[], "std":[], "max":[], "small":[]} +c_flags = ["-std=c99"] +cxx_flags = ["-std=c++11", "-Wno-reorder", "-fno-rtti", "-fno-exceptions"] +c_link_flags = [] +cxx_link_flags = ["-fno-rtti", "-fno-exceptions"] + +if "root" in emk.options: + root = emk.options["root"] +else: + root = "/" + +def setup_build_dir(): + build_arch = None + if "arch" in emk.options: + build_arch = emk.options["arch"] + elif not emk.cleaning: + build_arch = "osx" + emk.options["arch"] = build_arch + + opt_level = None + if "opt" in emk.options: + level = emk.options["opt"] + if level in opt_flags: + opt_level = level + else: + emk.log.warning("Unknown optimization level '%s'" % (level)) + elif not emk.cleaning: + opt_level = "dbg" + emk.options["opt"] = opt_level + + dirs = ["__build__"] + if build_arch: + dirs.append(build_arch) + if opt_level: + dirs.append(opt_level) + emk.build_dir = os.path.join(*dirs) + +def setup_osx(): + global c + global link + + flags = [("-arch", "x86_64"), "-fno-common", "-Wnewline-eof"] + c.flags.extend(flags) + c.cxx.flags += ["-stdlib=libc++"] + link.cxx.flags += ["-stdlib=libc++"] + + link_flags = [("-arch", "x86_64")] + link.local_flags.extend(link_flags) + +def setup_avr(): + global c + global link + + c.compiler = c.GccCompiler(root + "Projects/avr-tools/bin/avr-") + c.flags += ["-mmcu=atmega256rfr2", "-ffunction-sections", "-fdata-sections"] + link.linker = link.GccLinker(root + "Projects/avr-tools/bin/avr-") + link.flags += ["-mmcu=atmega256rfr2", "-mrelax", "-Wl,--gc-sections"] + link.strip = True + +def setup_arm_thumb(): + global c + global link + global asm + global utils + + asm.assembler = asm.GccAssembler(root + "cross/arm_cortex/bin/arm-none-eabi-") + c.compiler = c.GccCompiler(root + "cross/arm_cortex/bin/arm-none-eabi-") + link.linker = link.GccLinker(root + "cross/arm_cortex/bin/arm-none-eabi-") + + c.flags.extend(["-mcpu=cortex-m0", "-mthumb", "-ffunction-sections", "-fdata-sections", "-fno-builtin-fprintf", "-fno-builtin-printf"]) + c.defines["LPC11XX"] = 1 + + link.local_flags.extend(["-mcpu=cortex-m0", "-mthumb", "-nostartfiles", "-nostdlib", "-Wl,--gc-sections"]) + link.local_flags.extend(["-Tflash.lds", "-L" + root + "Projects/lpc11xx/core", root + "Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o"]) + link.local_syslibs += ["gcc"] + link.depdirs += [root + "Projects/lpc11xx/stdlib"] + + def do_objcopy(produces, requires): + utils.call(root + "cross/arm_cortex/bin/arm-none-eabi-objcopy", "-O", "binary", requires[0], produces[0]) + + def handle_exe(path): + emk.depend(path, root + "Projects/lpc11xx/core/" + emk.build_dir + "/board_cstartup.o") + emk.rule(do_objcopy, path + ".bin", path, cwd_safe=True, ex_safe=True) + emk.autobuild(path + ".bin") + + link.exe_funcs.append(handle_exe) + link.strip = True + + emk.recurse(root + "Projects/lpc11xx/core") + +def setup_linux_rpi(): + global c + global link + + c.compiler = c.GccCompiler("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") + link.linker = link.GccLinker("/Volumes/xtools/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-") + + c.flags.extend(["-fomit-frame-pointer"]) + +setup_build_dir() + +setup_funcs = {"osx":setup_osx, "avr":setup_avr, "arm_thumb":setup_arm_thumb, "rpi": setup_linux_rpi} + +if not emk.cleaning: + build_arch = emk.options["arch"] + opt_level = emk.options["opt"] + + c.flags.extend(default_compile_flags) + c.flags.extend(opt_flags[opt_level]) + c.c.flags.extend(c_flags) + c.cxx.flags.extend(cxx_flags) + link.local_flags.extend(default_link_flags) + link.local_flags.extend(opt_link_flags[opt_level]) + link.c.local_flags.extend(c_link_flags) + link.cxx.local_flags.extend(cxx_link_flags) + + c.include_dirs.append("$:proj:$") + + if build_arch in setup_funcs: + setup_funcs[build_arch]() + else: + raise emk.BuildError("Unknown target arch '%s'" % (build_arch)) + + c.defines["TARGET_ARCH_" + build_arch.upper()] = 1 diff --git a/core/embed/ble_bootloader/uecc/emk_rules.py b/core/embed/ble_bootloader/uecc/emk_rules.py new file mode 100644 index 000000000..b1d76c81a --- /dev/null +++ b/core/embed/ble_bootloader/uecc/emk_rules.py @@ -0,0 +1,3 @@ +c, link = emk.module("c", "link") + +emk.subdir("test") diff --git a/core/embed/ble_bootloader/uecc/examples/ecc_test/ecc_test.ino b/core/embed/ble_bootloader/uecc/examples/ecc_test/ecc_test.ino new file mode 100644 index 000000000..64a0be50f --- /dev/null +++ b/core/embed/ble_bootloader/uecc/examples/ecc_test/ecc_test.ino @@ -0,0 +1,80 @@ +#include + +static int RNG(uint8_t *dest, unsigned size) { + // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of + // random noise). This can take a long time to generate random data if the result of analogRead(0) + // doesn't change very frequently. + while (size) { + uint8_t val = 0; + for (unsigned i = 0; i < 8; ++i) { + int init = analogRead(0); + int count = 0; + while (analogRead(0) == init) { + ++count; + } + + if (count == 0) { + val = (val << 1) | (init & 0x01); + } else { + val = (val << 1) | (count & 0x01); + } + } + *dest = val; + ++dest; + --size; + } + // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar. + return 1; +} + +void setup() { + Serial.begin(115200); + Serial.print("Testing ecc\n"); + uECC_set_rng(&RNG); +} + +void loop() { + const struct uECC_Curve_t * curve = uECC_secp160r1(); + uint8_t private1[21]; + uint8_t private2[21]; + + uint8_t public1[40]; + uint8_t public2[40]; + + uint8_t secret1[20]; + uint8_t secret2[20]; + + unsigned long a = millis(); + uECC_make_key(public1, private1, curve); + unsigned long b = millis(); + + Serial.print("Made key 1 in "); Serial.println(b-a); + a = millis(); + uECC_make_key(public2, private2, curve); + b = millis(); + Serial.print("Made key 2 in "); Serial.println(b-a); + + a = millis(); + int r = uECC_shared_secret(public2, private1, secret1, curve); + b = millis(); + Serial.print("Shared secret 1 in "); Serial.println(b-a); + if (!r) { + Serial.print("shared_secret() failed (1)\n"); + return; + } + + a = millis(); + r = uECC_shared_secret(public1, private2, secret2, curve); + b = millis(); + Serial.print("Shared secret 2 in "); Serial.println(b-a); + if (!r) { + Serial.print("shared_secret() failed (2)\n"); + return; + } + + if (memcmp(secret1, secret2, 20) != 0) { + Serial.print("Shared secrets are not identical!\n"); + } else { + Serial.print("Shared secrets are identical\n"); + } +} diff --git a/core/embed/ble_bootloader/uecc/library.properties b/core/embed/ble_bootloader/uecc/library.properties new file mode 100644 index 000000000..390bdc87a --- /dev/null +++ b/core/embed/ble_bootloader/uecc/library.properties @@ -0,0 +1,9 @@ +name=micro-ecc +version=1.0.0 +author=Kenneth MacKay +maintainer=Kenneth MacKay +sentence=uECC +paragraph=A small and fast ECDH and ECDSA implementation for 8-bit, 32-bit, and 64-bit processors. +category=Other +url=https://github.com/kmackay/micro-ecc +architectures=* diff --git a/core/embed/ble_bootloader/uecc/platform-specific.inc b/core/embed/ble_bootloader/uecc/platform-specific.inc new file mode 100644 index 000000000..7e0373f50 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/platform-specific.inc @@ -0,0 +1,94 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_PLATFORM_SPECIFIC_H_ +#define _UECC_PLATFORM_SPECIFIC_H_ + +#include "types.h" + +#if (defined(_WIN32) || defined(_WIN64)) +/* Windows */ + +// use pragma syntax to prevent tweaking the linker script for getting CryptXYZ function +#pragma comment(lib, "crypt32.lib") +#pragma comment(lib, "advapi32.lib") + +#define WIN32_LEAN_AND_MEAN +#include +#include + +static int default_RNG(uint8_t *dest, unsigned size) { + HCRYPTPROV prov; + if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { + return 0; + } + + CryptGenRandom(prov, size, (BYTE *)dest); + CryptReleaseContext(prov, 0); + return 1; +} +#define default_RNG_defined 1 + +#elif defined(unix) || defined(__linux__) || defined(__unix__) || defined(__unix) || \ + (defined(__APPLE__) && defined(__MACH__)) || defined(uECC_POSIX) + +/* Some POSIX-like system with /dev/urandom or /dev/random. */ +#include +#include +#include + +#ifndef O_CLOEXEC + #define O_CLOEXEC 0 +#endif + +static int default_RNG(uint8_t *dest, unsigned size) { + int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + fd = open("/dev/random", O_RDONLY | O_CLOEXEC); + if (fd == -1) { + return 0; + } + } + + char *ptr = (char *)dest; + size_t left = size; + while (left > 0) { + ssize_t bytes_read = read(fd, ptr, left); + if (bytes_read <= 0) { // read failed + close(fd); + return 0; + } + left -= bytes_read; + ptr += bytes_read; + } + + close(fd); + return 1; +} +#define default_RNG_defined 1 + +#elif defined(RIOT_VERSION) + +#include + +static int default_RNG(uint8_t *dest, unsigned size) { + random_bytes(dest, size); + return 1; +} +#define default_RNG_defined 1 + +#elif defined(NRF52_SERIES) + +#include "app_error.h" +#include "nrf_crypto_rng.h" + +static int default_RNG(uint8_t *dest, unsigned size) +{ + // make sure to call nrf_crypto_init and nrf_crypto_rng_init first + ret_code_t ret_code = nrf_crypto_rng_vector_generate(dest, size); + return (ret_code == NRF_SUCCESS) ? 1 : 0; +} +#define default_RNG_defined 1 + +#endif /* platform */ + +#endif /* _UECC_PLATFORM_SPECIFIC_H_ */ diff --git a/core/embed/ble_bootloader/uecc/scripts/mult_arm.py b/core/embed/ble_bootloader/uecc/scripts/mult_arm.py new file mode 100755 index 000000000..402ace190 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/scripts/mult_arm.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in 32-bit words" + sys.exit(1) + +size = int(sys.argv[1]) + +full_rows = size // 3 +init_size = size % 3 + +if init_size == 0: + full_rows = full_rows - 1 + init_size = 3 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +rx = [3, 4, 5] +ry = [6, 7, 8] + +#### set up registers +emit("add r0, %s", (size - init_size) * 4) # move z +emit("add r2, %s", (size - init_size) * 4) # move y + +emit("ldmia r1!, {%s}", ", ".join(["r%s" % (rx[i]) for i in xrange(init_size)])) +emit("ldmia r2!, {%s}", ", ".join(["r%s" % (ry[i]) for i in xrange(init_size)])) + +print "" +if init_size == 1: + emit("umull r9, r10, r3, r6") + emit("stmia r0!, {r9, r10}") +else: + #### first two multiplications of initial block + emit("umull r11, r12, r3, r6") + emit("stmia r0!, {r11}") + print "" + emit("mov r10, #0") + emit("umull r11, r9, r3, r7") + emit("adds r12, r12, r11") + emit("adc r9, r9, #0") + emit("umull r11, r14, r4, r6") + emit("adds r12, r12, r11") + emit("adcs r9, r9, r14") + emit("adc r10, r10, #0") + emit("stmia r0!, {r12}") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [9, 10, 11, 12, 14] + if init_size == 3: + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 2): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i + 1], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[init_size-1], ry[init_size-1]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adc r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("stmia r0!, {r%s}", acc[0]) + emit("stmia r0!, {r%s}", acc[1]) +print "" + +#### reset y and z pointers +emit("sub r0, %s", (2 * init_size + 3) * 4) +emit("sub r2, %s", (init_size + 3) * 4) + +#### load y registers +emit("ldmia r2!, {%s}", ", ".join(["r%s" % (ry[i]) for i in xrange(3)])) + +#### load additional x registers +if init_size != 3: + emit("ldmia r1!, {%s}", ", ".join(["r%s" % (rx[i]) for i in xrange(init_size, 3)])) +print "" + +prev_size = init_size +for row in xrange(full_rows): + emit("umull r11, r12, r3, r6") + emit("stmia r0!, {r11}") + print "" + emit("mov r10, #0") + emit("umull r11, r9, r3, r7") + emit("adds r12, r12, r11") + emit("adc r9, r9, #0") + emit("umull r11, r14, r4, r6") + emit("adds r12, r12, r11") + emit("adcs r9, r9, r14") + emit("adc r10, r10, #0") + emit("stmia r0!, {r12}") + print "" + + acc = [9, 10, 11, 12, 14] + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], rx[i], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + #### now we need to start shifting x and loading from z + x_regs = [3, 4, 5] + for r in xrange(0, prev_size): + x_regs = x_regs[1:] + x_regs[:1] + emit("ldmia r1!, {r%s}", x_regs[2]) + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i], ry[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("ldr r%s, [r0]", acc[3]) # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, #0", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # done shifting x, start shifting y + y_regs = [6, 7, 8] + for r in xrange(0, prev_size): + y_regs = y_regs[1:] + y_regs[:1] + emit("ldmia r2!, {r%s}", y_regs[2]) + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 3): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i], y_regs[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("ldr r%s, [r0]", acc[3]) # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, #0", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # done both shifts, do remaining corner + emit("mov r%s, #0", acc[2]) + for i in xrange(0, 2): + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[i + 1], y_regs[2 - i]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + emit("stmia r0!, {r%s}", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + emit("umull r%s, r%s, r%s, r%s", acc[3], acc[4], x_regs[2], y_regs[2]) + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[3]) + emit("adc r%s, r%s, r%s", acc[1], acc[1], acc[4]) + emit("stmia r0!, {r%s}", acc[0]) + emit("stmia r0!, {r%s}", acc[1]) + print "" + + prev_size = prev_size + 3 + if row < full_rows - 1: + #### reset x, y and z pointers + emit("sub r0, %s", (2 * prev_size + 3) * 4) + emit("sub r1, %s", prev_size * 4) + emit("sub r2, %s", (prev_size + 3) * 4) + + #### load x and y registers + emit("ldmia r1!, {%s}", ",".join(["r%s" % (rx[i]) for i in xrange(3)])) + emit("ldmia r2!, {%s}", ",".join(["r%s" % (ry[i]) for i in xrange(3)])) + + print "" diff --git a/core/embed/ble_bootloader/uecc/scripts/mult_avr.py b/core/embed/ble_bootloader/uecc/scripts/mult_avr.py new file mode 100755 index 000000000..d40e4c23d --- /dev/null +++ b/core/embed/ble_bootloader/uecc/scripts/mult_avr.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in bytes" + sys.exit(1) + +size = int(sys.argv[1]) + +full_rows = size // 10 +init_size = size % 10 + +if init_size == 0: + full_rows = full_rows - 1 + init_size = 10 + +def rx(i): + return i + 2 + +def ry(i): + return i + 12 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +#### set up registers +emit("adiw r30, %s", size - init_size) # move z +emit("adiw r28, %s", size - init_size) # move y + +for i in xrange(init_size): + emit("ld r%s, x+", rx(i)) +for i in xrange(init_size): + emit("ld r%s, y+", ry(i)) + +emit("ldi r25, 0") +print "" +if init_size == 1: + emit("mul r2, r12") + emit("st z+, r0") + emit("st z+, r1") +else: + #### first two multiplications of initial block + emit("ldi r23, 0") + emit("mul r2, r12") + emit("st z+, r0") + emit("mov r22, r1") + print "" + emit("ldi r24, 0") + emit("mul r2, r13") + emit("add r22, r0") + emit("adc r23, r1") + emit("mul r3, r12") + emit("add r22, r0") + emit("adc r23, r1") + emit("adc r24, r25") + emit("st z+, r22") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [23, 24, 22] + for r in xrange(2, init_size): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, r+1): + emit("mul r%s, r%s", rx(i), ry(r - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + for r in xrange(1, init_size-1): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, init_size-r): + emit("mul r%s, r%s", rx(r+i), ry((init_size-1) - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + emit("mul r%s, r%s", rx(init_size-1), ry(init_size-1)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("st z+, r%s", acc[0]) + emit("st z+, r%s", acc[1]) +print "" + +#### reset y and z pointers +emit("sbiw r30, %s", 2 * init_size + 10) +emit("sbiw r28, %s", init_size + 10) + +#### load y registers +for i in xrange(10): + emit("ld r%s, y+", ry(i)) + +#### load additional x registers +for i in xrange(init_size, 10): + emit("ld r%s, x+", rx(i)) +print "" + +prev_size = init_size +for row in xrange(full_rows): + #### do x = 0-9, y = 0-9 multiplications + emit("ldi r23, 0") + emit("mul r2, r12") + emit("st z+, r0") + emit("mov r22, r1") + print "" + emit("ldi r24, 0") + emit("mul r2, r13") + emit("add r22, r0") + emit("adc r23, r1") + emit("mul r3, r12") + emit("add r22, r0") + emit("adc r23, r1") + emit("adc r24, r25") + emit("st z+, r22") + print "" + + acc = [23, 24, 22] + for r in xrange(2, 10): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, r+1): + emit("mul r%s, r%s", rx(i), ry(r - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + #### now we need to start shifting x and loading from z + x_regs = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + for r in xrange(0, prev_size): + x_regs = x_regs[1:] + x_regs[:1] + emit("ld r%s, x+", x_regs[9]) # load next byte of left + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, 10): + emit("mul r%s, r%s", x_regs[i], ry(9 - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r25", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) # store next byte (z increments) + print "" + acc = acc[1:] + acc[:1] + + # done shifting x, start shifting y + y_regs = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21] + for r in xrange(0, prev_size): + y_regs = y_regs[1:] + y_regs[:1] + emit("ld r%s, y+", y_regs[9]) # load next byte of right + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, 10): + emit("mul r%s, r%s", x_regs[i], y_regs[9 -i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r25", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) # store next byte (z increments) + print "" + acc = acc[1:] + acc[:1] + + # done both shifts, do remaining corner + for r in xrange(1, 9): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, 10-r): + emit("mul r%s, r%s", x_regs[r+i], y_regs[9 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, r25", acc[2]) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + emit("mul r%s, r%s", x_regs[9], y_regs[9]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("st z+, r%s", acc[0]) + emit("st z+, r%s", acc[1]) + print "" + + prev_size = prev_size + 10 + if row < full_rows - 1: + #### reset x, y and z pointers + emit("sbiw r30, %s", 2 * prev_size + 10) + emit("sbiw r28, %s", prev_size + 10) + emit("sbiw r26, %s", prev_size) + + #### load x and y registers + for i in xrange(10): + emit("ld r%s, x+", rx(i)) + emit("ld r%s, y+", ry(i)) + print "" + +emit("eor r1, r1") diff --git a/core/embed/ble_bootloader/uecc/scripts/mult_avr_extra.py b/core/embed/ble_bootloader/uecc/scripts/mult_avr_extra.py new file mode 100755 index 000000000..f6e654f6a --- /dev/null +++ b/core/embed/ble_bootloader/uecc/scripts/mult_avr_extra.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in bytes" + sys.exit(1) + +size = int(sys.argv[1]) + +def lhi(i): + return i + 2 + +def rhi(i): + return i + 6 + +left_lo = [10, 11, 12, 13] +right_lo = [14, 15, 16, 17] + +def llo(i): + return left_lo[i] + +def rlo(i): + return right_lo[i] + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +def update_low(): + global left_lo + global right_lo + left_lo = left_lo[1:] + left_lo[:1] + right_lo = right_lo[1:] + right_lo[:1] + emit("ld r%s, x+", left_lo[3]) + emit("ld r%s, y+", right_lo[3]) + +accum = [19, 20, 21] + +def acc(i): + return accum[i] + +def rotate_acc(): + global accum + accum = accum[1:] + accum[:1] + +# Load high values +for i in xrange(4): + emit("ld r%s, x+", lhi(i)) + emit("ld r%s, y+", rhi(i)) + +emit("sbiw r26, %s", size + 4) +emit("sbiw r28, %s", size + 4) +emit("sbiw r30, %s", size) + +# Load low values +for i in xrange(4): + emit("ld r%s, x+", llo(i)) + emit("ld r%s, y+", rlo(i)) +print "" + +# Compute initial triangles +emit("mul r%s, r%s", lhi(0), rlo(0)) +emit("mov r%s, r0", acc(0)) +emit("mov r%s, r1", acc(1)) +emit("ldi r%s, 0", acc(2)) +emit("ld r0, z") +emit("add r%s, r0", acc(0)) +emit("adc r%s, r25", acc(1)) +emit("mul r%s, r%s", rhi(0), llo(0)) +emit("add r%s, r0", acc(0)) +emit("adc r%s, r1", acc(1)) +emit("adc r%s, r25", acc(2)) +emit("st z+, r%s", acc(0)) +print "" +rotate_acc() + +for i in xrange(1, 4): + emit("ldi r%s, 0", acc(2)) + emit("ld r0, z") + emit("add r%s, r0", acc(0)) + emit("adc r%s, r25", acc(1)) + for j in xrange(i + 1): + emit("mul r%s, r%s", lhi(j), rlo(i-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("mul r%s, r%s", rhi(j), llo(i-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("st z+, r%s", acc(0)) + print "" + rotate_acc() + +# Compute rows overlapping old block +for i in xrange(4, size): + emit("ldi r%s, 0", acc(2)) + emit("ld r0, z") + emit("add r%s, r0", acc(0)) + emit("adc r%s, r25", acc(1)) + update_low() + for j in xrange(4): + emit("mul r%s, r%s", lhi(j), rlo(3-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("mul r%s, r%s", rhi(j), llo(3-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("st z+, r%s", acc(0)) + print "" + rotate_acc() + +# Compute new triangle +left_combined = [llo(1), llo(2), llo(3), lhi(0), lhi(1), lhi(2), lhi(3)] +right_combined = [rlo(1), rlo(2), rlo(3), rhi(0), rhi(1), rhi(2), rhi(3)] + +def left(i): + return left_combined[i] + +def right(i): + return right_combined[i] + +for i in xrange(6): + emit("ldi r%s, 0", acc(2)) + for j in xrange(7 - i): + emit("mul r%s, r%s", left(i+j), right(6-j)) + emit("add r%s, r0", acc(0)) + emit("adc r%s, r1", acc(1)) + emit("adc r%s, r25", acc(2)) + emit("st z+, r%s", acc(0)) + print "" + rotate_acc() + +emit("mul r%s, r%s", left(6), right(6)) +emit("add r%s, r0", acc(0)) +emit("adc r%s, r1", acc(1)) +emit("st z+, r%s", acc(0)) +emit("st z+, r%s", acc(1)) +emit("adiw r26, 4") +emit("adiw r28, 4") diff --git a/core/embed/ble_bootloader/uecc/scripts/square_arm.py b/core/embed/ble_bootloader/uecc/scripts/square_arm.py new file mode 100755 index 000000000..5330c7e63 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/scripts/square_arm.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in 32-bit words" + sys.exit(1) + +size = int(sys.argv[1]) + +if size > 8: + print "This script doesn't work with integer size %s due to laziness" % (size) + sys.exit(1) + +init_size = 0 +if size > 6: + init_size = size - 6 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +def mulacc(acc, r1, r2): + if size <= 6: + emit("umull r1, r14, r%s, r%s", r1, r2) + emit("adds r%s, r%s, r1", acc[0], acc[0]) + emit("adcs r%s, r%s, r14", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + else: + emit("mov r14, r%s", acc[1]) + emit("umlal r%s, r%s, r%s, r%s", acc[0], acc[1], r1, r2) + emit("cmp r14, r%s", acc[1]) + emit("it hi") + emit("adchi r%s, r%s, #0", acc[2], acc[2]) + +r = [2, 3, 4, 5, 6, 7] + +s = size - init_size + +if init_size == 1: + emit("ldmia r1!, {r2}") + emit("add r1, %s", (size - init_size * 2) * 4) + emit("ldmia r1!, {r5}") + + emit("add r0, %s", (size - init_size) * 4) + emit("umull r8, r9, r2, r5") + emit("stmia r0!, {r8, r9}") + + emit("sub r0, %s", (size + init_size) * 4) + emit("sub r1, %s", (size) * 4) + print "" +elif init_size == 2: + emit("ldmia r1!, {r2, r3}") + emit("add r1, %s", (size - init_size * 2) * 4) + emit("ldmia r1!, {r5, r6}") + + emit("add r0, %s", (size - init_size) * 4) + print "" + + emit("umull r8, r9, r2, r5") + emit("stmia r0!, {r8}") + print "" + + emit("umull r12, r10, r2, r6") + emit("adds r9, r9, r12") + emit("adc r10, r10, #0") + emit("stmia r0!, {r9}") + print "" + + emit("umull r8, r9, r3, r6") + emit("adds r10, r10, r8") + emit("adc r11, r9, #0") + emit("stmia r0!, {r10, r11}") + print "" + + emit("sub r0, %s", (size + init_size) * 4) + emit("sub r1, %s", (size) * 4) + +# load input words +emit("ldmia r1!, {%s}", ", ".join(["r%s" % (r[i]) for i in xrange(s)])) +print "" + +emit("umull r11, r12, r2, r2") +emit("stmia r0!, {r11}") +print "" +emit("mov r9, #0") +emit("umull r10, r11, r2, r3") +emit("adds r12, r12, r10") +emit("adcs r8, r11, #0") +emit("adc r9, r9, #0") +emit("adds r12, r12, r10") +emit("adcs r8, r8, r11") +emit("adc r9, r9, #0") +emit("stmia r0!, {r12}") +print "" +emit("mov r10, #0") +emit("umull r11, r12, r2, r4") +emit("adds r11, r11, r11") +emit("adcs r12, r12, r12") +emit("adc r10, r10, #0") +emit("adds r8, r8, r11") +emit("adcs r9, r9, r12") +emit("adc r10, r10, #0") +emit("umull r11, r12, r3, r3") +emit("adds r8, r8, r11") +emit("adcs r9, r9, r12") +emit("adc r10, r10, #0") +emit("stmia r0!, {r8}") +print "" + +acc = [8, 9, 10] +old_acc = [11, 12] +for i in xrange(3, s): + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], r[0], r[i]) + for j in xrange(1, (i+1)//2): + mulacc(acc, r[j], r[i-j]) + # multiply by 2 + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[1]) + emit("adc r%s, r%s, r%s", acc[2], acc[2], acc[2]) + + # add equal word (if any) + if ((i+1) % 2) != 0: + mulacc(acc, r[i//2], r[i//2]) + + # add old accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], old_acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +regs = list(r) +for i in xrange(init_size): + regs = regs[1:] + regs[:1] + emit("ldmia r1!, {r%s}", regs[5]) + + for limit in [4, 5]: + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], regs[0], regs[limit]) + for j in xrange(1, (limit+1)//2): + mulacc(acc, regs[j], regs[limit-j]) + + emit("ldr r14, [r0]") # load stored value from initial block, and add to accumulator + emit("adds r%s, r%s, r14", acc[0], acc[0]) + emit("adcs r%s, r%s, #0", acc[1], acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # multiply by 2 + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[1]) + emit("adc r%s, r%s, r%s", acc[2], acc[2], acc[2]) + + # add equal word + if limit == 4: + mulacc(acc, regs[2], regs[2]) + + # add old accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], old_acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +for i in xrange(1, s-3): + emit("mov r%s, #0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("umull r%s, r%s, r%s, r%s", acc[0], acc[1], regs[i], regs[s - 1]) + for j in xrange(1, (s-i)//2): + mulacc(acc, regs[i+j], regs[s - 1 - j]) + + # multiply by 2 + emit("adds r%s, r%s, r%s", acc[0], acc[0], acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], acc[1]) + emit("adc r%s, r%s, r%s", acc[2], acc[2], acc[2]) + + # add equal word (if any) + if ((s-i) % 2) != 0: + mulacc(acc, regs[i + (s-i)//2], regs[i + (s-i)//2]) + + # add old accumulator + emit("adds r%s, r%s, r%s", acc[0], acc[0], old_acc[0]) + emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) + emit("adc r%s, r%s, #0", acc[2], acc[2]) + + # store + emit("stmia r0!, {r%s}", acc[0]) + print "" + +acc = acc[1:] + acc[:1] +emit("mov r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 3], regs[s - 1]) +emit("adds r1, r1, r1") +emit("adcs r%s, r%s, r%s", old_acc[1], old_acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 2], regs[s - 2]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("stmia r0!, {r%s}", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("mov r%s, #0", acc[2]) +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 2], regs[s - 1]) +emit("adds r1, r1, r1") +emit("adcs r%s, r%s, r%s", old_acc[1], old_acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("adc r%s, r%s, #0", acc[2], acc[2]) +emit("stmia r0!, {r%s}", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("umull r1, r%s, r%s, r%s", old_acc[1], regs[s - 1], regs[s - 1]) +emit("adds r%s, r%s, r1", acc[0], acc[0]) +emit("adcs r%s, r%s, r%s", acc[1], acc[1], old_acc[1]) +emit("stmia r0!, {r%s}", acc[0]) +emit("stmia r0!, {r%s}", acc[1]) diff --git a/core/embed/ble_bootloader/uecc/scripts/square_avr.py b/core/embed/ble_bootloader/uecc/scripts/square_avr.py new file mode 100755 index 000000000..6571c3b3c --- /dev/null +++ b/core/embed/ble_bootloader/uecc/scripts/square_avr.py @@ -0,0 +1,327 @@ +#!/usr/bin/env python + +import sys + +if len(sys.argv) < 2: + print "Provide the integer size in bytes" + sys.exit(1) + +size = int(sys.argv[1]) + +if size > 40: + print "This script doesn't work with integer size %s due to laziness" % (size) + sys.exit(1) + +init_size = size - 20 +if size < 20: + init_size = 0 + +def rg(i): + return i + 2 + +def lo(i): + return i + 2 + +def hi(i): + return i + 12 + +def emit(line, *args): + s = '"' + line + r' \n\t"' + print s % args + +#### set up registers +zero = "r25" +emit("ldi %s, 0", zero) # zero register + +if init_size > 0: + emit("movw r28, r26") # y = x + h = (init_size + 1)//2 + + for i in xrange(h): + emit("ld r%s, x+", lo(i)) + emit("adiw r28, %s", size - init_size) # move y to other end + for i in xrange(h): + emit("ld r%s, y+", hi(i)) + + emit("adiw r30, %s", size - init_size) # move z + + if init_size == 1: + emit("mul %s, %s", lo(0), hi(0)) + emit("st z+, r0") + emit("st z+, r1") + else: + #### first one + print "" + emit("ldi r23, 0") + emit("mul %s, %s", lo(0), hi(0)) + emit("st z+, r0") + emit("mov r22, r1") + print "" + + #### rest of initial block, with moving accumulator registers + acc = [22, 23, 24] + for r in xrange(1, h): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (r+2)//2): + emit("mul r%s, r%s", lo(i), hi(r - i)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + lo_r = range(2, 2 + h) + hi_r = range(12, 12 + h) + + # now we need to start loading more from the high end + for r in xrange(h, init_size): + hi_r = hi_r[1:] + hi_r[:1] + emit("ld r%s, y+", hi_r[h-1]) + + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (r+2)//2): + emit("mul r%s, r%s", lo(i), hi_r[h - 1 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + # loaded all of the high end bytes; now need to start loading the rest of the low end + for r in xrange(1, init_size-h): + lo_r = lo_r[1:] + lo_r[:1] + emit("ld r%s, x+", lo_r[h-1]) + + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (init_size+1 - r)//2): + emit("mul r%s, r%s", lo_r[i], hi_r[h - 1 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + + lo_r = lo_r[1:] + lo_r[:1] + emit("ld r%s, x+", lo_r[h-1]) + + # now we have loaded everything, and we just need to finish the last corner + for r in xrange(init_size-h, init_size-1): + emit("ldi r%s, 0", acc[2]) + for i in xrange(0, (init_size+1 - r)//2): + emit("mul r%s, r%s", lo_r[i], hi_r[h - 1 - i]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + emit("st z+, r%s", acc[0]) + print "" + acc = acc[1:] + acc[:1] + lo_r = lo_r[1:] + lo_r[:1] # make the indexing easy + + emit("mul r%s, r%s", lo_r[0], hi_r[h - 1]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("st z+, r%s", acc[0]) + emit("st z+, r%s", acc[1]) + print "" + emit("sbiw r26, %s", init_size) # reset x + emit("sbiw r30, %s", size + init_size) # reset z + +# TODO you could do more rows of size 20 here if your integers are larger than 40 bytes + +s = size - init_size + +for i in xrange(s): + emit("ld r%s, x+", rg(i)) + +#### first few columns +# NOTE: this is only valid if size >= 3 +print "" +emit("ldi r23, 0") +emit("mul r%s, r%s", rg(0), rg(0)) +emit("st z+, r0") +emit("mov r22, r1") +print "" +emit("ldi r24, 0") +emit("mul r%s, r%s", rg(0), rg(1)) +emit("add r22, r0") +emit("adc r23, r1") +emit("adc r24, %s", zero) +emit("add r22, r0") +emit("adc r23, r1") +emit("adc r24, %s", zero) +emit("st z+, r22") +print "" +emit("ldi r22, 0") +emit("mul r%s, r%s", rg(0), rg(2)) +emit("add r23, r0") +emit("adc r24, r1") +emit("adc r22, %s", zero) +emit("add r23, r0") +emit("adc r24, r1") +emit("adc r22, %s", zero) +emit("mul r%s, r%s", rg(1), rg(1)) +emit("add r23, r0") +emit("adc r24, r1") +emit("adc r22, %s", zero) +emit("st z+, r23") +print "" + +acc = [23, 24, 22] +old_acc = [28, 29] +for i in xrange(3, s): + emit("ldi r%s, 0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("mul r%s, r%s", rg(0), rg(i)) + emit("mov r%s, r0", acc[0]) + emit("mov r%s, r1", acc[1]) + for j in xrange(1, (i+1)//2): + emit("mul r%s, r%s", rg(j), rg(i-j)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + # multiply by 2 + emit("lsl r%s", acc[0]) + emit("rol r%s", acc[1]) + emit("rol r%s", acc[2]) + + # add equal word (if any) + if ((i+1) % 2) != 0: + emit("mul r%s, r%s", rg(i//2), rg(i//2)) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # add old accumulator + emit("add r%s, r%s", acc[0], old_acc[0]) + emit("adc r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # store + emit("st z+, r%s", acc[0]) + print "" + +regs = range(2, 22) +for i in xrange(init_size): + regs = regs[1:] + regs[:1] + emit("ld r%s, x+", regs[19]) + + for limit in [18, 19]: + emit("ldi r%s, 0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("mul r%s, r%s", regs[0], regs[limit]) + emit("mov r%s, r0", acc[0]) + emit("mov r%s, r1", acc[1]) + for j in xrange(1, (limit+1)//2): + emit("mul r%s, r%s", regs[j], regs[limit-j]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r25", acc[1]) + emit("adc r%s, r25", acc[2]) + + # multiply by 2 + emit("lsl r%s", acc[0]) + emit("rol r%s", acc[1]) + emit("rol r%s", acc[2]) + + # add equal word + if limit == 18: + emit("mul r%s, r%s", regs[9], regs[9]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # add old accumulator + emit("add r%s, r%s", acc[0], old_acc[0]) + emit("adc r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # store + emit("st z+, r%s", acc[0]) + print "" + +for i in xrange(1, s-3): + emit("ldi r%s, 0", old_acc[1]) + tmp = [acc[1], acc[2]] + acc = [acc[0], old_acc[0], old_acc[1]] + old_acc = tmp + + # gather non-equal words + emit("mul r%s, r%s", regs[i], regs[s - 1]) + emit("mov r%s, r0", acc[0]) + emit("mov r%s, r1", acc[1]) + for j in xrange(1, (s-i)//2): + emit("mul r%s, r%s", regs[i+j], regs[s - 1 - j]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + # multiply by 2 + emit("lsl r%s", acc[0]) + emit("rol r%s", acc[1]) + emit("rol r%s", acc[2]) + + # add equal word (if any) + if ((s-i) % 2) != 0: + emit("mul r%s, r%s", regs[i + (s-i)//2], regs[i + (s-i)//2]) + emit("add r%s, r0", acc[0]) + emit("adc r%s, r1", acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # add old accumulator + emit("add r%s, r%s", acc[0], old_acc[0]) + emit("adc r%s, r%s", acc[1], old_acc[1]) + emit("adc r%s, %s", acc[2], zero) + + # store + emit("st z+, r%s", acc[0]) + print "" + +acc = acc[1:] + acc[:1] +emit("ldi r%s, 0", acc[2]) +emit("mul r%s, r%s", regs[17], regs[19]) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("mul r%s, r%s", regs[18], regs[18]) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("st z+, r%s", acc[0]) +print "" + +acc = acc[1:] + acc[:1] +emit("ldi r%s, 0", acc[2]) +emit("mul r%s, r%s", regs[18], regs[19]) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("add r%s, r0", acc[0]) +emit("adc r%s, r1", acc[1]) +emit("adc r%s, %s", acc[2], zero) +emit("st z+, r%s", acc[0]) +print "" + +emit("mul r%s, r%s", regs[19], regs[19]) +emit("add r%s, r0", acc[1]) +emit("adc r%s, r1", acc[2]) +emit("st z+, r%s", acc[1]) + +emit("st z+, r%s", acc[2]) +emit("eor r1, r1") diff --git a/core/embed/ble_bootloader/uecc/test/ecdsa_test_vectors.c b/core/embed/ble_bootloader/uecc/test/ecdsa_test_vectors.c new file mode 100644 index 000000000..1e902b266 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/test/ecdsa_test_vectors.c @@ -0,0 +1,128 @@ +/* Copyright 2020, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" + +#include +#include +#include + +typedef struct { + const char* private_key; + const char* public_key; + const char* k; + const char* hash; + const char* r; + const char* s; +} Test; + +Test secp256k1_tests[] = { + { + "ebb2c082fd7727890a28ac82f6bdf97bad8de9f5d7c9028692de1a255cad3e0f", + "779dd197a5df977ed2cf6cb31d82d43328b790dc6b3b7d4437a427bd5847dfcde94b724a555b6d017bb7607c3e3281daf5b1699d6ef4124975c9237b917d426f", + "49a0d7b786ec9cde0d0721d72804befd06571c974b191efb42ecf322ba9ddd9a", + "4b688df40bcedbe641ddb16ff0a1842d9c67ea1c3bf63f3e0471baa664531d1a", + "241097efbf8b63bf145c8961dbdf10c310efbb3b2676bbc0f8b08505c9e2f795", + "021006b7838609339e8b415a7f9acb1b661828131aef1ecbc7955dfb01f3ca0e" + }, +}; + +extern int uECC_sign_with_k(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *k, + uint8_t *signature, + uECC_Curve curve); + + +void vli_print(uint8_t *vli, unsigned int size) { + for(unsigned i=0; i +#include +#include + +typedef struct { + const char* k; + const char* Q; + int success; +} Test; + +Test secp160r1_tests[] = { + /* Note, I couldn't find any test vectors for secp160r1 online, so these are just + generated on my desktop using uECC. */ + { + "000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { + "000000000000000000000000000000000000000001", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { + "000000000000000000000000000000000000000002", + "02F997F33C5ED04C55D3EDF8675D3E92E8F46686F083A323482993E9440E817E21CFB7737DF8797B", + 1 + }, + { + "000000000000000000000000000000000000000003", + "7B76FF541EF363F2DF13DE1650BD48DAA958BC59C915CA790D8C8877B55BE0079D12854FFE9F6F5A", + 1 + }, + { /* n - 4 */ + "0100000000000000000001F4C8F927AED3CA752253", + "B4041D8683BE99F0AFE01C307B1AD4C100CF2A88C0CD35127BE0F73FF99F338B350B5A42864112F7", + 1 + }, + { /* n - 3 */ + "0100000000000000000001F4C8F927AED3CA752254", + "7B76FF541EF363F2DF13DE1650BD48DAA958BC5936EA3586F27377884AA41FF862ED7AAF816090A5", + 1 + }, + { /* n - 2 */ + "0100000000000000000001F4C8F927AED3CA752255", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { /* n - 1 */ + "0100000000000000000001F4C8F927AED3CA752256", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { /* n */ + "0100000000000000000001F4C8F927AED3CA752257", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, +}; + + +Test secp192r1_tests[] = { + { + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { + "000000000000000000000000000000000000000000000001", + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + 0 + }, + { + "000000000000000000000000000000000000000000000002", + "DAFEBF5828783F2AD35534631588A3F629A70FB16982A888DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB", + 1 + }, + { + "000000000000000000000000000000000000000000000003", + "76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD", + 1 + }, + { /* n - 4 */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282D", + "35433907297CC378B0015703374729D7A4FE46647084E4BA5D9B667B0DECA3CFE15C534F88932B0DDAC764CEE24C41CD", + 1 + }, + { /* n - 3 */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282E", + "76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA87D3C81C8D45BADF559D1F012EDE2B600C4ABC99F302FA02", + 1 + }, + { /* n - 2 */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282F", + "DAFEBF5828783F2AD35534631588A3F629A70FB16982A888229425F266C25F05B94D8443EBE4796FA6CCE505A3816C54", + 0 + }, + { /* n - 1 */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", + "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012F8E6D46A003725879CEFEE1294DB32298C06885EE186B7EE", + 0 + }, + { /* n */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, +}; + +Test secp224r1_tests[] = { + { + "00000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { + "00000000000000000000000000000000000000000000000000000001", + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + 0 + }, + { + "00000000000000000000000000000000000000000000000000000002", + "706A46DC76DCB76798E60E6D89474788D16DC18032D268FD1A704FA61C2B76A7BC25E7702A704FA986892849FCA629487ACF3709D2E4E8BB", + 1 + }, + { + "00000000000000000000000000000000000000000000000000000003", + "DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D04A3F7F03CADD0BE444C0AA56830130DDF77D317344E1AF3591981A925", + 1 + }, + { /* n - 4 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A39", + "AE99FEEBB5D26945B54892092A8AEE02912930FA41CD114E40447301FB7DA7F5F13A43B81774373C879CD32D6934C05FA758EEB14FCFAB38", + 1 + }, + { /* n - 3 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3A", + "DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D045C080FC3522F41BBB3F55A97CFECF21F882CE8CBB1E50CA6E67E56DC", + 1 + }, + { /* n - 2 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3B", + "706A46DC76DCB76798E60E6D89474788D16DC18032D268FD1A704FA6E3D4895843DA188FD58FB0567976D7B50359D6B78530C8F62D1B1746", + 0 + }, + { /* n - 1 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3C", + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D2142C89C774A08DC04B3DD201932BC8A5EA5F8B89BBB2A7E667AFF81CD", + 0 + }, + { /* n */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, +}; + +Test secp256r1_tests[] = { + { + "0000000000000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { + "0000000000000000000000000000000000000000000000000000000000000001", + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + 0 + }, + { + "0000000000000000000000000000000000000000000000000000000000000002", + "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC4766997807775510DB8ED040293D9AC69F7430DBBA7DADE63CE982299E04B79D227873D1", + 1 + }, + { + "0000000000000000000000000000000000000000000000000000000000000003", + "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032", + 1 + }, + { /* n - 4 */ + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254D", + "E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B0308521F0EA8A4B39CC339E62011A02579D289B103693D0CF11FFAA3BD3DC0E7B12739", + 1 + }, + { /* n - 3 */ + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254E", + "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C78CB9BF2B6670082C8B4F931E59B5D1327D54FCAC7B047C265864ED85D82AFCD", + 1 + }, + { /* n - 2 */ + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254F", + "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978F888AAEE24712FC0D6C26539608BCF244582521AC3167DD661FB4862DD878C2E", + 0 + }, + { /* n - 1 */ + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550", + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A", + 0 + }, + { /* n */ + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, +}; + +Test secp256k1_tests[] = { + { + "0000000000000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, + { + "0000000000000000000000000000000000000000000000000000000000000001", + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + 0 + }, + { + "0000000000000000000000000000000000000000000000000000000000000002", + "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE51AE168FEA63DC339A3C58419466CEAEEF7F632653266D0E1236431A950CFE52A", + 1 + }, + { + "0000000000000000000000000000000000000000000000000000000000000003", + "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9388F7B0F632DE8140FE337E62A37F3566500A99934C2231B6CB9FD7584B8E672", + 1 + }, + { /* n - 4 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413D", + "E493DBF1C10D80F3581E4904930B1404CC6C13900EE0758474FA94ABE8C4CD13AE1266C15F2BAA48A9BD1DF6715AEBB7269851CC404201BF30168422B88C630D", + 1 + }, + { /* n - 3 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413E", + "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9C77084F09CD217EBF01CC819D5C80CA99AFF5666CB3DDCE4934602897B4715BD", + 1 + }, + { /* n - 2 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413F", + "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE5E51E970159C23CC65C3A7BE6B99315110809CD9ACD992F1EDC9BCE55AF301705", + 0 + }, + { /* n - 1 */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140", + "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798B7C52588D95C3B9AA25B0403F1EEF75702E84BB7597AABE663B82F6F04EF2777", + 0 + }, + { /* n */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + 0 + }, +}; + + +void vli_print(uint8_t *vli, unsigned int size) { + for(unsigned i=0; i +#include + +#ifndef uECC_TEST_NUMBER_OF_ITERATIONS +#define uECC_TEST_NUMBER_OF_ITERATIONS 256 +#endif + +void vli_print(char *str, uint8_t *vli, unsigned int size) { + printf("%s ", str); + for(unsigned i=0; i +#include + +void vli_print(char *str, uint8_t *vli, unsigned int size) { + printf("%s ", str); + for(unsigned i=0; i +#include + +void vli_print(uint8_t *vli, unsigned int size) { + for(unsigned i=0; i +#include + +int main() { + int i, c; + uint8_t private[32] = {0}; + uint8_t public[64] = {0}; + uint8_t hash[32] = {0}; + uint8_t sig[64] = {0}; + + const struct uECC_Curve_t * curves[5]; + int num_curves = 0; +#if uECC_SUPPORTS_secp160r1 + curves[num_curves++] = uECC_secp160r1(); +#endif +#if uECC_SUPPORTS_secp192r1 + curves[num_curves++] = uECC_secp192r1(); +#endif +#if uECC_SUPPORTS_secp224r1 + curves[num_curves++] = uECC_secp224r1(); +#endif +#if uECC_SUPPORTS_secp256r1 + curves[num_curves++] = uECC_secp256r1(); +#endif +#if uECC_SUPPORTS_secp256k1 + curves[num_curves++] = uECC_secp256k1(); +#endif + + printf("Testing 256 signatures\n"); + for (c = 0; c < num_curves; ++c) { + for (i = 0; i < 256; ++i) { + printf("."); + fflush(stdout); + + if (!uECC_make_key(public, private, curves[c])) { + printf("uECC_make_key() failed\n"); + return 1; + } + memcpy(hash, public, sizeof(hash)); + + if (!uECC_sign(private, hash, sizeof(hash), sig, curves[c])) { + printf("uECC_sign() failed\n"); + return 1; + } + + if (!uECC_verify(public, hash, sizeof(hash), sig, curves[c])) { + printf("uECC_verify() failed\n"); + return 1; + } + } + printf("\n"); + } + + return 0; +} diff --git a/core/embed/ble_bootloader/uecc/test/test_ecdsa_deterministic.c.example b/core/embed/ble_bootloader/uecc/test/test_ecdsa_deterministic.c.example new file mode 100644 index 000000000..df9aa101f --- /dev/null +++ b/core/embed/ble_bootloader/uecc/test/test_ecdsa_deterministic.c.example @@ -0,0 +1,93 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" + +#include +#include + +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; + +extern void SHA256_Init(SHA256_CTX *ctx); +extern void SHA256_Update(SHA256_CTX *ctx, const uint8_t *message, size_t message_size); +extern void SHA256_Final(uint8_t digest[SHA256_DIGEST_LENGTH], SHA256_CTX *ctx); + +typedef struct SHA256_HashContext { + uECC_HashContext uECC; + SHA256_CTX ctx; +} SHA256_HashContext; + +static void init_SHA256(const uECC_HashContext *base) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Init(&context->ctx); +} + +static void update_SHA256(const uECC_HashContext *base, + const uint8_t *message, + unsigned message_size) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Update(&context->ctx, message, message_size); +} + +static void finish_SHA256(const uECC_HashContext *base, uint8_t *hash_result) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Final(hash_result, &context->ctx); +} + +int main() { + int i, c; + uint8_t private[32] = {0}; + uint8_t public[64] = {0}; + uint8_t hash[32] = {0}; + uint8_t sig[64] = {0}; + + uint8_t tmp[2 * SHA256_DIGEST_LENGTH + SHA256_BLOCK_LENGTH]; + SHA256_HashContext ctx = {{ + &init_SHA256, + &update_SHA256, + &finish_SHA256, + SHA256_BLOCK_LENGTH, + SHA256_DIGEST_LENGTH, + tmp + }}; + + const struct uECC_Curve_t * curves[5]; + curves[0] = uECC_secp160r1(); + curves[1] = uECC_secp192r1(); + curves[2] = uECC_secp224r1(); + curves[3] = uECC_secp256r1(); + curves[4] = uECC_secp256k1(); + + printf("Testing 256 signatures\n"); + for (c = 0; c < 5; ++c) { + for (i = 0; i < 256; ++i) { + printf("."); + fflush(stdout); + + if (!uECC_make_key(public, private, curves[c])) { + printf("uECC_make_key() failed\n"); + return 1; + } + memcpy(hash, public, sizeof(hash)); + + if (!uECC_sign_deterministic(private, hash, sizeof(hash), &ctx.uECC, sig, curves[c])) { + printf("uECC_sign() failed\n"); + return 1; + } + + if (!uECC_verify(public, hash, sizeof(hash), sig, curves[c])) { + printf("uECC_verify() failed\n"); + return 1; + } + } + printf("\n"); + } + + return 0; +} diff --git a/core/embed/ble_bootloader/uecc/types.h b/core/embed/ble_bootloader/uecc/types.h new file mode 100644 index 000000000..9ee81438f --- /dev/null +++ b/core/embed/ble_bootloader/uecc/types.h @@ -0,0 +1,108 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_TYPES_H_ +#define _UECC_TYPES_H_ + +#ifndef uECC_PLATFORM + #if __AVR__ + #define uECC_PLATFORM uECC_avr + #elif defined(__thumb2__) || defined(_M_ARMT) /* I think MSVC only supports Thumb-2 targets */ + #define uECC_PLATFORM uECC_arm_thumb2 + #elif defined(__thumb__) + #define uECC_PLATFORM uECC_arm_thumb + #elif defined(__arm__) || defined(_M_ARM) + #define uECC_PLATFORM uECC_arm + #elif defined(__aarch64__) + #define uECC_PLATFORM uECC_arm64 + #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__) + #define uECC_PLATFORM uECC_x86 + #elif defined(__amd64__) || defined(_M_X64) + #define uECC_PLATFORM uECC_x86_64 + #else + #define uECC_PLATFORM uECC_arch_other + #endif +#endif + +#ifndef uECC_ARM_USE_UMAAL + #if (uECC_PLATFORM == uECC_arm) && (__ARM_ARCH >= 6) + #define uECC_ARM_USE_UMAAL 1 + #elif (uECC_PLATFORM == uECC_arm_thumb2) && (__ARM_ARCH >= 6) && !__ARM_ARCH_7M__ + #define uECC_ARM_USE_UMAAL 1 + #else + #define uECC_ARM_USE_UMAAL 0 + #endif +#endif + +#ifndef uECC_WORD_SIZE + #if uECC_PLATFORM == uECC_avr + #define uECC_WORD_SIZE 1 + #elif (uECC_PLATFORM == uECC_x86_64 || uECC_PLATFORM == uECC_arm64) + #define uECC_WORD_SIZE 8 + #else + #define uECC_WORD_SIZE 4 + #endif +#endif + +#if (uECC_WORD_SIZE != 1) && (uECC_WORD_SIZE != 4) && (uECC_WORD_SIZE != 8) + #error "Unsupported value for uECC_WORD_SIZE" +#endif + +#if ((uECC_PLATFORM == uECC_avr) && (uECC_WORD_SIZE != 1)) + #pragma message ("uECC_WORD_SIZE must be 1 for AVR") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 1 +#endif + +#if ((uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) && \ + (uECC_WORD_SIZE != 4)) + #pragma message ("uECC_WORD_SIZE must be 4 for ARM") + #undef uECC_WORD_SIZE + #define uECC_WORD_SIZE 4 +#endif + +#if defined(__SIZEOF_INT128__) || ((__clang_major__ * 100 + __clang_minor__) >= 302) + #define SUPPORTS_INT128 1 +#else + #define SUPPORTS_INT128 0 +#endif + +typedef int8_t wordcount_t; +typedef int16_t bitcount_t; +typedef int8_t cmpresult_t; + +#if (uECC_WORD_SIZE == 1) + +typedef uint8_t uECC_word_t; +typedef uint16_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80 +#define uECC_WORD_BITS 8 +#define uECC_WORD_BITS_SHIFT 3 +#define uECC_WORD_BITS_MASK 0x07 + +#elif (uECC_WORD_SIZE == 4) + +typedef uint32_t uECC_word_t; +typedef uint64_t uECC_dword_t; + +#define HIGH_BIT_SET 0x80000000 +#define uECC_WORD_BITS 32 +#define uECC_WORD_BITS_SHIFT 5 +#define uECC_WORD_BITS_MASK 0x01F + +#elif (uECC_WORD_SIZE == 8) + +typedef uint64_t uECC_word_t; +#if SUPPORTS_INT128 +typedef unsigned __int128 uECC_dword_t; +#endif + +#define HIGH_BIT_SET 0x8000000000000000ull +#define uECC_WORD_BITS 64 +#define uECC_WORD_BITS_SHIFT 6 +#define uECC_WORD_BITS_MASK 0x03F + +#endif /* uECC_WORD_SIZE */ + +#endif /* _UECC_TYPES_H_ */ diff --git a/core/embed/ble_bootloader/uecc/uECC.c b/core/embed/ble_bootloader/uecc/uECC.c new file mode 100644 index 000000000..a3d502cf2 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/uECC.c @@ -0,0 +1,1669 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" +#include "uECC_vli.h" + +#ifndef uECC_RNG_MAX_TRIES + #define uECC_RNG_MAX_TRIES 64 +#endif + +#if uECC_ENABLE_VLI_API + #define uECC_VLI_API +#else + #define uECC_VLI_API static +#endif + +#if (uECC_PLATFORM == uECC_avr) || \ + (uECC_PLATFORM == uECC_arm) || \ + (uECC_PLATFORM == uECC_arm_thumb) || \ + (uECC_PLATFORM == uECC_arm_thumb2) + #define CONCATX(a, ...) a ## __VA_ARGS__ + #define CONCAT(a, ...) CONCATX(a, __VA_ARGS__) + + #define STRX(a) #a + #define STR(a) STRX(a) + + #define EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__)))) + #define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__)))) + #define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__)))) + #define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__)))) + #define EVAL4(...) __VA_ARGS__ + + #define DEC_1 0 + #define DEC_2 1 + #define DEC_3 2 + #define DEC_4 3 + #define DEC_5 4 + #define DEC_6 5 + #define DEC_7 6 + #define DEC_8 7 + #define DEC_9 8 + #define DEC_10 9 + #define DEC_11 10 + #define DEC_12 11 + #define DEC_13 12 + #define DEC_14 13 + #define DEC_15 14 + #define DEC_16 15 + #define DEC_17 16 + #define DEC_18 17 + #define DEC_19 18 + #define DEC_20 19 + #define DEC_21 20 + #define DEC_22 21 + #define DEC_23 22 + #define DEC_24 23 + #define DEC_25 24 + #define DEC_26 25 + #define DEC_27 26 + #define DEC_28 27 + #define DEC_29 28 + #define DEC_30 29 + #define DEC_31 30 + #define DEC_32 31 + + #define DEC(N) CONCAT(DEC_, N) + + #define SECOND_ARG(_, val, ...) val + #define SOME_CHECK_0 ~, 0 + #define GET_SECOND_ARG(...) SECOND_ARG(__VA_ARGS__, SOME,) + #define SOME_OR_0(N) GET_SECOND_ARG(CONCAT(SOME_CHECK_, N)) + + #define EMPTY(...) + #define DEFER(...) __VA_ARGS__ EMPTY() + + #define REPEAT_NAME_0() REPEAT_0 + #define REPEAT_NAME_SOME() REPEAT_SOME + #define REPEAT_0(...) + #define REPEAT_SOME(N, stuff) DEFER(CONCAT(REPEAT_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), stuff) stuff + #define REPEAT(N, stuff) EVAL(REPEAT_SOME(N, stuff)) + + #define REPEATM_NAME_0() REPEATM_0 + #define REPEATM_NAME_SOME() REPEATM_SOME + #define REPEATM_0(...) + #define REPEATM_SOME(N, macro) macro(N) \ + DEFER(CONCAT(REPEATM_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), macro) + #define REPEATM(N, macro) EVAL(REPEATM_SOME(N, macro)) +#endif + +#include "platform-specific.inc" + +#if (uECC_WORD_SIZE == 1) + #if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_WORDS 21 /* Due to the size of curve_n. */ + #endif + #if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 24 + #endif + #if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 28 + #endif + #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 32 + #endif +#elif (uECC_WORD_SIZE == 4) + #if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_WORDS 6 /* Due to the size of curve_n. */ + #endif + #if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 6 + #endif + #if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 7 + #endif + #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 8 + #endif +#elif (uECC_WORD_SIZE == 8) + #if uECC_SUPPORTS_secp160r1 + #define uECC_MAX_WORDS 3 + #endif + #if uECC_SUPPORTS_secp192r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 3 + #endif + #if uECC_SUPPORTS_secp224r1 + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 4 + #endif + #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1) + #undef uECC_MAX_WORDS + #define uECC_MAX_WORDS 4 + #endif +#endif /* uECC_WORD_SIZE */ + +#define BITS_TO_WORDS(num_bits) ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8)) +#define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8) + +struct uECC_Curve_t { + wordcount_t num_words; + wordcount_t num_bytes; + bitcount_t num_n_bits; + uECC_word_t p[uECC_MAX_WORDS]; + uECC_word_t n[uECC_MAX_WORDS]; + uECC_word_t G[uECC_MAX_WORDS * 2]; + uECC_word_t b[uECC_MAX_WORDS]; + void (*double_jacobian)(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * Z1, + uECC_Curve curve); +#if uECC_SUPPORT_COMPRESSED_POINT + void (*mod_sqrt)(uECC_word_t *a, uECC_Curve curve); +#endif + void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); +#if (uECC_OPTIMIZATION_LEVEL > 0) + void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product); +#endif +}; + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN +static void bcopy(uint8_t *dst, + const uint8_t *src, + unsigned num_bytes) { + while (0 != num_bytes) { + num_bytes--; + dst[num_bytes] = src[num_bytes]; + } +} +#endif + +static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +#if (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \ + uECC_PLATFORM == uECC_arm_thumb2) + #include "asm_arm.inc" +#endif + +#if (uECC_PLATFORM == uECC_avr) + #include "asm_avr.inc" +#endif + +#if default_RNG_defined +static uECC_RNG_Function g_rng_function = &default_RNG; +#else +static uECC_RNG_Function g_rng_function = 0; +#endif + +void uECC_set_rng(uECC_RNG_Function rng_function) { + g_rng_function = rng_function; +} + +uECC_RNG_Function uECC_get_rng(void) { + return g_rng_function; +} + +int uECC_curve_private_key_size(uECC_Curve curve) { + return BITS_TO_BYTES(curve->num_n_bits); +} + +int uECC_curve_public_key_size(uECC_Curve curve) { + return 2 * curve->num_bytes; +} + +#if !asm_clear +uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) { + wordcount_t i; + for (i = 0; i < num_words; ++i) { + vli[i] = 0; + } +} +#endif /* !asm_clear */ + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_VLI_API uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) { + uECC_word_t bits = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + bits |= vli[i]; + } + return (bits == 0); +} + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_VLI_API uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) { + return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK))); +} + +/* Counts the number of words in vli. */ +static wordcount_t vli_numDigits(const uECC_word_t *vli, const wordcount_t max_words) { + wordcount_t i; + /* Search from the end until we find a non-zero digit. + We do it in reverse because we expect that most digits will be nonzero. */ + for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) { + } + + return (i + 1); +} + +/* Counts the number of bits required to represent vli. */ +uECC_VLI_API bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) { + uECC_word_t i; + uECC_word_t digit; + + wordcount_t num_digits = vli_numDigits(vli, max_words); + if (num_digits == 0) { + return 0; + } + + digit = vli[num_digits - 1]; + for (i = 0; digit; ++i) { + digit >>= 1; + } + + return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i); +} + +/* Sets dest = src. */ +#if !asm_set +uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) { + wordcount_t i; + for (i = 0; i < num_words; ++i) { + dest[i] = src[i]; + } +} +#endif /* !asm_set */ + +/* Returns sign of left - right. */ +static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + wordcount_t i; + for (i = num_words - 1; i >= 0; --i) { + if (left[i] > right[i]) { + return 1; + } else if (left[i] < right[i]) { + return -1; + } + } + return 0; +} + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise. */ +uECC_VLI_API uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t diff = 0; + wordcount_t i; + for (i = num_words - 1; i >= 0; --i) { + diff |= (left[i] ^ right[i]); + } + return (diff == 0); +} + +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Returns sign of left - right, in constant time. */ +uECC_VLI_API cmpresult_t uECC_vli_cmp(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t tmp[uECC_MAX_WORDS]; + uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words); + uECC_word_t equal = uECC_vli_isZero(tmp, num_words); + return (!equal - 2 * neg); +} + +/* Computes vli = vli >> 1. */ +#if !asm_rshift1 +uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) { + uECC_word_t *end = vli; + uECC_word_t carry = 0; + + vli += num_words; + while (vli-- > end) { + uECC_word_t temp = *vli; + *vli = (temp >> 1) | carry; + carry = temp << (uECC_WORD_BITS - 1); + } +} +#endif /* !asm_rshift1 */ + +/* Computes result = left + right, returning carry. Can modify in place. */ +#if !asm_add +uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t carry = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + uECC_word_t sum = left[i] + right[i] + carry; + if (sum != left[i]) { + carry = (sum < left[i]); + } + result[i] = sum; + } + return carry; +} +#endif /* !asm_add */ + +/* Computes result = left - right, returning borrow. Can modify in place. */ +#if !asm_sub +uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words; ++i) { + uECC_word_t diff = left[i] - right[i] - borrow; + if (diff != left[i]) { + borrow = (diff > left[i]); + } + result[i] = diff; + } + return borrow; +} +#endif /* !asm_sub */ + +#if !asm_mult || (uECC_SQUARE_FUNC && !asm_square) || \ + (uECC_SUPPORTS_secp256k1 && (uECC_OPTIMIZATION_LEVEL > 0) && \ + ((uECC_WORD_SIZE == 1) || (uECC_WORD_SIZE == 8))) +static void muladd(uECC_word_t a, + uECC_word_t b, + uECC_word_t *r0, + uECC_word_t *r1, + uECC_word_t *r2) { +#if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128 + uint64_t a0 = a & 0xffffffffull; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xffffffffull; + uint64_t b1 = b >> 32; + + uint64_t i0 = a0 * b0; + uint64_t i1 = a0 * b1; + uint64_t i2 = a1 * b0; + uint64_t i3 = a1 * b1; + + uint64_t p0, p1; + + i2 += (i0 >> 32); + i2 += i1; + if (i2 < i1) { /* overflow */ + i3 += 0x100000000ull; + } + + p0 = (i0 & 0xffffffffull) | (i2 << 32); + p1 = i3 + (i2 >> 32); + + *r0 += p0; + *r1 += (p1 + (*r0 < p0)); + *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0)); +#else + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +#endif +} +#endif /* muladd needed */ + +#if !asm_mult +uECC_VLI_API void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words) { + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + wordcount_t i, k; + + /* Compute each digit of result in sequence, maintaining the carries. */ + for (k = 0; k < num_words; ++k) { + for (i = 0; i <= k; ++i) { + muladd(left[i], right[k - i], &r0, &r1, &r2); + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + for (k = num_words; k < num_words * 2 - 1; ++k) { + for (i = (k + 1) - num_words; i < num_words; ++i) { + muladd(left[i], right[k - i], &r0, &r1, &r2); + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + result[num_words * 2 - 1] = r0; +} +#endif /* !asm_mult */ + +#if uECC_SQUARE_FUNC + +#if !asm_square +static void mul2add(uECC_word_t a, + uECC_word_t b, + uECC_word_t *r0, + uECC_word_t *r1, + uECC_word_t *r2) { +#if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128 + uint64_t a0 = a & 0xffffffffull; + uint64_t a1 = a >> 32; + uint64_t b0 = b & 0xffffffffull; + uint64_t b1 = b >> 32; + + uint64_t i0 = a0 * b0; + uint64_t i1 = a0 * b1; + uint64_t i2 = a1 * b0; + uint64_t i3 = a1 * b1; + + uint64_t p0, p1; + + i2 += (i0 >> 32); + i2 += i1; + if (i2 < i1) + { /* overflow */ + i3 += 0x100000000ull; + } + + p0 = (i0 & 0xffffffffull) | (i2 << 32); + p1 = i3 + (i2 >> 32); + + *r2 += (p1 >> 63); + p1 = (p1 << 1) | (p0 >> 63); + p0 <<= 1; + + *r0 += p0; + *r1 += (p1 + (*r0 < p0)); + *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0)); +#else + uECC_dword_t p = (uECC_dword_t)a * b; + uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0; + *r2 += (p >> (uECC_WORD_BITS * 2 - 1)); + p *= 2; + r01 += p; + *r2 += (r01 < p); + *r1 = r01 >> uECC_WORD_BITS; + *r0 = (uECC_word_t)r01; +#endif +} + +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + uECC_word_t r0 = 0; + uECC_word_t r1 = 0; + uECC_word_t r2 = 0; + + wordcount_t i, k; + + for (k = 0; k < num_words * 2 - 1; ++k) { + uECC_word_t min = (k < num_words ? 0 : (k + 1) - num_words); + for (i = min; i <= k && i <= k - i; ++i) { + if (i < k-i) { + mul2add(left[i], left[k - i], &r0, &r1, &r2); + } else { + muladd(left[i], left[k - i], &r0, &r1, &r2); + } + } + result[k] = r0; + r0 = r1; + r1 = r2; + r2 = 0; + } + + result[num_words * 2 - 1] = r0; +} +#endif /* !asm_square */ + +#else /* uECC_SQUARE_FUNC */ + +#if uECC_ENABLE_VLI_API +uECC_VLI_API void uECC_vli_square(uECC_word_t *result, + const uECC_word_t *left, + wordcount_t num_words) { + uECC_vli_mult(result, left, left, num_words); +} +#endif /* uECC_ENABLE_VLI_API */ + +#endif /* uECC_SQUARE_FUNC */ + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +uECC_VLI_API void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t carry = uECC_vli_add(result, left, right, num_words); + if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) { + /* result > mod (result = mod + remainder), so subtract mod to get remainder. */ + uECC_vli_sub(result, result, mod, num_words); + } +} + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +uECC_VLI_API void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words); + if (l_borrow) { + /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x, + we can get the correct result from result + mod (with overflow). */ + uECC_vli_add(result, result, mod, num_words); + } +} + +/* Computes result = product % mod, where product is 2N words long. */ +/* Currently only designed to work for curve_p or curve_n. */ +uECC_VLI_API void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t mod_multiple[2 * uECC_MAX_WORDS]; + uECC_word_t tmp[2 * uECC_MAX_WORDS]; + uECC_word_t *v[2] = {tmp, product}; + uECC_word_t index; + + /* Shift mod so its highest set bit is at the maximum position. */ + bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - uECC_vli_numBits(mod, num_words); + wordcount_t word_shift = shift / uECC_WORD_BITS; + wordcount_t bit_shift = shift % uECC_WORD_BITS; + uECC_word_t carry = 0; + uECC_vli_clear(mod_multiple, word_shift); + if (bit_shift > 0) { + for(index = 0; index < (uECC_word_t)num_words; ++index) { + mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry; + carry = mod[index] >> (uECC_WORD_BITS - bit_shift); + } + } else { + uECC_vli_set(mod_multiple + word_shift, mod, num_words); + } + + for (index = 1; shift >= 0; --shift) { + uECC_word_t borrow = 0; + wordcount_t i; + for (i = 0; i < num_words * 2; ++i) { + uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow; + if (diff != v[index][i]) { + borrow = (diff > v[index][i]); + } + v[1 - index][i] = diff; + } + index = !(index ^ borrow); /* Swap the index if there was no borrow */ + uECC_vli_rshift1(mod_multiple, num_words); + mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1); + uECC_vli_rshift1(mod_multiple + num_words, num_words); + } + uECC_vli_set(result, v[index], num_words); +} + +/* Computes result = (left * right) % mod. */ +uECC_VLI_API void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, num_words); + uECC_vli_mmod(result, product, mod, num_words); +} + +uECC_VLI_API void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_mult(product, left, right, curve->num_words); +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + +#if uECC_SQUARE_FUNC + +#if uECC_ENABLE_VLI_API +/* Computes result = left^2 % mod. */ +uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_square(product, left, num_words); + uECC_vli_mmod(result, product, mod, num_words); +} +#endif /* uECC_ENABLE_VLI_API */ + +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + uECC_word_t product[2 * uECC_MAX_WORDS]; + uECC_vli_square(product, left, curve->num_words); +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + +#else /* uECC_SQUARE_FUNC */ + +#if uECC_ENABLE_VLI_API +uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_vli_modMult(result, left, left, mod, num_words); +} +#endif /* uECC_ENABLE_VLI_API */ + +uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result, + const uECC_word_t *left, + uECC_Curve curve) { + uECC_vli_modMult_fast(result, left, left, curve); +} + +#endif /* uECC_SQUARE_FUNC */ + +#define EVEN(vli) (!(vli[0] & 1)) +static void vli_modInv_update(uECC_word_t *uv, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t carry = 0; + if (!EVEN(uv)) { + carry = uECC_vli_add(uv, uv, mod, num_words); + } + uECC_vli_rshift1(uv, num_words); + if (carry) { + uv[num_words - 1] |= HIGH_BIT_SET; + } +} + +/* Computes result = (1 / input) % mod. All VLIs are the same size. + See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" */ +uECC_VLI_API void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words) { + uECC_word_t a[uECC_MAX_WORDS], b[uECC_MAX_WORDS], u[uECC_MAX_WORDS], v[uECC_MAX_WORDS]; + cmpresult_t cmpResult; + + if (uECC_vli_isZero(input, num_words)) { + uECC_vli_clear(result, num_words); + return; + } + + uECC_vli_set(a, input, num_words); + uECC_vli_set(b, mod, num_words); + uECC_vli_clear(u, num_words); + u[0] = 1; + uECC_vli_clear(v, num_words); + while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) { + if (EVEN(a)) { + uECC_vli_rshift1(a, num_words); + vli_modInv_update(u, mod, num_words); + } else if (EVEN(b)) { + uECC_vli_rshift1(b, num_words); + vli_modInv_update(v, mod, num_words); + } else if (cmpResult > 0) { + uECC_vli_sub(a, a, b, num_words); + uECC_vli_rshift1(a, num_words); + if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) { + uECC_vli_add(u, u, mod, num_words); + } + uECC_vli_sub(u, u, v, num_words); + vli_modInv_update(u, mod, num_words); + } else { + uECC_vli_sub(b, b, a, num_words); + uECC_vli_rshift1(b, num_words); + if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) { + uECC_vli_add(v, v, mod, num_words); + } + uECC_vli_sub(v, v, u, num_words); + vli_modInv_update(v, mod, num_words); + } + } + uECC_vli_set(result, u, num_words); +} + +/* ------ Point operations ------ */ + +#include "curve-specific.inc" + +/* Returns 1 if 'point' is the point at infinity, 0 otherwise. */ +#define EccPoint_isZero(point, curve) uECC_vli_isZero((point), (curve)->num_words * 2) + +/* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates. +From http://eprint.iacr.org/2011/338.pdf +*/ + +/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */ +static void apply_z(uECC_word_t * X1, + uECC_word_t * Y1, + const uECC_word_t * const Z, + uECC_Curve curve) { + uECC_word_t t1[uECC_MAX_WORDS]; + + uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */ + uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */ + uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */ + uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */ +} + +/* P = (x1, y1) => 2P, (x2, y2) => P' */ +static void XYcZ_initial_double(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * X2, + uECC_word_t * Y2, + const uECC_word_t * const initial_Z, + uECC_Curve curve) { + uECC_word_t z[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + if (initial_Z) { + uECC_vli_set(z, initial_Z, num_words); + } else { + uECC_vli_clear(z, num_words); + z[0] = 1; + } + + uECC_vli_set(X2, X1, num_words); + uECC_vli_set(Y2, Y1, num_words); + + apply_z(X1, Y1, z, curve); + curve->double_jacobian(X1, Y1, z, curve); + apply_z(X2, Y2, z, curve); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3) + or P => P', Q => P + Q +*/ +static void XYcZ_add(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * X2, + uECC_word_t * Y2, + uECC_Curve curve) { + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */ + + uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */ + uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */ + uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */ + uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */ + + uECC_vli_set(X2, t5, num_words); +} + +/* Input P = (x1, y1, Z), Q = (x2, y2, Z) + Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3) + or P => P - Q, Q => P + Q +*/ +static void XYcZ_addC(uECC_word_t * X1, + uECC_word_t * Y1, + uECC_word_t * X2, + uECC_word_t * Y2, + uECC_Curve curve) { + /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */ + uECC_word_t t5[uECC_MAX_WORDS]; + uECC_word_t t6[uECC_MAX_WORDS]; + uECC_word_t t7[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */ + uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */ + uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */ + uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */ + uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */ + + uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */ + uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */ + uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */ + uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */ + uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */ + + uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */ + uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */ + uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */ + + uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */ + uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */ + uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */ + uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */ + uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */ + + uECC_vli_set(X1, t7, num_words); +} + +/* result may overlap point. */ +static void EccPoint_mult(uECC_word_t * result, + const uECC_word_t * point, + const uECC_word_t * scalar, + const uECC_word_t * initial_Z, + bitcount_t num_bits, + uECC_Curve curve) { + /* R0 and R1 */ + uECC_word_t Rx[2][uECC_MAX_WORDS]; + uECC_word_t Ry[2][uECC_MAX_WORDS]; + uECC_word_t z[uECC_MAX_WORDS]; + bitcount_t i; + uECC_word_t nb; + wordcount_t num_words = curve->num_words; + + uECC_vli_set(Rx[1], point, num_words); + uECC_vli_set(Ry[1], point + num_words, num_words); + + XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve); + + for (i = num_bits - 2; i > 0; --i) { + nb = !uECC_vli_testBit(scalar, i); + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + } + + nb = !uECC_vli_testBit(scalar, 0); + XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve); + + /* Find final 1/Z value. */ + uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */ + uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */ + uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */ + uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0)) */ + /* yP / (xP * Yb * (X1 - X0)) */ + uECC_vli_modMult_fast(z, z, point + num_words, curve); + uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */ + /* End 1/Z calculation */ + + XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve); + apply_z(Rx[0], Ry[0], z, curve); + + uECC_vli_set(result, Rx[0], num_words); + uECC_vli_set(result + num_words, Ry[0], num_words); +} + +static uECC_word_t regularize_k(const uECC_word_t * const k, + uECC_word_t *k0, + uECC_word_t *k1, + uECC_Curve curve) { + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) || + (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) && + uECC_vli_testBit(k0, num_n_bits)); + uECC_vli_add(k1, k0, curve->n, num_n_words); + return carry; +} + +/* Generates a random integer in the range 0 < random < top. + Both random and top have num_words words. */ +uECC_VLI_API int uECC_generate_random_int(uECC_word_t *random, + const uECC_word_t *top, + wordcount_t num_words) { + uECC_word_t mask = (uECC_word_t)-1; + uECC_word_t tries; + bitcount_t num_bits = uECC_vli_numBits(top, num_words); + + if (!g_rng_function) { + return 0; + } + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) { + return 0; + } + random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits)); + if (!uECC_vli_isZero(random, num_words) && + uECC_vli_cmp(top, random, num_words) == 1) { + return 1; + } + } + return 0; +} + +static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result, + uECC_word_t *private_key, + uECC_Curve curve) { + uECC_word_t tmp1[uECC_MAX_WORDS]; + uECC_word_t tmp2[uECC_MAX_WORDS]; + uECC_word_t *p2[2] = {tmp1, tmp2}; + uECC_word_t *initial_Z = 0; + uECC_word_t carry; + + /* Regularize the bitcount for the private key so that attackers cannot use a side channel + attack to learn the number of leading zeros. */ + carry = regularize_k(private_key, tmp1, tmp2, curve); + + /* If an RNG function was specified, try to get a random initial Z value to improve + protection against side-channel attacks. */ + if (g_rng_function) { + if (!uECC_generate_random_int(p2[carry], curve->p, curve->num_words)) { + return 0; + } + initial_Z = p2[carry]; + } + EccPoint_mult(result, curve->G, p2[!carry], initial_Z, curve->num_n_bits + 1, curve); + + if (EccPoint_isZero(result, curve)) { + return 0; + } + return 1; +} + +#if uECC_WORD_SIZE == 1 + +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, + int num_bytes, + const uint8_t *native) { + wordcount_t i; + for (i = 0; i < num_bytes; ++i) { + bytes[i] = native[(num_bytes - 1) - i]; + } +} + +uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native, + const uint8_t *bytes, + int num_bytes) { + uECC_vli_nativeToBytes(native, num_bytes, bytes); +} + +#else + +uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes, + int num_bytes, + const uECC_word_t *native) { + int i; + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + bytes[i] = native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)); + } +} + +uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native, + const uint8_t *bytes, + int num_bytes) { + int i; + uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE); + for (i = 0; i < num_bytes; ++i) { + unsigned b = num_bytes - 1 - i; + native[b / uECC_WORD_SIZE] |= + (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE)); + } +} + +#endif /* uECC_WORD_SIZE */ + +int uECC_make_key(uint8_t *public_key, + uint8_t *private_key, + uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_private = (uECC_word_t *)private_key; + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _private[uECC_MAX_WORDS]; + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t tries; + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!uECC_generate_random_int(_private, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (EccPoint_compute_public_key(_public, _private, curve)) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), _private); + uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public); + uECC_vli_nativeToBytes( + public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words); +#endif + return 1; + } + } + return 0; +} + +int uECC_shared_secret(const uint8_t *public_key, + const uint8_t *private_key, + uint8_t *secret, + uECC_Curve curve) { + uECC_word_t _public[uECC_MAX_WORDS * 2]; + uECC_word_t _private[uECC_MAX_WORDS]; + + uECC_word_t tmp[uECC_MAX_WORDS]; + uECC_word_t *p2[2] = {_private, tmp}; + uECC_word_t *initial_Z = 0; + uECC_word_t carry; + wordcount_t num_words = curve->num_words; + wordcount_t num_bytes = curve->num_bytes; + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) _private, private_key, num_bytes); + bcopy((uint8_t *) _public, public_key, num_bytes*2); +#else + uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits)); + uECC_vli_bytesToNative(_public, public_key, num_bytes); + uECC_vli_bytesToNative(_public + num_words, public_key + num_bytes, num_bytes); +#endif + + /* Regularize the bitcount for the private key so that attackers cannot use a side channel + attack to learn the number of leading zeros. */ + carry = regularize_k(_private, _private, tmp, curve); + + /* If an RNG function was specified, try to get a random initial Z value to improve + protection against side-channel attacks. */ + if (g_rng_function) { + if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) { + return 0; + } + initial_Z = p2[carry]; + } + + EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve); +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) secret, (uint8_t *) _public, num_bytes); +#else + uECC_vli_nativeToBytes(secret, num_bytes, _public); +#endif + return !EccPoint_isZero(_public, curve); +} + +#if uECC_SUPPORT_COMPRESSED_POINT +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve) { + wordcount_t i; + for (i = 0; i < curve->num_bytes; ++i) { + compressed[i+1] = public_key[i]; + } +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + compressed[0] = 2 + (public_key[curve->num_bytes] & 0x01); +#else + compressed[0] = 2 + (public_key[curve->num_bytes * 2 - 1] & 0x01); +#endif +} + +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *point = (uECC_word_t *)public_key; +#else + uECC_word_t point[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t *y = point + curve->num_words; +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy(public_key, compressed+1, curve->num_bytes); +#else + uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes); +#endif + curve->x_side(y, point, curve); + curve->mod_sqrt(y, curve); + + if ((y[0] & 0x01) != (compressed[0] & 0x01)) { + uECC_vli_sub(y, curve->p, y, curve->num_words); + } + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(public_key, curve->num_bytes, point); + uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y); +#endif +} +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +uECC_VLI_API int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) { + uECC_word_t tmp1[uECC_MAX_WORDS]; + uECC_word_t tmp2[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + + /* The point at infinity is invalid. */ + if (EccPoint_isZero(point, curve)) { + return 0; + } + + /* x and y must be smaller than p. */ + if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 || + uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) { + return 0; + } + + uECC_vli_modSquare_fast(tmp1, point + num_words, curve); + curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */ + + /* Make sure that y^2 == x^3 + ax + b */ + return (int)(uECC_vli_equal(tmp1, tmp2, num_words)); +} + +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_bytesToNative(_public, public_key, curve->num_bytes); + uECC_vli_bytesToNative( + _public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes); +#endif + return uECC_valid_point(_public, curve); +} + +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) { +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_private = (uECC_word_t *)private_key; + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _private[uECC_MAX_WORDS]; + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits)); +#endif + + /* Make sure the private key is in the range [1, n-1]. */ + if (uECC_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (uECC_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) != 1) { + return 0; + } + + /* Compute public key. */ + if (!EccPoint_compute_public_key(_public, _private, curve)) { + return 0; + } + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public); + uECC_vli_nativeToBytes( + public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words); +#endif + return 1; +} + + +/* -------- ECDSA code -------- */ + +static void bits2int(uECC_word_t *native, + const uint8_t *bits, + unsigned bits_size, + uECC_Curve curve) { + unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits); + unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits); + int shift; + uECC_word_t carry; + uECC_word_t *ptr; + + if (bits_size > num_n_bytes) { + bits_size = num_n_bytes; + } + + uECC_vli_clear(native, num_n_words); +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) native, bits, bits_size); +#else + uECC_vli_bytesToNative(native, bits, bits_size); +#endif + if (bits_size * 8 <= (unsigned)curve->num_n_bits) { + return; + } + shift = bits_size * 8 - curve->num_n_bits; + carry = 0; + ptr = native + num_n_words; + while (ptr-- > native) { + uECC_word_t temp = *ptr; + *ptr = (temp >> shift) | carry; + carry = temp << (uECC_WORD_BITS - shift); + } + + /* Reduce mod curve_n */ + if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) { + uECC_vli_sub(native, native, curve->n, num_n_words); + } +} + +static int uECC_sign_with_k_internal(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uECC_word_t *k, + uint8_t *signature, + uECC_Curve curve) { + + uECC_word_t tmp[uECC_MAX_WORDS]; + uECC_word_t s[uECC_MAX_WORDS]; + uECC_word_t *k2[2] = {tmp, s}; + uECC_word_t *initial_Z = 0; +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *p = (uECC_word_t *)signature; +#else + uECC_word_t p[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t carry; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + + /* Make sure 0 < k < curve_n */ + if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) { + return 0; + } + + carry = regularize_k(k, tmp, s, curve); + /* If an RNG function was specified, try to get a random initial Z value to improve + protection against side-channel attacks. */ + if (g_rng_function) { + if (!uECC_generate_random_int(k2[carry], curve->p, num_words)) { + return 0; + } + initial_Z = k2[carry]; + } + EccPoint_mult(p, curve->G, k2[!carry], initial_Z, num_n_bits + 1, curve); + if (uECC_vli_isZero(p, num_words)) { + return 0; + } + + /* If an RNG function was specified, get a random number + to prevent side channel analysis of k. */ + if (!g_rng_function) { + uECC_vli_clear(tmp, num_n_words); + tmp[0] = 1; + } else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) { + return 0; + } + + /* Prevent side channel analysis of uECC_vli_modInv() to determine + bits of k / the private key by premultiplying by a random number */ + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */ + uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */ + uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */ + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0 + uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */ +#endif + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); +#else + uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */ +#endif + + s[num_n_words - 1] = 0; + uECC_vli_set(s, p, num_words); + uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */ + + bits2int(tmp, message_hash, hash_size, curve); + uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */ + uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */ + if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) { + return 0; + } +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) signature + curve->num_bytes, (uint8_t *) s, curve->num_bytes); +#else + uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s); +#endif + return 1; +} + +/* For testing - sign with an explicitly specified k value */ +int uECC_sign_with_k(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *k, + uint8_t *signature, + uECC_Curve curve) { + uECC_word_t k2[uECC_MAX_WORDS]; + bits2int(k2, k, BITS_TO_BYTES(curve->num_n_bits), curve); + return uECC_sign_with_k_internal(private_key, message_hash, hash_size, k2, signature, curve); +} + +int uECC_sign(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uint8_t *signature, + uECC_Curve curve) { + uECC_word_t k[uECC_MAX_WORDS]; + uECC_word_t tries; + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + if (!uECC_generate_random_int(k, curve->n, BITS_TO_WORDS(curve->num_n_bits))) { + return 0; + } + + if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, k, signature, curve)) { + return 1; + } + } + return 0; +} + +/* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always + the same size as the hash result size. */ +static void HMAC_init(const uECC_HashContext *hash_context, const uint8_t *K) { + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + pad[i] = K[i] ^ 0x36; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x36; + + hash_context->init_hash(hash_context); + hash_context->update_hash(hash_context, pad, hash_context->block_size); +} + +static void HMAC_update(const uECC_HashContext *hash_context, + const uint8_t *message, + unsigned message_size) { + hash_context->update_hash(hash_context, message, message_size); +} + +static void HMAC_finish(const uECC_HashContext *hash_context, + const uint8_t *K, + uint8_t *result) { + uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) + pad[i] = K[i] ^ 0x5c; + for (; i < hash_context->block_size; ++i) + pad[i] = 0x5c; + + hash_context->finish_hash(hash_context, result); + + hash_context->init_hash(hash_context); + hash_context->update_hash(hash_context, pad, hash_context->block_size); + hash_context->update_hash(hash_context, result, hash_context->result_size); + hash_context->finish_hash(hash_context, result); +} + +/* V = HMAC_K(V) */ +static void update_V(const uECC_HashContext *hash_context, uint8_t *K, uint8_t *V) { + HMAC_init(hash_context, K); + HMAC_update(hash_context, V, hash_context->result_size); + HMAC_finish(hash_context, K, V); +} + +/* Deterministic signing, similar to RFC 6979. Differences are: + * We just use H(m) directly rather than bits2octets(H(m)) + (it is not reduced modulo curve_n). + * We generate a value for k (aka T) directly rather than converting endianness. + + Layout of hash_context->tmp: | | (1 byte overlapped 0x00 or 0x01) / */ +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve) { + uint8_t *K = hash_context->tmp; + uint8_t *V = K + hash_context->result_size; + wordcount_t num_bytes = curve->num_bytes; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + bitcount_t num_n_bits = curve->num_n_bits; + uECC_word_t tries; + unsigned i; + for (i = 0; i < hash_context->result_size; ++i) { + V[i] = 0x01; + K[i] = 0; + } + + /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + V[hash_context->result_size] = 0x00; + HMAC_update(hash_context, V, hash_context->result_size + 1); + HMAC_update(hash_context, private_key, num_bytes); + HMAC_update(hash_context, message_hash, hash_size); + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + + /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */ + HMAC_init(hash_context, K); + V[hash_context->result_size] = 0x01; + HMAC_update(hash_context, V, hash_context->result_size + 1); + HMAC_update(hash_context, private_key, num_bytes); + HMAC_update(hash_context, message_hash, hash_size); + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + + for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) { + uECC_word_t T[uECC_MAX_WORDS]; + uint8_t *T_ptr = (uint8_t *)T; + wordcount_t T_bytes = 0; + for (;;) { + update_V(hash_context, K, V); + for (i = 0; i < hash_context->result_size; ++i) { + T_ptr[T_bytes++] = V[i]; + if (T_bytes >= num_n_words * uECC_WORD_SIZE) { + goto filled; + } + } + } + filled: + if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) { + uECC_word_t mask = (uECC_word_t)-1; + T[num_n_words - 1] &= + mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits)); + } + + if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, T, signature, curve)) { + return 1; + } + + /* K = HMAC_K(V || 0x00) */ + HMAC_init(hash_context, K); + V[hash_context->result_size] = 0x00; + HMAC_update(hash_context, V, hash_context->result_size + 1); + HMAC_finish(hash_context, K, K); + + update_V(hash_context, K, V); + } + return 0; +} + +static bitcount_t smax(bitcount_t a, bitcount_t b) { + return (a > b ? a : b); +} + +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve) { + uECC_word_t u1[uECC_MAX_WORDS], u2[uECC_MAX_WORDS]; + uECC_word_t z[uECC_MAX_WORDS]; + uECC_word_t sum[uECC_MAX_WORDS * 2]; + uECC_word_t rx[uECC_MAX_WORDS]; + uECC_word_t ry[uECC_MAX_WORDS]; + uECC_word_t tx[uECC_MAX_WORDS]; + uECC_word_t ty[uECC_MAX_WORDS]; + uECC_word_t tz[uECC_MAX_WORDS]; + const uECC_word_t *points[4]; + const uECC_word_t *point; + bitcount_t num_bits; + bitcount_t i; +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + uECC_word_t *_public = (uECC_word_t *)public_key; +#else + uECC_word_t _public[uECC_MAX_WORDS * 2]; +#endif + uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS]; + wordcount_t num_words = curve->num_words; + wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits); + + rx[num_n_words - 1] = 0; + r[num_n_words - 1] = 0; + s[num_n_words - 1] = 0; + +#if uECC_VLI_NATIVE_LITTLE_ENDIAN + bcopy((uint8_t *) r, signature, curve->num_bytes); + bcopy((uint8_t *) s, signature + curve->num_bytes, curve->num_bytes); +#else + uECC_vli_bytesToNative(_public, public_key, curve->num_bytes); + uECC_vli_bytesToNative( + _public + num_words, public_key + curve->num_bytes, curve->num_bytes); + uECC_vli_bytesToNative(r, signature, curve->num_bytes); + uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes); +#endif + + /* r, s must not be 0. */ + if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) { + return 0; + } + + /* r, s must be < n. */ + if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 || + uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) { + return 0; + } + + /* Calculate u1 and u2. */ + uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */ + u1[num_n_words - 1] = 0; + bits2int(u1, message_hash, hash_size, curve); + uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */ + uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */ + + /* Calculate sum = G + Q. */ + uECC_vli_set(sum, _public, num_words); + uECC_vli_set(sum + num_words, _public + num_words, num_words); + uECC_vli_set(tx, curve->G, num_words); + uECC_vli_set(ty, curve->G + num_words, num_words); + uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */ + XYcZ_add(tx, ty, sum, sum + num_words, curve); + uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */ + apply_z(sum, sum + num_words, z, curve); + + /* Use Shamir's trick to calculate u1*G + u2*Q */ + points[0] = 0; + points[1] = curve->G; + points[2] = _public; + points[3] = sum; + num_bits = smax(uECC_vli_numBits(u1, num_n_words), + uECC_vli_numBits(u2, num_n_words)); + + point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) | + ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)]; + uECC_vli_set(rx, point, num_words); + uECC_vli_set(ry, point + num_words, num_words); + uECC_vli_clear(z, num_words); + z[0] = 1; + + for (i = num_bits - 2; i >= 0; --i) { + uECC_word_t index; + curve->double_jacobian(rx, ry, z, curve); + + index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1); + point = points[index]; + if (point) { + uECC_vli_set(tx, point, num_words); + uECC_vli_set(ty, point + num_words, num_words); + apply_z(tx, ty, z, curve); + uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */ + XYcZ_add(tx, ty, rx, ry, curve); + uECC_vli_modMult_fast(z, z, tz, curve); + } + } + + uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */ + apply_z(rx, ry, z, curve); + + /* v = x1 (mod n) */ + if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) { + uECC_vli_sub(rx, rx, curve->n, num_n_words); + } + + /* Accept only if v == r. */ + return (int)(uECC_vli_equal(rx, r, num_words)); +} + +#if uECC_ENABLE_VLI_API + +unsigned uECC_curve_num_words(uECC_Curve curve) { + return curve->num_words; +} + +unsigned uECC_curve_num_bytes(uECC_Curve curve) { + return curve->num_bytes; +} + +unsigned uECC_curve_num_bits(uECC_Curve curve) { + return curve->num_bytes * 8; +} + +unsigned uECC_curve_num_n_words(uECC_Curve curve) { + return BITS_TO_WORDS(curve->num_n_bits); +} + +unsigned uECC_curve_num_n_bytes(uECC_Curve curve) { + return BITS_TO_BYTES(curve->num_n_bits); +} + +unsigned uECC_curve_num_n_bits(uECC_Curve curve) { + return curve->num_n_bits; +} + +const uECC_word_t *uECC_curve_p(uECC_Curve curve) { + return curve->p; +} + +const uECC_word_t *uECC_curve_n(uECC_Curve curve) { + return curve->n; +} + +const uECC_word_t *uECC_curve_G(uECC_Curve curve) { + return curve->G; +} + +const uECC_word_t *uECC_curve_b(uECC_Curve curve) { + return curve->b; +} + +#if uECC_SUPPORT_COMPRESSED_POINT +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve) { + curve->mod_sqrt(a, curve); +} +#endif + +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve) { +#if (uECC_OPTIMIZATION_LEVEL > 0) + curve->mmod_fast(result, product); +#else + uECC_vli_mmod(result, product, curve->p, curve->num_words); +#endif +} + +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve) { + uECC_word_t tmp1[uECC_MAX_WORDS]; + uECC_word_t tmp2[uECC_MAX_WORDS]; + uECC_word_t *p2[2] = {tmp1, tmp2}; + uECC_word_t carry = regularize_k(scalar, tmp1, tmp2, curve); + + EccPoint_mult(result, point, p2[!carry], 0, curve->num_n_bits + 1, curve); +} + +#endif /* uECC_ENABLE_VLI_API */ diff --git a/core/embed/ble_bootloader/uecc/uECC.h b/core/embed/ble_bootloader/uecc/uECC.h new file mode 100644 index 000000000..dcbdbfa8b --- /dev/null +++ b/core/embed/ble_bootloader/uecc/uECC.h @@ -0,0 +1,367 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_H_ +#define _UECC_H_ + +#include + +/* Platform selection options. +If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. +Possible values for uECC_PLATFORM are defined below: */ +#define uECC_arch_other 0 +#define uECC_x86 1 +#define uECC_x86_64 2 +#define uECC_arm 3 +#define uECC_arm_thumb 4 +#define uECC_arm_thumb2 5 +#define uECC_arm64 6 +#define uECC_avr 7 + +/* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). +If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your +platform. */ + +/* Optimization level; trade speed for code size. + Larger values produce code that is faster but larger. + Currently supported values are 0 - 4; 0 is unusably slow for most applications. + Optimization level 4 currently only has an effect ARM platforms where more than one + curve is enabled. */ +#ifndef uECC_OPTIMIZATION_LEVEL + #define uECC_OPTIMIZATION_LEVEL 2 +#endif + +/* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be +used for (scalar) squaring instead of the generic multiplication function. This can make things +faster somewhat faster, but increases the code size. */ +#ifndef uECC_SQUARE_FUNC + #define uECC_SQUARE_FUNC 0 +#endif + +/* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native +little-endian format for *all* arrays passed in and out of the public API. This includes public +and private keys, shared secrets, signatures and message hashes. +Using this switch reduces the amount of call stack memory used by uECC, since less intermediate +translations are required. +Note that this will *only* work on native little-endian processors and it will treat the uint8_t +arrays passed into the public API as word arrays, therefore requiring the provided byte arrays +to be word aligned on architectures that do not support unaligned accesses. +IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible +with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use +the same endianness. */ +#ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN + #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0 +#endif + +/* Curve support selection. Set to 0 to remove that curve. */ +#ifndef uECC_SUPPORTS_secp160r1 + #define uECC_SUPPORTS_secp160r1 1 +#endif +#ifndef uECC_SUPPORTS_secp192r1 + #define uECC_SUPPORTS_secp192r1 1 +#endif +#ifndef uECC_SUPPORTS_secp224r1 + #define uECC_SUPPORTS_secp224r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256r1 + #define uECC_SUPPORTS_secp256r1 1 +#endif +#ifndef uECC_SUPPORTS_secp256k1 + #define uECC_SUPPORTS_secp256k1 1 +#endif + +/* Specifies whether compressed point format is supported. + Set to 0 to disable point compression/decompression functions. */ +#ifndef uECC_SUPPORT_COMPRESSED_POINT + #define uECC_SUPPORT_COMPRESSED_POINT 1 +#endif + +struct uECC_Curve_t; +typedef const struct uECC_Curve_t * uECC_Curve; + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_SUPPORTS_secp160r1 +uECC_Curve uECC_secp160r1(void); +#endif +#if uECC_SUPPORTS_secp192r1 +uECC_Curve uECC_secp192r1(void); +#endif +#if uECC_SUPPORTS_secp224r1 +uECC_Curve uECC_secp224r1(void); +#endif +#if uECC_SUPPORTS_secp256r1 +uECC_Curve uECC_secp256r1(void); +#endif +#if uECC_SUPPORTS_secp256k1 +uECC_Curve uECC_secp256k1(void); +#endif + +/* uECC_RNG_Function type +The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if +'dest' was filled with random data, or 0 if the random data could not be generated. +The filled-in values should be either truly random, or from a cryptographically-secure PRNG. + +A correctly functioning RNG function must be set (using uECC_set_rng()) before calling +uECC_make_key() or uECC_sign(). + +Setting a correctly functioning RNG function improves the resistance to side-channel attacks +for uECC_shared_secret() and uECC_sign_deterministic(). + +A correct RNG function is set by default when building for Windows, Linux, or OS X. +If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, +you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined +RNG function; you must provide your own. +*/ +typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); + +/* uECC_set_rng() function. +Set the function that will be used to generate random bytes. The RNG function should +return 1 if the random data was generated, or 0 if the random data could not be generated. + +On platforms where there is no predefined RNG function (eg embedded platforms), this must +be called before uECC_make_key() or uECC_sign() are used. + +Inputs: + rng_function - The function that will be used to generate random bytes. +*/ +void uECC_set_rng(uECC_RNG_Function rng_function); + +/* uECC_get_rng() function. + +Returns the function that will be used to generate random bytes. +*/ +uECC_RNG_Function uECC_get_rng(void); + +/* uECC_curve_private_key_size() function. + +Returns the size of a private key for the curve in bytes. +*/ +int uECC_curve_private_key_size(uECC_Curve curve); + +/* uECC_curve_public_key_size() function. + +Returns the size of a public key for the curve in bytes. +*/ +int uECC_curve_public_key_size(uECC_Curve curve); + +/* uECC_make_key() function. +Create a public/private key pair. + +Outputs: + public_key - Will be filled in with the public key. Must be at least 2 * the curve size + (in bytes) long. For example, if the curve is secp256r1, public_key must be 64 + bytes long. + private_key - Will be filled in with the private key. Must be as long as the curve order; this + is typically the same as the curve size, except for secp160r1. For example, if the + curve is secp256r1, private_key must be 32 bytes long. + + For secp160r1, private_key must be 21 bytes long! Note that the first byte will + almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero). + +Returns 1 if the key pair was generated successfully, 0 if an error occurred. +*/ +int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve); + +/* uECC_shared_secret() function. +Compute a shared secret given your secret key and someone else's public key. If the public key +is not from a trusted source and has not been previously verified, you should verify it first +using uECC_valid_public_key(). +Note: It is recommended that you hash the result of uECC_shared_secret() before using it for +symmetric encryption or HMAC. + +Inputs: + public_key - The public key of the remote party. + private_key - Your private key. + +Outputs: + secret - Will be filled in with the shared secret value. Must be the same size as the + curve size; for example, if the curve is secp256r1, secret must be 32 bytes long. + +Returns 1 if the shared secret was generated successfully, 0 if an error occurred. +*/ +int uECC_shared_secret(const uint8_t *public_key, + const uint8_t *private_key, + uint8_t *secret, + uECC_Curve curve); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* uECC_compress() function. +Compress a public key. + +Inputs: + public_key - The public key to compress. + +Outputs: + compressed - Will be filled in with the compressed public key. Must be at least + (curve size + 1) bytes long; for example, if the curve is secp256r1, + compressed must be 33 bytes long. +*/ +void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve); + +/* uECC_decompress() function. +Decompress a compressed public key. + +Inputs: + compressed - The compressed public key. + +Outputs: + public_key - Will be filled in with the decompressed public key. +*/ +void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve); +#endif /* uECC_SUPPORT_COMPRESSED_POINT */ + +/* uECC_valid_public_key() function. +Check to see if a public key is valid. + +Note that you are not required to check for a valid public key before using any other uECC +functions. However, you may wish to avoid spending CPU time computing a shared secret or +verifying a signature using an invalid public key. + +Inputs: + public_key - The public key to check. + +Returns 1 if the public key is valid, 0 if it is invalid. +*/ +int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve); + +/* uECC_compute_public_key() function. +Compute the corresponding public key for a private key. + +Inputs: + private_key - The private key to compute the public key for + +Outputs: + public_key - Will be filled in with the corresponding public key + +Returns 1 if the key was computed successfully, 0 if an error occurred. +*/ +int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve); + +/* uECC_sign() function. +Generate an ECDSA signature for a given hash value. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to +this function along with your private key. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + +Outputs: + signature - Will be filled in with the signature value. Must be at least 2 * curve size long. + For example, if the curve is secp256r1, signature must be 64 bytes long. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_HashContext structure. +This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). +The structure will be used for multiple hash computations; each time a new hash +is computed, init_hash() will be called, followed by one or more calls to +update_hash(), and finally a call to finish_hash() to produce the resulting hash. + +The intention is that you will create a structure that includes uECC_HashContext +followed by any hash-specific data. For example: + +typedef struct SHA256_HashContext { + uECC_HashContext uECC; + SHA256_CTX ctx; +} SHA256_HashContext; + +void init_SHA256(uECC_HashContext *base) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Init(&context->ctx); +} + +void update_SHA256(uECC_HashContext *base, + const uint8_t *message, + unsigned message_size) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Update(&context->ctx, message, message_size); +} + +void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { + SHA256_HashContext *context = (SHA256_HashContext *)base; + SHA256_Final(hash_result, &context->ctx); +} + +... when signing ... +{ + uint8_t tmp[32 + 32 + 64]; + SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; + uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); +} +*/ +typedef struct uECC_HashContext { + void (*init_hash)(const struct uECC_HashContext *context); + void (*update_hash)(const struct uECC_HashContext *context, + const uint8_t *message, + unsigned message_size); + void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result); + unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ + unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ + uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ +} uECC_HashContext; + +/* uECC_sign_deterministic() function. +Generate an ECDSA signature for a given hash value, using a deterministic algorithm +(see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling +this function; however, if the RNG is defined it will improve resistance to side-channel +attacks. + +Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to +this function along with your private key and a hash context. Note that the message_hash +does not need to be computed with the same hash function used by hash_context. + +Inputs: + private_key - Your private key. + message_hash - The hash of the message to sign. + hash_size - The size of message_hash in bytes. + hash_context - A hash context to use. + +Outputs: + signature - Will be filled in with the signature value. + +Returns 1 if the signature generated successfully, 0 if an error occurred. +*/ +int uECC_sign_deterministic(const uint8_t *private_key, + const uint8_t *message_hash, + unsigned hash_size, + const uECC_HashContext *hash_context, + uint8_t *signature, + uECC_Curve curve); + +/* uECC_verify() function. +Verify an ECDSA signature. + +Usage: Compute the hash of the signed data using the same hash as the signer and +pass it to this function along with the signer's public key and the signature values (r and s). + +Inputs: + public_key - The signer's public key. + message_hash - The hash of the signed data. + hash_size - The size of message_hash in bytes. + signature - The signature value. + +Returns 1 if the signature is valid, 0 if it is invalid. +*/ +int uECC_verify(const uint8_t *public_key, + const uint8_t *message_hash, + unsigned hash_size, + const uint8_t *signature, + uECC_Curve curve); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_H_ */ diff --git a/core/embed/ble_bootloader/uecc/uECC_vli.h b/core/embed/ble_bootloader/uecc/uECC_vli.h new file mode 100644 index 000000000..864cc3335 --- /dev/null +++ b/core/embed/ble_bootloader/uecc/uECC_vli.h @@ -0,0 +1,172 @@ +/* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#ifndef _UECC_VLI_H_ +#define _UECC_VLI_H_ + +#include "uECC.h" +#include "types.h" + +/* Functions for raw large-integer manipulation. These are only available + if uECC.c is compiled with uECC_ENABLE_VLI_API defined to 1. */ +#ifndef uECC_ENABLE_VLI_API + #define uECC_ENABLE_VLI_API 0 +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if uECC_ENABLE_VLI_API + +void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words); + +/* Constant-time comparison to zero - secure way to compare long integers */ +/* Returns 1 if vli == 0, 0 otherwise. */ +uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words); + +/* Returns nonzero if bit 'bit' of vli is set. */ +uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit); + +/* Counts the number of bits required to represent vli. */ +bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words); + +/* Sets dest = src. */ +void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns one if left == right, zero otherwise */ +uECC_word_t uECC_vli_equal(const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Constant-time comparison function - secure way to compare long integers */ +/* Returns sign of left - right, in constant time. */ +cmpresult_t uECC_vli_cmp(const uECC_word_t *left, const uECC_word_t *right, wordcount_t num_words); + +/* Computes vli = vli >> 1. */ +void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words); + +/* Computes result = left + right, returning carry. Can modify in place. */ +uECC_word_t uECC_vli_add(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left - right, returning borrow. Can modify in place. */ +uECC_word_t uECC_vli_sub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left * right. Result must be 2 * num_words long. */ +void uECC_vli_mult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + wordcount_t num_words); + +/* Computes result = left^2. Result must be 2 * num_words long. */ +void uECC_vli_square(uECC_word_t *result, const uECC_word_t *left, wordcount_t num_words); + +/* Computes result = (left + right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modAdd(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left - right) % mod. + Assumes that left < mod and right < mod, and that result does not overlap mod. */ +void uECC_vli_modSub(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = product % mod, where product is 2N words long. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_mmod(uECC_word_t *result, + uECC_word_t *product, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Calculates result = product (mod curve->p), where product is up to + 2 * curve->num_words long. */ +void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve); + +/* Computes result = (left * right) % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modMult(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = (left * right) % curve->p. */ +void uECC_vli_modMult_fast(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *right, + uECC_Curve curve); + +/* Computes result = left^2 % mod. + Currently only designed to work for mod == curve->p or curve_n. */ +void uECC_vli_modSquare(uECC_word_t *result, + const uECC_word_t *left, + const uECC_word_t *mod, + wordcount_t num_words); + +/* Computes result = left^2 % curve->p. */ +void uECC_vli_modSquare_fast(uECC_word_t *result, const uECC_word_t *left, uECC_Curve curve); + +/* Computes result = (1 / input) % mod.*/ +void uECC_vli_modInv(uECC_word_t *result, + const uECC_word_t *input, + const uECC_word_t *mod, + wordcount_t num_words); + +#if uECC_SUPPORT_COMPRESSED_POINT +/* Calculates a = sqrt(a) (mod curve->p) */ +void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve); +#endif + +/* Converts an integer in uECC native format to big-endian bytes. */ +void uECC_vli_nativeToBytes(uint8_t *bytes, int num_bytes, const uECC_word_t *native); +/* Converts big-endian bytes to an integer in uECC native format. */ +void uECC_vli_bytesToNative(uECC_word_t *native, const uint8_t *bytes, int num_bytes); + +unsigned uECC_curve_num_words(uECC_Curve curve); +unsigned uECC_curve_num_bytes(uECC_Curve curve); +unsigned uECC_curve_num_bits(uECC_Curve curve); +unsigned uECC_curve_num_n_words(uECC_Curve curve); +unsigned uECC_curve_num_n_bytes(uECC_Curve curve); +unsigned uECC_curve_num_n_bits(uECC_Curve curve); + +const uECC_word_t *uECC_curve_p(uECC_Curve curve); +const uECC_word_t *uECC_curve_n(uECC_Curve curve); +const uECC_word_t *uECC_curve_G(uECC_Curve curve); +const uECC_word_t *uECC_curve_b(uECC_Curve curve); + +int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve); + +/* Multiplies a point by a scalar. Points are represented by the X coordinate followed by + the Y coordinate in the same array, both coordinates are curve->num_words long. Note + that scalar must be curve->num_n_words long (NOT curve->num_words). */ +void uECC_point_mult(uECC_word_t *result, + const uECC_word_t *point, + const uECC_word_t *scalar, + uECC_Curve curve); + +/* Generates a random integer in the range 0 < random < top. + Both random and top have num_words words. */ +int uECC_generate_random_int(uECC_word_t *random, + const uECC_word_t *top, + wordcount_t num_words); + +#endif /* uECC_ENABLE_VLI_API */ + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif /* _UECC_VLI_H_ */ diff --git a/core/embed/ble_bootloader/version.h b/core/embed/ble_bootloader/version.h new file mode 100644 index 000000000..14de53045 --- /dev/null +++ b/core/embed/ble_bootloader/version.h @@ -0,0 +1,4 @@ +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 +#define VERSION_PATCH 0 +#define VERSION_BUILD 0 diff --git a/core/embed/ble_firmware/advertising.c b/core/embed/ble_firmware/advertising.c new file mode 100644 index 000000000..b7665017b --- /dev/null +++ b/core/embed/ble_firmware/advertising.c @@ -0,0 +1,203 @@ +#include "ble_gap.h" + +#include "advertising.h" +#include "ble_advdata.h" +#include "ble_advertising.h" +#include "ble_nus.h" +#include "connection.h" +#include "defs.h" +#include "int_comm.h" +#include "nrf_log.h" +#include "pm.h" +#include "power.h" + +#define APP_ADV_INTERVAL \ + 64 /**< The advertising interval (in units of 0.625 ms. This value \ + corresponds to 40 ms). */ + +#define APP_ADV_DURATION \ + 18000 /**< The advertising duration (180 seconds) in units of 10 \ + milliseconds. */ + +#define NUS_SERVICE_UUID_TYPE \ + BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service \ + (vendor specific). */ + +static ble_uuid_t m_adv_uuids[] = /**< Universally unique service identifier. */ + {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; + +BLE_ADVERTISING_DEF(m_advertising); /**< Advertising module instance. */ + +/**@brief Function for handling advertising events. + * + * @details This function will be called for advertising events which are passed + * to the application. + * + * @param[in] ble_adv_evt Advertising event. + */ +static void on_adv_evt(ble_adv_evt_t ble_adv_evt) { + uint32_t err_code; + + switch (ble_adv_evt) { + case BLE_ADV_EVT_DIRECTED_HIGH_DUTY: + NRF_LOG_INFO("High Duty Directed advertising."); + send_status_event(); + break; + + case BLE_ADV_EVT_DIRECTED: + NRF_LOG_INFO("Directed advertising."); + send_status_event(); + break; + + case BLE_ADV_EVT_FAST: + NRF_LOG_INFO("Fast advertising."); + send_status_event(); + break; + + case BLE_ADV_EVT_SLOW: + NRF_LOG_INFO("Slow advertising."); + send_status_event(); + break; + + case BLE_ADV_EVT_FAST_WHITELIST: + NRF_LOG_INFO("Fast advertising with whitelist."); + send_status_event(); + break; + + case BLE_ADV_EVT_SLOW_WHITELIST: + NRF_LOG_INFO("Slow advertising with whitelist."); + send_status_event(); + break; + + case BLE_ADV_EVT_IDLE: + send_status_event(); + // sleep_mode_enter(); + break; + + case BLE_ADV_EVT_WHITELIST_REQUEST: { + ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + uint32_t addr_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; + uint32_t irk_cnt = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; + + err_code = pm_whitelist_get(whitelist_addrs, &addr_cnt, whitelist_irks, + &irk_cnt); + if (err_code != NRF_ERROR_NOT_FOUND) { + APP_ERROR_CHECK(err_code); + } else { + break; + } + NRF_LOG_DEBUG( + "pm_whitelist_get returns %d addr in whitelist and %d irk whitelist", + addr_cnt, irk_cnt); + + // Set the correct identities list (no excluding peers with no Central + // Address Resolution). + identities_set(PM_PEER_ID_LIST_SKIP_NO_IRK); + + // Apply the whitelist. + err_code = ble_advertising_whitelist_reply( + &m_advertising, whitelist_addrs, addr_cnt, whitelist_irks, irk_cnt); + APP_ERROR_CHECK(err_code); + } break; // BLE_ADV_EVT_WHITELIST_REQUEST + + case BLE_ADV_EVT_PEER_ADDR_REQUEST: { + pm_peer_data_bonding_t peer_bonding_data; + + // Only Give peer address if we have a handle to the bonded peer. + if (get_peer_id() != PM_PEER_ID_INVALID) { + err_code = pm_peer_data_bonding_load(get_peer_id(), &peer_bonding_data); + if (err_code != NRF_ERROR_NOT_FOUND) { + APP_ERROR_CHECK(err_code); + + // Manipulate identities to exclude peers with no Central Address + // Resolution. + identities_set(PM_PEER_ID_LIST_SKIP_ALL); + + ble_gap_addr_t *p_peer_addr = + &(peer_bonding_data.peer_ble_id.id_addr_info); + err_code = + ble_advertising_peer_addr_reply(&m_advertising, p_peer_addr); + APP_ERROR_CHECK(err_code); + } + } + } break; // BLE_ADV_EVT_PEER_ADDR_REQUEST + + default: + break; + } +} + +void advertising_init(void) { + uint32_t err_code; + uint8_t adv_flags; + ble_advertising_init_t init; + + memset(&init, 0, sizeof(init)); + + adv_flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + init.advdata.name_type = BLE_ADVDATA_FULL_NAME; + init.advdata.include_appearance = false; + init.advdata.flags = adv_flags; + init.advdata.uuids_complete.uuid_cnt = 0; + init.advdata.uuids_complete.p_uuids = NULL; + + init.config.ble_adv_whitelist_enabled = true; + init.config.ble_adv_directed_high_duty_enabled = true; + init.config.ble_adv_directed_enabled = false; + init.config.ble_adv_directed_interval = 0; + init.config.ble_adv_directed_timeout = 0; + init.config.ble_adv_fast_enabled = true; + init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; + init.config.ble_adv_fast_timeout = APP_ADV_DURATION; + + init.evt_handler = on_adv_evt; + + init.srdata.uuids_more_available.uuid_cnt = + sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); + init.srdata.uuids_more_available.p_uuids = m_adv_uuids; + + err_code = ble_advertising_init(&m_advertising, &init); + APP_ERROR_CHECK(err_code); + + ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG); +} + +void advertising_start(bool whitelist) { + m_advertising.adv_modes_config.ble_adv_on_disconnect_disabled = false; + + if (m_advertising.adv_mode_current != BLE_ADV_MODE_DIRECTED_HIGH_DUTY) { + if (m_advertising.adv_mode_current != BLE_ADV_MODE_FAST && + get_connection_handle() == BLE_CONN_HANDLE_INVALID) { + whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR); + + ret_code_t ret = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); + APP_ERROR_CHECK(ret); + } + + if (!whitelist) { + ret_code_t ret = + ble_advertising_restart_without_whitelist(&m_advertising); + APP_ERROR_CHECK(ret); + } + } +} + +void advertising_stop(void) { + m_advertising.adv_modes_config.ble_adv_on_disconnect_disabled = true; + ret_code_t ret = ble_advertising_start(&m_advertising, BLE_ADV_MODE_IDLE); + APP_ERROR_CHECK(ret); + // ret =sd_ble_gap_disconnect(get_connection_handle(), + // BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); APP_ERROR_CHECK(ret); +} + +void advertising_restart_without_whitelist(void) { + ret_code_t ret = ble_advertising_restart_without_whitelist(&m_advertising); + APP_ERROR_CHECK(ret); +} + +bool is_advertising(void) { + return m_advertising.adv_mode_current != BLE_ADV_MODE_IDLE; +} + +bool is_advertising_wl(void) { return m_advertising.whitelist_in_use; } diff --git a/core/embed/ble_firmware/advertising.h b/core/embed/ble_firmware/advertising.h new file mode 100644 index 000000000..02c7af44c --- /dev/null +++ b/core/embed/ble_firmware/advertising.h @@ -0,0 +1,18 @@ +#ifndef __ADVERTISING__ +#define __ADVERTISING__ + +#include + +void advertising_init(void); + +void advertising_start(bool whitelist); + +void advertising_stop(void); + +void advertising_restart_without_whitelist(void); + +bool is_advertising(void); + +bool is_advertising_wl(void); + +#endif diff --git a/core/embed/ble_firmware/ble_nus.c b/core/embed/ble_firmware/ble_nus.c new file mode 100644 index 000000000..d2dad7b09 --- /dev/null +++ b/core/embed/ble_firmware/ble_nus.c @@ -0,0 +1,356 @@ +// clang-format off + +/** + * Copyright (c) 2012 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_NUS) +#include "ble.h" +#include "ble_nus.h" +#include "ble_srv_common.h" + +#define NRF_LOG_MODULE_NAME ble_nus +#if BLE_NUS_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL BLE_NUS_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR BLE_NUS_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR BLE_NUS_CONFIG_DEBUG_COLOR +#else // BLE_NUS_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // BLE_NUS_CONFIG_LOG_ENABLED +#include "nrf_log.h" +NRF_LOG_MODULE_REGISTER(); + + +#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */ +#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */ + +#define BLE_NUS_MAX_RX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the RX Characteristic (in bytes). */ +#define BLE_NUS_MAX_TX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the TX Characteristic (in bytes). */ + +#define NUS_BASE_UUID {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor specific UUID. */ + + +/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the SoftDevice. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_connect(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt) +{ + ret_code_t err_code; + ble_nus_evt_t evt; + ble_gatts_value_t gatts_val; + uint8_t cccd_value[2]; + ble_nus_client_context_t * p_client = NULL; + + err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, + p_ble_evt->evt.gap_evt.conn_handle, + (void *) &p_client); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.", + p_ble_evt->evt.gap_evt.conn_handle); + } + + /* Check the hosts CCCD value to inform of readiness to send data using the RX characteristic */ + memset(&gatts_val, 0, sizeof(ble_gatts_value_t)); + gatts_val.p_value = cccd_value; + gatts_val.len = sizeof(cccd_value); + gatts_val.offset = 0; + + err_code = sd_ble_gatts_value_get(p_ble_evt->evt.gap_evt.conn_handle, + p_nus->tx_handles.cccd_handle, + &gatts_val); + + if ((err_code == NRF_SUCCESS) && + (p_nus->data_handler != NULL) && + ble_srv_is_notification_enabled(gatts_val.p_value)) + { + if (p_client != NULL) + { + p_client->is_notification_enabled = true; + } + + memset(&evt, 0, sizeof(ble_nus_evt_t)); + evt.type = BLE_NUS_EVT_COMM_STARTED; + evt.p_nus = p_nus; + evt.conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + evt.p_link_ctx = p_client; + + p_nus->data_handler(&evt); + } +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt) +{ + ret_code_t err_code; + ble_nus_evt_t evt; + ble_nus_client_context_t * p_client; + ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, + p_ble_evt->evt.gatts_evt.conn_handle, + (void *) &p_client); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.", + p_ble_evt->evt.gatts_evt.conn_handle); + } + + memset(&evt, 0, sizeof(ble_nus_evt_t)); + evt.p_nus = p_nus; + evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; + evt.p_link_ctx = p_client; + + if ((p_evt_write->handle == p_nus->tx_handles.cccd_handle) && + (p_evt_write->len == 2)) + { + if (p_client != NULL) + { + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + p_client->is_notification_enabled = true; + evt.type = BLE_NUS_EVT_COMM_STARTED; + } + else + { + p_client->is_notification_enabled = false; + evt.type = BLE_NUS_EVT_COMM_STOPPED; + } + + if (p_nus->data_handler != NULL) + { + p_nus->data_handler(&evt); + } + + } + } + else if ((p_evt_write->handle == p_nus->rx_handles.value_handle) && + (p_nus->data_handler != NULL)) + { + evt.type = BLE_NUS_EVT_RX_DATA; + evt.params.rx_data.p_data = p_evt_write->data; + evt.params.rx_data.length = p_evt_write->len; + + p_nus->data_handler(&evt); + } + else + { + // Do Nothing. This event is not relevant for this service. + } +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event from the SoftDevice. + * + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_hvx_tx_complete(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt) +{ + ret_code_t err_code; + ble_nus_evt_t evt; + ble_nus_client_context_t * p_client; + + err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, + p_ble_evt->evt.gatts_evt.conn_handle, + (void *) &p_client); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.", + p_ble_evt->evt.gatts_evt.conn_handle); + return; + } + + if ((p_client->is_notification_enabled) && (p_nus->data_handler != NULL)) + { + memset(&evt, 0, sizeof(ble_nus_evt_t)); + evt.type = BLE_NUS_EVT_TX_RDY; + evt.p_nus = p_nus; + evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; + evt.p_link_ctx = p_client; + + p_nus->data_handler(&evt); + } +} + + +void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context) +{ + if ((p_context == NULL) || (p_ble_evt == NULL)) + { + return; + } + + ble_nus_t * p_nus = (ble_nus_t *)p_context; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_nus, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_nus, p_ble_evt); + break; + + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + on_hvx_tx_complete(p_nus, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init) +{ + ret_code_t err_code; + ble_uuid_t ble_uuid; + ble_uuid128_t nus_base_uuid = NUS_BASE_UUID; + ble_add_char_params_t add_char_params; + + VERIFY_PARAM_NOT_NULL(p_nus); + VERIFY_PARAM_NOT_NULL(p_nus_init); + + // Initialize the service structure. + p_nus->data_handler = p_nus_init->data_handler; + + /**@snippet [Adding proprietary Service to the SoftDevice] */ + // Add a custom base UUID. + err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type); + VERIFY_SUCCESS(err_code); + + ble_uuid.type = p_nus->uuid_type; + ble_uuid.uuid = BLE_UUID_NUS_SERVICE; + + // Add the service. + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_nus->service_handle); + /**@snippet [Adding proprietary Service to the SoftDevice] */ + VERIFY_SUCCESS(err_code); + + // Add the RX Characteristic. + memset(&add_char_params, 0, sizeof(add_char_params)); + add_char_params.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC; + add_char_params.uuid_type = p_nus->uuid_type; + add_char_params.max_len = BLE_NUS_MAX_RX_CHAR_LEN; + add_char_params.init_len = sizeof(uint8_t); + add_char_params.is_var_len = true; + add_char_params.char_props.write = 1; + add_char_params.char_props.write_wo_resp = 1; + + add_char_params.read_access = SEC_MITM; + add_char_params.write_access = SEC_MITM; + + err_code = characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->rx_handles); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add the TX Characteristic. + /**@snippet [Adding proprietary characteristic to the SoftDevice] */ + memset(&add_char_params, 0, sizeof(add_char_params)); + add_char_params.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC; + add_char_params.uuid_type = p_nus->uuid_type; + add_char_params.max_len = BLE_NUS_MAX_TX_CHAR_LEN; + add_char_params.init_len = sizeof(uint8_t); + add_char_params.is_var_len = true; + add_char_params.char_props.notify = 1; + + add_char_params.read_access = SEC_MITM; + add_char_params.write_access = SEC_MITM; + add_char_params.cccd_write_access = SEC_MITM; + + return characteristic_add(p_nus->service_handle, &add_char_params, &p_nus->tx_handles); + /**@snippet [Adding proprietary characteristic to the SoftDevice] */ +} + + +uint32_t ble_nus_data_send(ble_nus_t * p_nus, + uint8_t * p_data, + uint16_t * p_length, + uint16_t conn_handle) +{ + ret_code_t err_code; + ble_gatts_hvx_params_t hvx_params; + ble_nus_client_context_t * p_client; + + VERIFY_PARAM_NOT_NULL(p_nus); + + err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, conn_handle, (void *) &p_client); + VERIFY_SUCCESS(err_code); + + if ((conn_handle == BLE_CONN_HANDLE_INVALID) || (p_client == NULL)) + { + return NRF_ERROR_NOT_FOUND; + } + + if (!p_client->is_notification_enabled) + { + return NRF_ERROR_INVALID_STATE; + } + + if (*p_length > BLE_NUS_MAX_DATA_LEN) + { + return NRF_ERROR_INVALID_PARAM; + } + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_nus->tx_handles.value_handle; + hvx_params.p_data = p_data; + hvx_params.p_len = p_length; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + + return sd_ble_gatts_hvx(conn_handle, &hvx_params); +} + + +#endif // NRF_MODULE_ENABLED(BLE_NUS) diff --git a/core/embed/ble_firmware/connection.c b/core/embed/ble_firmware/connection.c new file mode 100644 index 000000000..87d20f359 --- /dev/null +++ b/core/embed/ble_firmware/connection.c @@ -0,0 +1,17 @@ + +#include "ble_gap.h" + +#include "connection.h" + +static uint16_t m_conn_handle = + BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ + +void set_connection_handle(uint16_t val) { m_conn_handle = val; } +uint16_t get_connection_handle(void) { return m_conn_handle; } + +void disconnect(void) { + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) { + sd_ble_gap_disconnect(m_conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + } +} diff --git a/core/embed/ble_firmware/connection.h b/core/embed/ble_firmware/connection.h new file mode 100644 index 000000000..7eecbdf50 --- /dev/null +++ b/core/embed/ble_firmware/connection.h @@ -0,0 +1,11 @@ +#ifndef BLE_CONNECTION_H__ +#define BLE_CONNECTION_H__ + +#include + +void set_connection_handle(uint16_t val); +uint16_t get_connection_handle(void); + +void disconnect(void); + +#endif diff --git a/core/embed/ble_firmware/defs.h b/core/embed/ble_firmware/defs.h new file mode 100644 index 000000000..b2e354d3c --- /dev/null +++ b/core/embed/ble_firmware/defs.h @@ -0,0 +1,3 @@ + +#define APP_BLE_CONN_CFG_TAG \ + 1 /**< A tag identifying the SoftDevice BLE configuration. */ diff --git a/core/embed/ble_firmware/dis.c b/core/embed/ble_firmware/dis.c new file mode 100644 index 000000000..0d4a673bb --- /dev/null +++ b/core/embed/ble_firmware/dis.c @@ -0,0 +1,23 @@ +#include "dis.h" +#include +#include "app_error.h" +#include "ble_dis.h" +#include "sdk_errors.h" + +#define MANUFACTURER_NAME \ + "SatoshiLabs" /**< Manufacturer. Will be passed to Device Information \ + Service. */ + +void dis_init(void) { + ret_code_t err_code; + ble_dis_init_t dis_init_obj; + + memset(&dis_init_obj, 0, sizeof(dis_init_obj)); + + ble_srv_ascii_to_utf8(&dis_init_obj.manufact_name_str, MANUFACTURER_NAME); + + dis_init_obj.dis_char_rd_sec = SEC_JUST_WORKS; + + err_code = ble_dis_init(&dis_init_obj); + APP_ERROR_CHECK(err_code); +} diff --git a/core/embed/ble_firmware/dis.h b/core/embed/ble_firmware/dis.h new file mode 100644 index 000000000..ad88ffd9a --- /dev/null +++ b/core/embed/ble_firmware/dis.h @@ -0,0 +1,6 @@ +#ifndef __DIS__ +#define __DIS__ + +void dis_init(void); + +#endif diff --git a/core/embed/ble_firmware/int_comm.c b/core/embed/ble_firmware/int_comm.c new file mode 100644 index 000000000..5aa619b03 --- /dev/null +++ b/core/embed/ble_firmware/int_comm.c @@ -0,0 +1,458 @@ +#include "int_comm.h" +#include "advertising.h" +#include "app_error.h" +#include "app_uart.h" +#include "ble/int_comm_defs.h" +#include "ble_advertising.h" +#include "ble_nus.h" +#include "connection.h" +#include "messages.pb.h" +#include "nrf_drv_spi.h" +#include "nrf_log.h" +#include "pm.h" +#include "protob_helpers.h" +#include "stdint.h" +#include "trezor_t3w1_d1_NRF.h" + +#define SPI_INSTANCE 0 /**< SPI instance index. */ + +static uint8_t m_uart_rx_data[BLE_NUS_MAX_DATA_LEN]; +static uint8_t m_spi_tx_data[BLE_PACKET_SIZE]; +static bool m_uart_rx_data_ready_internal = false; + +BLE_NUS_DEF(m_nus, + NRF_SDH_BLE_TOTAL_LINK_COUNT); /**< BLE NUS service instance. */ + +static const nrf_drv_spi_t spi = + NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */ +static volatile bool spi_xfer_done = true; /**< Flag used to indicate that SPI + instance completed the transfer. */ + +/** + * @brief SPI user event handler. + * @param event + */ +void spi_event_handler(nrf_drv_spi_evt_t const *p_event, void *p_context) { + spi_xfer_done = true; + NRF_LOG_INFO("Transfer completed."); +} + +void spi_init(void) { + nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; + spi_config.ss_pin = SPI_SS_PIN; + spi_config.miso_pin = SPI_MISO_PIN; + spi_config.mosi_pin = SPI_MOSI_PIN; + spi_config.sck_pin = SPI_SCK_PIN; + spi_config.frequency = NRF_DRV_SPI_FREQ_8M; + APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL)); +} + +void nus_init() { + uint32_t err_code; + + ble_nus_init_t nus_init; + + memset(&nus_init, 0, sizeof(nus_init)); + + nus_init.data_handler = nus_data_handler; + + err_code = ble_nus_init(&m_nus, &nus_init); + APP_ERROR_CHECK(err_code); +} + +void send_byte(uint8_t byte) { + uint32_t err_code; + + do { + err_code = app_uart_put(byte); + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) { + NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code); + } + } while (err_code == NRF_ERROR_BUSY); +} + +void send_packet(uint8_t message_type, const uint8_t *tx_data, uint16_t len) { + uint16_t total_len = len + OVERHEAD_SIZE; + send_byte(message_type); + send_byte((total_len >> 8) & 0xFF); + send_byte(total_len & 0xFF); + for (uint32_t i = 0; i < len; i++) { + send_byte(tx_data[i]); + } + send_byte(EOM); +} + +bool write(pb_ostream_t *stream, const pb_byte_t *buf, size_t count) { + write_state *state = (write_state *)(stream->state); + + size_t written = 0; + // while we have data left + while (written < count) { + size_t remaining = count - written; + // if all remaining data fit into our packet + if (state->packet_pos + remaining <= USB_PACKET_SIZE) { + // append data from buf to state->buf + memcpy(state->buf + state->packet_pos, buf + written, remaining); + // advance position + state->packet_pos += remaining; + // and return + return true; + } else { + // append data that fits + memcpy(state->buf + state->packet_pos, buf + written, + USB_PACKET_SIZE - state->packet_pos); + written += USB_PACKET_SIZE - state->packet_pos; + + // send packet + send_packet(state->iface_num, state->buf, USB_PACKET_SIZE); + + // prepare new packet + state->packet_index++; + memset(state->buf, 0, USB_PACKET_SIZE); + state->buf[0] = '?'; + state->packet_pos = MSG_HEADER2_LEN; + } + } + + return true; +}; + +void write_flush(write_state *state) { + // if packet is not filled up completely + if (state->packet_pos < USB_PACKET_SIZE) { + // pad it with zeroes + memset(state->buf + state->packet_pos, 0, + USB_PACKET_SIZE - state->packet_pos); + } + // send packet + send_packet(state->iface_num, state->buf, USB_PACKET_SIZE); +} + +/* we don't use secbool/sectrue/secfalse here as it is a nanopb api */ +static bool read(pb_istream_t *stream, uint8_t *buf, size_t count) { + read_state *state = (read_state *)(stream->state); + + size_t read = 0; + // while we have data left + while (read < count) { + size_t remaining = count - read; + // if all remaining data fit into our packet + if (state->packet_pos + remaining <= state->packet_size) { + // append data from buf to state->buf + memcpy(buf + read, state->buf + state->packet_pos, remaining); + // advance position + state->packet_pos += remaining; + // and return + return true; + } else { + // append data that fits + memcpy(buf + read, state->buf + state->packet_pos, + state->packet_size - state->packet_pos); + read += state->packet_size - state->packet_pos; + // read next packet + + while (!m_uart_rx_data_ready_internal) + ; + m_uart_rx_data_ready_internal = false; + memcpy(state->buf, m_uart_rx_data, USB_PACKET_SIZE); + + // prepare next packet + state->packet_index++; + state->packet_pos = MSG_HEADER2_LEN; + } + } + + return true; +} + +static void read_flush(read_state *state) { (void)state; } + +#define MSG_SEND_NRF(msg) (MSG_SEND(msg, write, write_flush)) + +void process_command(uint8_t *data, uint16_t len) { + uint8_t cmd = data[0]; + switch (cmd) { + case INTERNAL_CMD_SEND_STATE: + send_status_event(); + break; + case INTERNAL_CMD_ADVERTISING_ON: + advertising_start(data[1] != 0); + send_status_event(); + break; + case INTERNAL_CMD_ADVERTISING_OFF: + advertising_stop(); + send_status_event(); + break; + case INTERNAL_CMD_ERASE_BONDS: + delete_bonds(); + send_success_event(); + break; + case INTERNAL_CMD_DISCONNECT: + disconnect(); + send_success_event(); + break; + default: + break; + } +} + +secbool process_auth_key(uint8_t *data, uint32_t len, void *msg) { + recv_protob_msg(INTERNAL_MESSAGE, len, data, AuthKey_fields, msg, read, + read_flush, USB_PACKET_SIZE); + return sectrue; +} + +secbool process_success(uint8_t *data, uint32_t len, void *msg) { + recv_protob_msg(INTERNAL_MESSAGE, len, data, Success_fields, msg, read, + read_flush, USB_PACKET_SIZE); + return sectrue; +} + +void process_unexpected(uint8_t *data, uint32_t len) {} + +secbool await_response(uint16_t expected, + secbool (*process)(uint8_t *data, uint32_t len, + void *msg), + void *msg_recv) { + while (!m_uart_rx_data_ready_internal) + ; + + m_uart_rx_data_ready_internal = false; + + uint16_t id = 0; + uint32_t msg_size = 0; + + msg_parse_header(m_uart_rx_data, &id, &msg_size); + + if (id == expected) { + if (process != NULL) { + return process(m_uart_rx_data, msg_size, msg_recv); + } + return sectrue; + } else { + process_unexpected(m_uart_rx_data, msg_size); + } + return secfalse; +} + +/**@brief Function for handling app_uart events. + * + * @details This function will receive a single character from the app_uart + * module and append it to a string. The string will be be sent over BLE when + * the last character received was a 'new line' '\n' (hex 0x0A) or if the string + * has reached the maximum data length. + */ +/**@snippet [Handling the data received over UART] */ +void uart_event_handle(app_uart_evt_t *p_event) { + static uint8_t index = 0; + static uint8_t message_type = 0; + static uint16_t len = 0; + uint32_t err_code; + uint8_t rx_byte = 0; + + switch (p_event->evt_type) { + case APP_UART_DATA_READY: + while (app_uart_get(&rx_byte) == NRF_SUCCESS) { + if (index == 0) { + if (rx_byte == INTERNAL_MESSAGE || rx_byte == INTERNAL_EVENT || + rx_byte == EXTERNAL_MESSAGE) { + message_type = rx_byte; + index += 1; + continue; + } else { + // unknown message + continue; + } + } + + if (index == 1) { + // len HI + len = rx_byte << 8; + index += 1; + continue; + } + + if (index == 2) { + // len LO + len |= rx_byte; + index += 1; + if (len > sizeof(m_uart_rx_data) + OVERHEAD_SIZE) { + // message too long + index = 0; + continue; + } + continue; + } + + if (index < (len - 1)) { + // command + m_uart_rx_data[index - COMM_HEADER_SIZE] = rx_byte; + index += 1; + continue; + } + + if (index >= (len - 1)) { + if (rx_byte == EOM) { + if (message_type == EXTERNAL_MESSAGE) { + NRF_LOG_DEBUG("Ready to send data over BLE NUS"); + NRF_LOG_HEXDUMP_DEBUG(m_uart_rx_data, index); + + do { + uint16_t length = (uint16_t)len - OVERHEAD_SIZE; + err_code = ble_nus_data_send(&m_nus, m_uart_rx_data, &length, + get_connection_handle()); + if ((err_code != NRF_ERROR_INVALID_STATE) && + (err_code != NRF_ERROR_RESOURCES) && + (err_code != NRF_ERROR_NOT_FOUND)) { + APP_ERROR_CHECK(err_code); + } + } while (err_code == NRF_ERROR_RESOURCES); + } else if (message_type == INTERNAL_MESSAGE) { + m_uart_rx_data_ready_internal = true; + } else if (message_type == INTERNAL_EVENT) { + process_command(m_uart_rx_data, len - OVERHEAD_SIZE); + } + } + index = 0; + } + } + break; + default: + break; + } +} +/**@snippet [Handling the data received over UART] */ + +/**@brief Function for handling the data from the Nordic UART Service. + * + * @details This function will process the data received from the Nordic UART + * BLE Service and forward it to Trezor + * + * @param[in] p_evt Nordic UART Service event. + */ +/**@snippet [Handling the data received over BLE] */ +void nus_data_handler(ble_nus_evt_t *p_evt) { + if (p_evt->type == BLE_NUS_EVT_RX_DATA) { + NRF_LOG_DEBUG("Received data from BLE NUS. Forwarding."); + NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, + p_evt->params.rx_data.length); + + if (p_evt->params.rx_data.length != BLE_PACKET_SIZE) { + return; + } + + while (!spi_xfer_done) + ; + spi_xfer_done = false; + + memcpy(m_spi_tx_data, p_evt->params.rx_data.p_data, BLE_PACKET_SIZE); + + nrf_drv_spi_transfer(&spi, m_spi_tx_data, BLE_PACKET_SIZE, NULL, 0); + } +} +/**@snippet [Handling the data received over BLE] */ + +void send_status_event(void) { + uint8_t tx_data[] = { + INTERNAL_EVENT_STATUS, + (get_connection_handle() != BLE_CONN_HANDLE_INVALID) ? 1 + : 0, // connected + is_advertising() ? 1 : 0, // advertising + is_advertising_wl() ? 1 : 0, // advertising whitelist + pm_peer_count(), // peer count + }; + send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data)); +} + +void send_success_event(void) { + uint8_t tx_data[] = { + INTERNAL_EVENT_SUCCESS, + }; + send_packet(INTERNAL_EVENT, tx_data, sizeof(tx_data)); +} + +uint16_t get_message_type(const uint8_t *rx_data) { + return (rx_data[3] << 8) | rx_data[4]; +} + +static bool read_authkey(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + uint8_t *key_buffer = (uint8_t *)(*arg); + + if (stream->bytes_left > BLE_GAP_PASSKEY_LEN) { + return false; + } + + memset(key_buffer, 0, BLE_GAP_PASSKEY_LEN); + + while (stream->bytes_left) { + // read data + if (!pb_read(stream, (pb_byte_t *)(key_buffer), + (stream->bytes_left > BLE_GAP_PASSKEY_LEN) + ? BLE_GAP_PASSKEY_LEN + : stream->bytes_left)) { + return false; + } + } + + return true; +} + +static bool write_authkey(pb_ostream_t *stream, const pb_field_t *field, + void *const *arg) { + uint8_t *key = (uint8_t *)(*arg); + if (!pb_encode_tag_for_field(stream, field)) return false; + + return pb_encode_string(stream, (uint8_t *)key, BLE_GAP_PASSKEY_LEN); +} + +bool send_comparison_request(uint8_t *p_key, int8_t p_key_len) { + uint8_t iface_num = INTERNAL_MESSAGE; + MSG_SEND_INIT(ComparisonRequest); + MSG_SEND_CALLBACK(key, write_authkey, p_key); + MSG_SEND_NRF(ComparisonRequest); + + MSG_RECV_INIT(Success); + secbool result = await_response(MessageType_MessageType_Success, + process_success, &msg_recv); + + if (result != sectrue) { + return false; + } + + return true; +} + +bool send_auth_key_request(uint8_t *p_key, uint8_t p_key_len) { + uint8_t iface_num = INTERNAL_MESSAGE; + MSG_SEND_INIT(PairingRequest); + MSG_SEND_NRF(PairingRequest); + + uint8_t buffer[BLE_GAP_PASSKEY_LEN]; + MSG_RECV_INIT(AuthKey); + MSG_RECV_CALLBACK(key, read_authkey, buffer); + secbool result = await_response(MessageType_MessageType_AuthKey, + process_auth_key, &msg_recv); + + if (result != sectrue) { + return false; + } + + memcpy(p_key, buffer, + BLE_GAP_PASSKEY_LEN > p_key_len ? p_key_len : BLE_GAP_PASSKEY_LEN); + + return true; +} + +bool send_repair_request(void) { + uint8_t iface_num = INTERNAL_MESSAGE; + MSG_SEND_INIT(RepairRequest); + MSG_SEND_NRF(RepairRequest); + + MSG_RECV_INIT(Success); + + secbool result = await_response(MessageType_MessageType_Success, + process_success, &msg_recv); + + return result == sectrue; +} diff --git a/core/embed/ble_firmware/int_comm.h b/core/embed/ble_firmware/int_comm.h new file mode 100644 index 000000000..cb957c6e9 --- /dev/null +++ b/core/embed/ble_firmware/int_comm.h @@ -0,0 +1,27 @@ +#ifndef __INT_COMM__ +#define __INT_COMM__ + +#include "app_uart.h" +#include "ble_nus.h" +#include "stdint.h" + +void spi_init(void); + +void nus_init(void); + +void nus_data_handler(ble_nus_evt_t *p_evt); + +void uart_event_handle(app_uart_evt_t *p_event); + +void send_status_event(void); +void send_success_event(void); + +bool send_comparison_request(uint8_t *p_key, int8_t p_key_len); + +bool send_auth_key_request(uint8_t *p_key, uint8_t p_key_len); + +bool send_repair_request(void); + +void send_initialized(void); + +#endif diff --git a/core/embed/ble_firmware/jlink.jdebug b/core/embed/ble_firmware/jlink.jdebug new file mode 100644 index 000000000..8e6976c84 --- /dev/null +++ b/core/embed/ble_firmware/jlink.jdebug @@ -0,0 +1,332 @@ +/********************************************************************* +* (c) SEGGER Microcontroller GmbH * +* The Embedded Experts * +* www.segger.com * +********************************************************************** + +File : /home/mbruna/CLionProjects/trezor-model_r/core/embed/ble_firmware/jlink.jdebug +Created : 6 Feb 2023 15:54 +Ozone Version : V3.28c +*/ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // + // Dialog-generated settings + // + Project.AddPathSubstitute (".", "$(ProjectDir)"); + Project.AddPathSubstitute (".", "$(ProjectDir)"); + Project.SetDevice ("Cortex-M4"); + Project.SetHostIF ("USB", ""); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("20 MHz"); + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); + // + // User settings + // + File.Open ("../../build/ble_firmware/ble_firmware.elf"); +} + +/********************************************************************* +* +* OnStartupComplete +* +* Function description +* Called when program execution has reached/passed +* the startup completion point. Optional. +* +********************************************************************** +*/ +//void OnStartupComplete (void) { +//} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging an application in RAM on a Cortex-M target device. +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// VectorTableAddr = Elf.GetBaseAddr(); +// // +// // Set up initial stack pointer +// // +// if (VectorTableAddr != 0xFFFFFFFF) { +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// } +// // +// // Set up entry point PC +// // +// PC = Elf.GetEntryPointPC(); +// +// if (PC != 0xFFFFFFFF) { +// Target.SetReg("PC", PC); +// } else if (VectorTableAddr != 0xFFFFFFFF) { +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } else { +// Util.Error("Project file error: failed to set entry point PC", 1); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +** +********************************************************************** +*/ +void AfterTargetReset (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +void BeforeTargetConnect (void) { + Project.SetJLinkScript("./MMDScript.JLinkScript"); +} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. Optional. +* The default implementation initializes SP and PC to reset values. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + _SetupTarget(); +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} + +/********************************************************************* +* +* BeforeTargetResume +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetResume (void) { +//} + +/********************************************************************* +* +* OnSnapshotLoad +* +* Function description +* Called upon loading a snapshot. Optional. +* +* Additional information +* This function is used to restore the target state in cases +* where values cannot simply be written to the target. +* Typical use: GPIO clock needs to be enabled, before +* GPIO is configured. +* +********************************************************************** +*/ +//void OnSnapshotLoad (void) { +//} + +/********************************************************************* +* +* OnSnapshotSave +* +* Function description +* Called upon saving a snapshot. Optional. +* +* Additional information +* This function is usually used to save values of the target +* state which can either not be trivially read, +* or need to be restored in a specific way or order. +* Typically use: Memory Mapped Registers, +* such as PLL and GPIO configuration. +* +********************************************************************** +*/ +//void OnSnapshotSave (void) { +//} + +/********************************************************************* +* +* OnError +* +* Function description +* Called when an error ocurred. Optional. +* +********************************************************************** +*/ +//void OnError (void) { +//} + +/********************************************************************* +* +* AfterProjectLoad +* +* Function description +* After Project load routine. Optional. +* +********************************************************************** +*/ +//void AfterProjectLoad (void) { +//} + +/********************************************************************* +* +* _SetupTarget +* +* Function description +* Setup the target. +* Called by AfterTargetReset() and AfterTargetDownload(). +* +* Auto-generated function. May be overridden by Ozone. +* +********************************************************************** +*/ +void _SetupTarget(void) { + // + // this function is intentionally empty because both inital PC and + // initial SP were chosen not to be set + // +} diff --git a/core/embed/ble_firmware/main.c b/core/embed/ble_firmware/main.c new file mode 100644 index 000000000..af560a5ef --- /dev/null +++ b/core/embed/ble_firmware/main.c @@ -0,0 +1,631 @@ +/** + * Copyright (c) 2014 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be + * reverse engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ +/** @file + * + * @defgroup ble_sdk_uart_over_ble_main main.c + * @{ + * @ingroup ble_sdk_app_nus_eval + * @brief UART over BLE application main file. + * + * This file contains the source code for a sample application that uses the + * Nordic UART service. This application uses the @ref srvlib_conn_params + * module. + */ + +#include +#include +#include "app_scheduler.h" +#include "app_timer.h" +#include "app_uart.h" +#include "app_util_platform.h" +#include "ble_conn_params.h" +#include "ble_hci.h" +#include "nordic_common.h" +#include "nrf.h" +#include "nrf_ble_gatt.h" +#include "nrf_ble_qwr.h" +#include "nrf_drv_uart.h" +#include "nrf_gpio.h" +#include "nrf_pwr_mgmt.h" +#include "nrf_sdh.h" +#include "nrf_sdh_ble.h" +#include "nrf_sdh_soc.h" +#include "trezor_t3w1_d1_NRF.h" + +#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#endif + +#if defined(UART_PRESENT) +#include "nrf_uart.h" +#endif +#if defined(UARTE_PRESENT) +#include "nrf_uarte.h" +#endif + +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#include "nrf_log_default_backends.h" + +#include "advertising.h" +#include "ble_nus.h" +#include "connection.h" +#include "defs.h" +#include "dis.h" +#include "int_comm.h" +#include "nrf_ble_lesc.h" +#include "pm.h" +#include "power.h" + +#define DEVICE_NAME \ + "Trezor" /**< Name of device. Will be included in the advertising data. \ + */ + +#define APP_BLE_OBSERVER_PRIO \ + 3 /**< Application's BLE observer priority. You shouldn't need to modify \ + this value. */ + +#define MIN_CONN_INTERVAL \ + MSEC_TO_UNITS( \ + 7.5, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), \ + Connection interval uses 1.25 ms units. */ +#define MAX_CONN_INTERVAL \ + MSEC_TO_UNITS( \ + 7.5, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), \ + Connection interval uses 1.25 ms units. */ +#define SLAVE_LATENCY 0 /**< Slave latency. */ +#define CONN_SUP_TIMEOUT \ + MSEC_TO_UNITS(4000, \ + UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), \ + Supervision Timeout uses 10 ms units. */ +#define FIRST_CONN_PARAMS_UPDATE_DELAY \ + APP_TIMER_TICKS( \ + 5000) /**< Time from initiating event (connect or start of notification) \ + to first time sd_ble_gap_conn_param_update is called (5 \ + seconds). */ +#define NEXT_CONN_PARAMS_UPDATE_DELAY \ + APP_TIMER_TICKS( \ + 30000) /**< Time between each call to sd_ble_gap_conn_param_update after \ + the first call (30 seconds). */ +#define MAX_CONN_PARAMS_UPDATE_COUNT \ + 3 /**< Number of attempts before giving up the connection parameter \ + negotiation. */ + +#define DEAD_BEEF \ + 0xDEADBEEF /**< Value used as error code on stack dump, can be used to \ + identify stack location on stack unwind. */ + +#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ +#define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */ + +NRF_BLE_GATT_DEF(m_gatt); /**< GATT module instance. */ +NRF_BLE_QWR_DEF(m_qwr); /**< Context for the Queued Write module.*/ + +#define SCHED_MAX_EVENT_DATA_SIZE \ + APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */ +#ifdef SVCALL_AS_NORMAL_FUNCTION +#define SCHED_QUEUE_SIZE \ + 20 /**< Maximum number of events in the scheduler queue. More is needed in \ + case of Serialization. */ +#else +#define SCHED_QUEUE_SIZE \ + 10 /**< Maximum number of events in the scheduler queue. */ +#endif + +static uint16_t m_ble_nus_max_data_len = + BLE_GATT_ATT_MTU_DEFAULT - + 3; /**< Maximum length of data (in bytes) that can be transmitted to the + peer by the Nordic UART service module. */ + +/**@brief Function for assert macro callback. + * + * @details This function will be called in case of an assert in the SoftDevice. + * + * @warning On assert from the SoftDevice, the system can only recover on reset. + * + * @param[in] line_num Line number of the failing ASSERT call. + * @param[in] p_file_name File name of the failing ASSERT call. + */ +void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) { + app_error_handler(DEAD_BEEF, line_num, p_file_name); +} + +/*lint -save -e14 */ +/** + * Function is implemented as weak so that it can be overwritten by custom + * application error handler when needed. + */ +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) { + __disable_irq(); + + // signalize firmware not running + nrf_gpio_pin_clear(GPIO_2_PIN); + + NRF_LOG_FINAL_FLUSH(); + +#ifndef DEBUG + NRF_LOG_ERROR("Fatal error"); +#else + switch (id) { +#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT + case NRF_FAULT_ID_SD_ASSERT: + NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED"); + break; + case NRF_FAULT_ID_APP_MEMACC: + NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS"); + break; +#endif + case NRF_FAULT_ID_SDK_ASSERT: { + assert_info_t *p_info = (assert_info_t *)info; + NRF_LOG_ERROR("ASSERTION FAILED at %s:%u", p_info->p_file_name, + p_info->line_num); + break; + } + case NRF_FAULT_ID_SDK_ERROR: { + error_info_t *p_info = (error_info_t *)info; + NRF_LOG_ERROR("ERROR %u [%s] at %s:%u\r\nPC at: 0x%08x", p_info->err_code, + nrf_strerror_get(p_info->err_code), p_info->p_file_name, + p_info->line_num, pc); + NRF_LOG_ERROR("End of error report"); + break; + } + default: + NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc); + break; + } +#endif + + NRF_BREAKPOINT_COND; + // On assert, the system can only recover with a reset. + +#ifndef DEBUG + NRF_LOG_WARNING("System reset"); + NVIC_SystemReset(); +#else + app_error_save_and_stop(id, pc, info); +#endif // DEBUG +} + +/**@brief Function for initializing the timer module. + */ +static void timers_init(void) { + ret_code_t err_code = app_timer_init(); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for the GAP initialization. + * + * @details This function will set up all the necessary GAP (Generic Access + * Profile) parameters of the device. It also sets the permissions and + * appearance. + */ +static void gap_params_init(void) { + uint32_t err_code; + ble_gap_conn_params_t gap_conn_params; + ble_gap_conn_sec_mode_t sec_mode; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, + strlen(DEVICE_NAME)); + APP_ERROR_CHECK(err_code); + + err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); + APP_ERROR_CHECK(err_code); + + memset(&gap_conn_params, 0, sizeof(gap_conn_params)); + + gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; + gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; + gap_conn_params.slave_latency = SLAVE_LATENCY; + gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; + + err_code = sd_ble_gap_ppcp_set(&gap_conn_params); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for handling Queued Write Module errors. + * + * @details A pointer to this function will be passed to each service which may + * need to inform the application about an error. + * + * @param[in] nrf_error Error code containing information about what went + * wrong. + */ +static void nrf_qwr_error_handler(uint32_t nrf_error) { + APP_ERROR_HANDLER(nrf_error); +} + +/**@brief Function for initializing services that will be used by the + * application. + */ +static void services_init(void) { + uint32_t err_code; + nrf_ble_qwr_init_t qwr_init = {0}; + + // Initialize Queued Write Module. + qwr_init.error_handler = nrf_qwr_error_handler; + + err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init); + APP_ERROR_CHECK(err_code); + + dis_init(); + nus_init(); +} + +/**@brief Function for handling errors from the Connection Parameters module. + * + * @param[in] nrf_error Error code containing information about what went + * wrong. + */ +static void conn_params_error_handler(uint32_t nrf_error) { + APP_ERROR_HANDLER(nrf_error); +} + +/**@brief Function for initializing the Connection Parameters module. + */ +static void conn_params_init(void) { + uint32_t err_code; + ble_conn_params_init_t cp_init; + + memset(&cp_init, 0, sizeof(cp_init)); + + cp_init.p_conn_params = NULL; + cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; + cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; + cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; + cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; + cp_init.disconnect_on_fail = false; + cp_init.evt_handler = NULL; + cp_init.error_handler = conn_params_error_handler; + + err_code = ble_conn_params_init(&cp_init); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for handling BLE events. + * + * @param[in] p_ble_evt Bluetooth stack event. + * @param[in] p_context Unused. + */ +static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) { + uint32_t err_code; + char passkey[BLE_GAP_PASSKEY_LEN + 1] = {0}; + + switch (p_ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: + NRF_LOG_INFO("Connected"); + // err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); + // APP_ERROR_CHECK(err_code); + + uint16_t handle = p_ble_evt->evt.gap_evt.conn_handle; + set_connection_handle(handle); + send_status_event(); + err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, handle); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GAP_EVT_DISCONNECTED: + NRF_LOG_INFO("Disconnected"); + // bsp_indication_set(BSP_INDICATE_IDLE); + set_connection_handle(BLE_CONN_HANDLE_INVALID); + send_status_event(); + break; + + case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { + NRF_LOG_DEBUG("PHY update request."); + ble_gap_phys_t const phys = { + .rx_phys = BLE_GAP_PHY_AUTO, + .tx_phys = BLE_GAP_PHY_AUTO, + }; + err_code = + sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys); + APP_ERROR_CHECK(err_code); + } break; + + case BLE_GAP_EVT_PASSKEY_DISPLAY: + memcpy(passkey, p_ble_evt->evt.gap_evt.params.passkey_display.passkey, + BLE_GAP_PASSKEY_LEN); + + NRF_LOG_INFO("BLE_GAP_EVT_PASSKEY_DISPLAY: passkey=%s match_req=%d", + nrf_log_push(passkey), + p_ble_evt->evt.gap_evt.params.passkey_display.match_request); + + if (p_ble_evt->evt.gap_evt.params.passkey_display.match_request) { + bool ok = + send_comparison_request((uint8_t *)passkey, BLE_GAP_PASSKEY_LEN); + + if (ok) { + sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_AUTH_KEY_TYPE_PASSKEY, NULL); + } else { + sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_AUTH_KEY_TYPE_NONE, NULL); + } + } + break; + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + NRF_LOG_INFO("BLE_GAP_EVT_LESC_DHKEY_REQUEST"); + break; + + case BLE_GAP_EVT_AUTH_KEY_REQUEST: { + NRF_LOG_INFO("Key requested."); + + bool ok = send_auth_key_request((uint8_t *)passkey, BLE_GAP_PASSKEY_LEN); + + sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle, + BLE_GAP_AUTH_KEY_TYPE_PASSKEY, + (uint8_t *)passkey); + + if (ok) { + NRF_LOG_INFO("Received data: %c", passkey); + } else { + NRF_LOG_INFO("Auth key request failed."); + } + + // APP_ERROR_CHECK(err_code); + break; + } + case BLE_GATTC_EVT_TIMEOUT: + // Disconnect on GATT Client timeout event. + err_code = + sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GATTS_EVT_TIMEOUT: + // Disconnect on GATT Server timeout event. + err_code = + sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + break; + + default: + // No implementation needed. + break; + } +} + +/**@brief Function for the SoftDevice initialization. + * + * @details This function initializes the SoftDevice and the BLE event + * interrupt. + */ +static void ble_stack_init(void) { + ret_code_t err_code; + + err_code = nrf_sdh_enable_request(); + APP_ERROR_CHECK(err_code); + + // Configure the BLE stack using the default settings. + // Fetch the start address of the application RAM. + uint32_t ram_start = 0; + err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start); + APP_ERROR_CHECK(err_code); + + // Enable BLE stack. + err_code = nrf_sdh_ble_enable(&ram_start); + APP_ERROR_CHECK(err_code); + + // Register a handler for BLE events. + NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, + NULL); +} + +/**@brief Function for handling events from the GATT library. */ +void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt) { + if ((get_connection_handle() == p_evt->conn_handle) && + (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)) { + m_ble_nus_max_data_len = + p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; + NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, + m_ble_nus_max_data_len); + } + NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x", + p_gatt->att_mtu_desired_central, + p_gatt->att_mtu_desired_periph); +} + +/**@brief Function for initializing the GATT library. */ +void gatt_init(void) { + ret_code_t err_code; + + err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler); + APP_ERROR_CHECK(err_code); + + err_code = + nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); + APP_ERROR_CHECK(err_code); +} + +///**@brief Function for handling events from the BSP module. +// * +// * @param[in] event Event generated by button press. +// */ +// void bsp_event_handler(bsp_event_t event) { +// uint32_t err_code; +// switch (event) { +// case BSP_EVENT_SLEEP: +// sleep_mode_enter(); +// break; +// +// case BSP_EVENT_DISCONNECT: +// err_code = sd_ble_gap_disconnect( +// get_connection_handle(), BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); +// if (err_code != NRF_ERROR_INVALID_STATE) { +// APP_ERROR_CHECK(err_code); +// } +// break; +// +// case BSP_EVENT_WHITELIST_OFF: +// if (get_connection_handle() == BLE_CONN_HANDLE_INVALID) { +// advertising_restart_without_whitelist(); +// } +// break; +// +// default: +// break; +// } +//} + +/**@brief Function for initializing the UART module. + */ +/**@snippet [UART Initialization] */ +static void uart_init(void) { + uint32_t err_code; + app_uart_comm_params_t const comm_params = { + .rx_pin_no = RX_PIN_NUMBER, + .tx_pin_no = TX_PIN_NUMBER, + .rts_pin_no = RTS_PIN_NUMBER, + .cts_pin_no = CTS_PIN_NUMBER, + .flow_control = APP_UART_FLOW_CONTROL_ENABLED, + .use_parity = false, +#if defined(UART_PRESENT) + .baud_rate = NRF_UART_BAUDRATE_1000000 +#else + .baud_rate = NRF_UARTE_BAUDRATE_1000000 +#endif + }; + + APP_UART_FIFO_INIT(&comm_params, UART_RX_BUF_SIZE, UART_TX_BUF_SIZE, + uart_event_handle, APP_IRQ_PRIORITY_LOWEST, err_code); + APP_ERROR_CHECK(err_code); +} +/**@snippet [UART Initialization] */ + +///**@brief Function for initializing buttons and leds. +// * +// * @param[out] p_erase_bonds Will be true if the clear bonding button was +// * pressed to wake the application up. +// */ +// static void buttons_leds_init(bool *p_erase_bonds) { +// bsp_event_t startup_event; +// +// uint32_t err_code = +// bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler); +// APP_ERROR_CHECK(err_code); +// +// err_code = bsp_btn_ble_init(NULL, &startup_event); +// APP_ERROR_CHECK(err_code); +// +// *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA); +//} + +/**@brief Function for initializing the nrf log module. + */ +static void log_init(void) { + ret_code_t err_code = NRF_LOG_INIT(NULL); + APP_ERROR_CHECK(err_code); + + NRF_LOG_DEFAULT_BACKENDS_INIT(); +} + +/**@brief Function for initializing power management. + */ +static void power_management_init(void) { + ret_code_t err_code; + err_code = nrf_pwr_mgmt_init(); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for handling the idle state (main loop). + * + * @details If there is no pending log operation, then sleep until next the next + * event occurs. + */ +static void idle_state_handle(void) { + app_sched_execute(); + if (NRF_LOG_PROCESS() == false) { + nrf_pwr_mgmt_run(); + } +} + +/**@brief Function for the Event Scheduler initialization. + */ +static void scheduler_init(void) { + APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); +} + +/**@brief Application main function. + */ +int main(void) { + bool erase_bonds = false; + + nrf_gpio_cfg_output(GPIO_1_PIN); + nrf_gpio_cfg_output(GPIO_2_PIN); + nrf_gpio_pin_clear(GPIO_1_PIN); + + // Initialize. + spi_init(); + uart_init(); + log_init(); + timers_init(); + // buttons_leds_init(&erase_bonds); + power_management_init(); + ble_stack_init(); + scheduler_init(); + gap_params_init(); + gatt_init(); + services_init(); + advertising_init(); + conn_params_init(); + peer_manager_init(); + + // signalize firmware running + nrf_gpio_pin_set(GPIO_2_PIN); + send_status_event(); + + if (erase_bonds) { + delete_bonds(); + } + + // Enter main loop. + for (;;) { + nrf_ble_lesc_request_handler(); + idle_state_handle(); + } +} + +/** + * @} + */ diff --git a/core/embed/ble_firmware/memory.ld b/core/embed/ble_firmware/memory.ld new file mode 100644 index 000000000..6a607e0d9 --- /dev/null +++ b/core/embed/ble_firmware/memory.ld @@ -0,0 +1,130 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x27000, LENGTH = 0x49000 + RAM (rwx) : ORIGIN = 0x20002ae8, LENGTH = 0x1d518 +} + +SECTIONS +{ +} + +SECTIONS +{ + . = ALIGN(4); + .mem_section_dummy_ram : + { + } + .cli_sorted_cmd_ptrs : + { + PROVIDE(__start_cli_sorted_cmd_ptrs = .); + KEEP(*(.cli_sorted_cmd_ptrs)) + PROVIDE(__stop_cli_sorted_cmd_ptrs = .); + } > RAM + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .log_dynamic_data : + { + PROVIDE(__start_log_dynamic_data = .); + KEEP(*(SORT(.log_dynamic_data*))) + PROVIDE(__stop_log_dynamic_data = .); + } > RAM + .log_filter_data : + { + PROVIDE(__start_log_filter_data = .); + KEEP(*(SORT(.log_filter_data*))) + PROVIDE(__stop_log_filter_data = .); + } > RAM + +} INSERT AFTER .data; + +SECTIONS +{ + .mem_section_dummy_rom : + { + } + .sdh_soc_observers : + { + PROVIDE(__start_sdh_soc_observers = .); + KEEP(*(SORT(.sdh_soc_observers*))) + PROVIDE(__stop_sdh_soc_observers = .); + } > FLASH + .sdh_ble_observers : + { + PROVIDE(__start_sdh_ble_observers = .); + KEEP(*(SORT(.sdh_ble_observers*))) + PROVIDE(__stop_sdh_ble_observers = .); + } > FLASH + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(SORT(.pwr_mgmt_data*))) + PROVIDE(__stop_pwr_mgmt_data = .); + } > FLASH + .sdh_req_observers : + { + PROVIDE(__start_sdh_req_observers = .); + KEEP(*(SORT(.sdh_req_observers*))) + PROVIDE(__stop_sdh_req_observers = .); + } > FLASH + .sdh_state_observers : + { + PROVIDE(__start_sdh_state_observers = .); + KEEP(*(SORT(.sdh_state_observers*))) + PROVIDE(__stop_sdh_state_observers = .); + } > FLASH + .sdh_stack_observers : + { + PROVIDE(__start_sdh_stack_observers = .); + KEEP(*(SORT(.sdh_stack_observers*))) + PROVIDE(__stop_sdh_stack_observers = .); + } > FLASH + .nrf_queue : + { + PROVIDE(__start_nrf_queue = .); + KEEP(*(.nrf_queue)) + PROVIDE(__stop_nrf_queue = .); + } > FLASH + .nrf_balloc : + { + PROVIDE(__start_nrf_balloc = .); + KEEP(*(.nrf_balloc)) + PROVIDE(__stop_nrf_balloc = .); + } > FLASH + .cli_command : + { + PROVIDE(__start_cli_command = .); + KEEP(*(.cli_command)) + PROVIDE(__stop_cli_command = .); + } > FLASH + .crypto_data : + { + PROVIDE(__start_crypto_data = .); + KEEP(*(SORT(.crypto_data*))) + PROVIDE(__stop_crypto_data = .); + } > FLASH + .log_const_data : + { + PROVIDE(__start_log_const_data = .); + KEEP(*(SORT(.log_const_data*))) + PROVIDE(__stop_log_const_data = .); + } > FLASH + .log_backends : + { + PROVIDE(__start_log_backends = .); + KEEP(*(SORT(.log_backends*))) + PROVIDE(__stop_log_backends = .); + } > FLASH + +} INSERT AFTER .text + + +INCLUDE "nrf_common.ld" diff --git a/core/embed/ble_firmware/pm.c b/core/embed/ble_firmware/pm.c new file mode 100644 index 000000000..c18a255cd --- /dev/null +++ b/core/embed/ble_firmware/pm.c @@ -0,0 +1,156 @@ + + +#include "nrf_log.h" +#include "peer_manager_handler.h" + +#include "int_comm.h" +#include "pm.h" + +#define SEC_PARAM_BOND 1 /**< Perform bonding. */ +#define SEC_PARAM_MITM 1 /**< Man In The Middle protection not required. */ +#define SEC_PARAM_LESC 1 /**< LE Secure Connections not enabled. */ +#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */ +#define SEC_PARAM_IO_CAPABILITIES \ + BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY /**< No I/O capabilities. */ +#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ +#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ +#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ + +static pm_peer_id_t + m_peer_id; /**< Device reference handle to the current bonded central. */ + +pm_peer_id_t get_peer_id(void) { return m_peer_id; } + +/**@brief Function for setting filtered whitelist. + * + * @param[in] skip Filter passed to @ref pm_peer_id_list. + */ +void whitelist_set(pm_peer_id_list_skip_t skip) { + pm_peer_id_t peer_ids[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + uint32_t peer_id_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; + + ret_code_t err_code = + pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip); + APP_ERROR_CHECK(err_code); + + NRF_LOG_INFO("\tm_whitelist_peer_cnt %d, MAX_PEERS_WLIST %d", + peer_id_count + 1, BLE_GAP_WHITELIST_ADDR_MAX_COUNT); + + err_code = pm_whitelist_set(peer_ids, peer_id_count); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for handling Peer Manager events. + * + * @param[in] p_evt Peer Manager event. + */ +void pm_evt_handler(pm_evt_t const *p_evt) { + pm_handler_on_pm_evt(p_evt); + pm_handler_disconnect_on_sec_failure(p_evt); + pm_handler_flash_clean(p_evt); + + switch (p_evt->evt_id) { + case PM_EVT_CONN_SEC_SUCCEEDED: + m_peer_id = p_evt->peer_id; + break; + + case PM_EVT_PEERS_DELETE_SUCCEEDED: + // advertising_start(false); + break; + + case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED: + if (p_evt->params.peer_data_update_succeeded.flash_changed && + (p_evt->params.peer_data_update_succeeded.data_id == + PM_PEER_DATA_ID_BONDING)) { + NRF_LOG_INFO("New Bond, add the peer to the whitelist if possible"); + // Note: You should check on what kind of white list policy your + // application should use. + + whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR); + } + break; + case PM_EVT_CONN_SEC_CONFIG_REQ: { + bool ok = send_repair_request(); + + if (ok) { + // Allow pairing request from an already bonded peer. + pm_conn_sec_config_t conn_sec_config = {.allow_repairing = true}; + pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config); + } else { + // Reject pairing request from an already bonded peer. + pm_conn_sec_config_t conn_sec_config = {.allow_repairing = false}; + pm_conn_sec_config_reply(p_evt->conn_handle, &conn_sec_config); + } + + } break; + default: + break; + } +} + +/**@brief Function for the Peer Manager initialization. + */ +void peer_manager_init(void) { + ble_gap_sec_params_t sec_param; + pm_privacy_params_t privacy_params; + ret_code_t err_code; + + err_code = pm_init(); + APP_ERROR_CHECK(err_code); + + memset(&sec_param, 0, sizeof(ble_gap_sec_params_t)); + + // Security parameters to be used for all security procedures. + sec_param.bond = SEC_PARAM_BOND; + sec_param.mitm = SEC_PARAM_MITM; + sec_param.lesc = SEC_PARAM_LESC; + sec_param.keypress = SEC_PARAM_KEYPRESS; + sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES; + sec_param.oob = SEC_PARAM_OOB; + sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE; + sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE; + sec_param.kdist_own.enc = 1; + sec_param.kdist_own.id = 1; + sec_param.kdist_peer.enc = 1; + sec_param.kdist_peer.id = 1; + + err_code = pm_sec_params_set(&sec_param); + APP_ERROR_CHECK(err_code); + + privacy_params.p_device_irk = NULL; + privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY; + privacy_params.private_addr_cycle_s = 0; + privacy_params.private_addr_type = + BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE; + pm_privacy_set(&privacy_params); + + err_code = pm_register(pm_evt_handler); + APP_ERROR_CHECK(err_code); +} + +/**@brief Function for setting filtered device identities. + * + * @param[in] skip Filter passed to @ref pm_peer_id_list. + */ +void identities_set(pm_peer_id_list_skip_t skip) { + pm_peer_id_t peer_ids[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + uint32_t peer_id_count = BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; + + ret_code_t err_code = + pm_peer_id_list(peer_ids, &peer_id_count, PM_PEER_ID_INVALID, skip); + APP_ERROR_CHECK(err_code); + + err_code = pm_device_identities_list_set(peer_ids, peer_id_count); + APP_ERROR_CHECK(err_code); +} + +/////**@brief Clear bond information from persistent storage. */ +void delete_bonds(void) { + ret_code_t err_code; + + NRF_LOG_INFO("Erase bonds!"); + + // pm_whitelist_set(NULL, 0); + err_code = pm_peers_delete(); + APP_ERROR_CHECK(err_code); +} diff --git a/core/embed/ble_firmware/pm.h b/core/embed/ble_firmware/pm.h new file mode 100644 index 000000000..cfe9e6193 --- /dev/null +++ b/core/embed/ble_firmware/pm.h @@ -0,0 +1,18 @@ +#ifndef __PEER_MANAGER__ +#define __PEER_MANAGER__ + +#include "peer_manager.h" + +pm_peer_id_t get_peer_id(void); + +void whitelist_set(pm_peer_id_list_skip_t skip); + +void identities_set(pm_peer_id_list_skip_t skip); + +/**@brief Function for the Peer Manager initialization. + */ +void peer_manager_init(void); + +void delete_bonds(void); + +#endif diff --git a/core/embed/ble_firmware/power.c b/core/embed/ble_firmware/power.c new file mode 100644 index 000000000..b6f47f016 --- /dev/null +++ b/core/embed/ble_firmware/power.c @@ -0,0 +1,21 @@ +#include "power.h" +#include "app_error.h" + +/**@brief Function for putting the chip into sleep mode. + * + * @note This function will not return. + */ +// void sleep_mode_enter(void) { +// uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); +// APP_ERROR_CHECK(err_code); +// +// // Prepare wakeup buttons. +// err_code = bsp_btn_ble_sleep_mode_prepare(); +// APP_ERROR_CHECK(err_code); +// +// // Go to system-off mode (this function will not return; wakeup will cause +// a +// // reset). +// err_code = sd_power_system_off(); +// APP_ERROR_CHECK(err_code); +// } diff --git a/core/embed/ble_firmware/power.h b/core/embed/ble_firmware/power.h new file mode 100644 index 000000000..ac1f8965d --- /dev/null +++ b/core/embed/ble_firmware/power.h @@ -0,0 +1,6 @@ +#ifndef __POWER__ +#define __POWER__ + +void sleep_mode_enter(void); + +#endif diff --git a/core/embed/ble_firmware/sdk_config.h b/core/embed/ble_firmware/sdk_config.h new file mode 100644 index 000000000..835c6595d --- /dev/null +++ b/core/embed/ble_firmware/sdk_config.h @@ -0,0 +1,12147 @@ +// clang-format off + +/** + * Copyright (c) 2017 - 2021, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + + +#ifndef SDK_CONFIG_H +#define SDK_CONFIG_H +// <<< Use Configuration Wizard in Context Menu >>>\n +#ifdef USE_APP_CONFIG +#include "app_config.h" +#endif +// Board Support + +//========================================================== +// BSP_BTN_BLE_ENABLED - bsp_btn_ble - Button Control for BLE + + +#ifndef BSP_BTN_BLE_ENABLED +#define BSP_BTN_BLE_ENABLED 1 +#endif + +// +//========================================================== + +// nRF_BLE + +//========================================================== +// BLE_ADVERTISING_ENABLED - ble_advertising - Advertising module + + +#ifndef BLE_ADVERTISING_ENABLED +#define BLE_ADVERTISING_ENABLED 1 +#endif + +// BLE_DTM_ENABLED - ble_dtm - Module for testing RF/PHY using DTM commands +//========================================================== +#ifndef BLE_DTM_ENABLED +#define BLE_DTM_ENABLED 0 +#endif +// NRF_RADIO_ANTENNA_PIN_1 - Antenna 1 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_1 +#define NRF_RADIO_ANTENNA_PIN_1 21 +#endif + +// NRF_RADIO_ANTENNA_PIN_2 - Antenna 2 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_2 +#define NRF_RADIO_ANTENNA_PIN_2 23 +#endif + +// NRF_RADIO_ANTENNA_PIN_3 - Antenna 3 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_3 +#define NRF_RADIO_ANTENNA_PIN_3 26 +#endif + +// NRF_RADIO_ANTENNA_PIN_4 - Antenna 4 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_4 +#define NRF_RADIO_ANTENNA_PIN_4 27 +#endif + +// NRF_RADIO_ANTENNA_PIN_5 - Antenna 5 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_5 +#define NRF_RADIO_ANTENNA_PIN_5 28 +#endif + +// NRF_RADIO_ANTENNA_PIN_6 - Antenna 6 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_6 +#define NRF_RADIO_ANTENNA_PIN_6 29 +#endif + +// NRF_RADIO_ANTENNA_PIN_7 - Antenna 7 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_7 +#define NRF_RADIO_ANTENNA_PIN_7 30 +#endif + +// NRF_RADIO_ANTENNA_PIN_8 - Antenna 8 GPIO pin +#ifndef NRF_RADIO_ANTENNA_PIN_8 +#define NRF_RADIO_ANTENNA_PIN_8 31 +#endif + +// NRF_RADIO_ANTENNA_COUNT +#ifndef NRF_RADIO_ANTENNA_COUNT +#define NRF_RADIO_ANTENNA_COUNT 12 +#endif + +// DTM_RADIO_IRQ_PRIORITY - RADIO interrupt priority +#ifndef DTM_RADIO_IRQ_PRIORITY +#define DTM_RADIO_IRQ_PRIORITY 2 +#endif + +// DTM_TIMER_IRQ_PRIORITY - DTM timer interrupt priority +#ifndef DTM_TIMER_IRQ_PRIORITY +#define DTM_TIMER_IRQ_PRIORITY 3 +#endif + +// DTM_ANOMALY_172_TIMER_IRQ_PRIORITY - DTM anomaly 172 timer interrupt priority +#ifndef DTM_ANOMALY_172_TIMER_IRQ_PRIORITY +#define DTM_ANOMALY_172_TIMER_IRQ_PRIORITY 2 +#endif + +// NRF_DTM_TIMER_INSTANCE - DTM TIMER instance + +// <0=> TIMER0 +// <2=> TIMER2 +// <3=> TIMER3 +// <4=> TIMER4 + +#ifndef NRF_DTM_TIMER_INSTANCE +#define NRF_DTM_TIMER_INSTANCE 0 +#endif + +// + +// BLE_RACP_ENABLED - ble_racp - Record Access Control Point library + + +#ifndef BLE_RACP_ENABLED +#define BLE_RACP_ENABLED 0 +#endif + +// NRF_BLE_CONN_PARAMS_ENABLED - ble_conn_params - Initiating and executing a connection parameters negotiation procedure +//========================================================== +#ifndef NRF_BLE_CONN_PARAMS_ENABLED +#define NRF_BLE_CONN_PARAMS_ENABLED 1 +#endif +// NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION - The largest acceptable deviation in slave latency. +// The largest deviation (+ or -) from the requested slave latency that will not be renegotiated. + +#ifndef NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION +#define NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION 499 +#endif + +// NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION - The largest acceptable deviation (in 10 ms units) in supervision timeout. +// The largest deviation (+ or -, in 10 ms units) from the requested supervision timeout that will not be renegotiated. + +#ifndef NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION +#define NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION 65535 +#endif + +// + +// NRF_BLE_GATT_ENABLED - nrf_ble_gatt - GATT module +//========================================================== +#ifndef NRF_BLE_GATT_ENABLED +#define NRF_BLE_GATT_ENABLED 1 +#endif +// NRF_BLE_GATT_MTU_EXCHANGE_INITIATION_ENABLED - Enable GATT MTU exchange initiation + + +#ifndef NRF_BLE_GATT_MTU_EXCHANGE_INITIATION_ENABLED +#define NRF_BLE_GATT_MTU_EXCHANGE_INITIATION_ENABLED 1 +#endif + +// + +// NRF_BLE_QWR_ENABLED - nrf_ble_qwr - Queued writes support module (prepare/execute write) +//========================================================== +#ifndef NRF_BLE_QWR_ENABLED +#define NRF_BLE_QWR_ENABLED 1 +#endif +// NRF_BLE_QWR_MAX_ATTR - Maximum number of attribute handles that can be registered. This number must be adjusted according to the number of attributes for which Queued Writes will be enabled. If it is zero, the module will reject all Queued Write requests. +#ifndef NRF_BLE_QWR_MAX_ATTR +#define NRF_BLE_QWR_MAX_ATTR 0 +#endif + +// + +// PEER_MANAGER_ENABLED - peer_manager - Peer Manager +//========================================================== +#ifndef PEER_MANAGER_ENABLED +#define PEER_MANAGER_ENABLED 1 +#endif +// PM_MAX_REGISTRANTS - Number of event handlers that can be registered. +#ifndef PM_MAX_REGISTRANTS +#define PM_MAX_REGISTRANTS 3 +#endif + +// PM_FLASH_BUFFERS - Number of internal buffers for flash operations. +// Decrease this value to lower RAM usage. + +#ifndef PM_FLASH_BUFFERS +#define PM_FLASH_BUFFERS 4 +#endif + +// PM_CENTRAL_ENABLED - Enable/disable central-specific Peer Manager functionality. + + +// Enable/disable central-specific Peer Manager functionality. + +#ifndef PM_CENTRAL_ENABLED +#define PM_CENTRAL_ENABLED 0 +#endif + +// PM_SERVICE_CHANGED_ENABLED - Enable/disable the service changed management for GATT server in Peer Manager. + + +// If not using a GATT server, or using a server wihout a service changed characteristic, +// disable this to save code space. + +#ifndef PM_SERVICE_CHANGED_ENABLED +#define PM_SERVICE_CHANGED_ENABLED 1 +#endif + +// PM_PEER_RANKS_ENABLED - Enable/disable the peer rank management in Peer Manager. + + +// Set this to false to save code space if not using the peer rank API. + +#ifndef PM_PEER_RANKS_ENABLED +#define PM_PEER_RANKS_ENABLED 1 +#endif + +// PM_LESC_ENABLED - Enable/disable LESC support in Peer Manager. + + +// If set to true, you need to call nrf_ble_lesc_request_handler() in the main loop to respond to LESC-related BLE events. If LESC support is not required, set this to false to save code space. + +#ifndef PM_LESC_ENABLED +#define PM_LESC_ENABLED 1 +#endif + +// PM_RA_PROTECTION_ENABLED - Enable/disable protection against repeated pairing attempts in Peer Manager. +//========================================================== +#ifndef PM_RA_PROTECTION_ENABLED +#define PM_RA_PROTECTION_ENABLED 0 +#endif +// PM_RA_PROTECTION_TRACKED_PEERS_NUM - Maximum number of peers whose authorization status can be tracked. +#ifndef PM_RA_PROTECTION_TRACKED_PEERS_NUM +#define PM_RA_PROTECTION_TRACKED_PEERS_NUM 8 +#endif + +// PM_RA_PROTECTION_MIN_WAIT_INTERVAL - Minimum waiting interval (in ms) before a new pairing attempt can be initiated. +#ifndef PM_RA_PROTECTION_MIN_WAIT_INTERVAL +#define PM_RA_PROTECTION_MIN_WAIT_INTERVAL 4000 +#endif + +// PM_RA_PROTECTION_MAX_WAIT_INTERVAL - Maximum waiting interval (in ms) before a new pairing attempt can be initiated. +#ifndef PM_RA_PROTECTION_MAX_WAIT_INTERVAL +#define PM_RA_PROTECTION_MAX_WAIT_INTERVAL 64000 +#endif + +// PM_RA_PROTECTION_REWARD_PERIOD - Reward period (in ms). +// The waiting interval is gradually decreased when no new failed pairing attempts are made during reward period. + +#ifndef PM_RA_PROTECTION_REWARD_PERIOD +#define PM_RA_PROTECTION_REWARD_PERIOD 10000 +#endif + +// + +// PM_HANDLER_SEC_DELAY_MS - Delay before starting security. +// This might be necessary for interoperability reasons, especially as peripheral. + +#ifndef PM_HANDLER_SEC_DELAY_MS +#define PM_HANDLER_SEC_DELAY_MS 0 +#endif + +// + + +// nrf_ble_lesc - Le Secure Connection + +//========================================================== +// NRF_BLE_LESC_ENABLED - Enable LESC Module + + +#ifndef NRF_BLE_LESC_ENABLED +#define NRF_BLE_LESC_ENABLED 1 +#endif + +// NRF_BLE_LESC_GENERATE_NEW_KEYS - Generate new LESC keys after every pairing attempt. Keys are generated on the auth status event + + +#ifndef NRF_BLE_LESC_GENERATE_NEW_KEYS +#define NRF_BLE_LESC_GENERATE_NEW_KEYS 0 +#endif + +#ifndef NRF_CRYPTO_RNG_AUTO_INIT_ENABLED +#define NRF_CRYPTO_RNG_AUTO_INIT_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_BLE_Services + +//========================================================== +// BLE_ANCS_C_ENABLED - ble_ancs_c - Apple Notification Service Client + + +#ifndef BLE_ANCS_C_ENABLED +#define BLE_ANCS_C_ENABLED 0 +#endif + +// BLE_ANS_C_ENABLED - ble_ans_c - Alert Notification Service Client + + +#ifndef BLE_ANS_C_ENABLED +#define BLE_ANS_C_ENABLED 0 +#endif + +// BLE_BAS_C_ENABLED - ble_bas_c - Battery Service Client + + +#ifndef BLE_BAS_C_ENABLED +#define BLE_BAS_C_ENABLED 0 +#endif + +// BLE_BAS_ENABLED - ble_bas - Battery Service +//========================================================== +#ifndef BLE_BAS_ENABLED +#define BLE_BAS_ENABLED 0 +#endif +// BLE_BAS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef BLE_BAS_CONFIG_LOG_ENABLED +#define BLE_BAS_CONFIG_LOG_ENABLED 0 +#endif +// BLE_BAS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef BLE_BAS_CONFIG_LOG_LEVEL +#define BLE_BAS_CONFIG_LOG_LEVEL 3 +#endif + +// BLE_BAS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef BLE_BAS_CONFIG_INFO_COLOR +#define BLE_BAS_CONFIG_INFO_COLOR 0 +#endif + +// BLE_BAS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef BLE_BAS_CONFIG_DEBUG_COLOR +#define BLE_BAS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// BLE_CSCS_ENABLED - ble_cscs - Cycling Speed and Cadence Service + + +#ifndef BLE_CSCS_ENABLED +#define BLE_CSCS_ENABLED 0 +#endif + +// BLE_CTS_C_ENABLED - ble_cts_c - Current Time Service Client + + +#ifndef BLE_CTS_C_ENABLED +#define BLE_CTS_C_ENABLED 0 +#endif + +// BLE_DIS_ENABLED - ble_dis - Device Information Service + + +#ifndef BLE_DIS_ENABLED +#define BLE_DIS_ENABLED 1 +#endif + +// BLE_GLS_ENABLED - ble_gls - Glucose Service + + +#ifndef BLE_GLS_ENABLED +#define BLE_GLS_ENABLED 0 +#endif + +// BLE_HIDS_ENABLED - ble_hids - Human Interface Device Service + + +#ifndef BLE_HIDS_ENABLED +#define BLE_HIDS_ENABLED 0 +#endif + +// BLE_HRS_C_ENABLED - ble_hrs_c - Heart Rate Service Client + + +#ifndef BLE_HRS_C_ENABLED +#define BLE_HRS_C_ENABLED 0 +#endif + +// BLE_HRS_ENABLED - ble_hrs - Heart Rate Service + + +#ifndef BLE_HRS_ENABLED +#define BLE_HRS_ENABLED 0 +#endif + +// BLE_HTS_ENABLED - ble_hts - Health Thermometer Service + + +#ifndef BLE_HTS_ENABLED +#define BLE_HTS_ENABLED 0 +#endif + +// BLE_IAS_C_ENABLED - ble_ias_c - Immediate Alert Service Client + + +#ifndef BLE_IAS_C_ENABLED +#define BLE_IAS_C_ENABLED 0 +#endif + +// BLE_IAS_ENABLED - ble_ias - Immediate Alert Service +//========================================================== +#ifndef BLE_IAS_ENABLED +#define BLE_IAS_ENABLED 0 +#endif +// BLE_IAS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef BLE_IAS_CONFIG_LOG_ENABLED +#define BLE_IAS_CONFIG_LOG_ENABLED 0 +#endif +// BLE_IAS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef BLE_IAS_CONFIG_LOG_LEVEL +#define BLE_IAS_CONFIG_LOG_LEVEL 3 +#endif + +// BLE_IAS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef BLE_IAS_CONFIG_INFO_COLOR +#define BLE_IAS_CONFIG_INFO_COLOR 0 +#endif + +// BLE_IAS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef BLE_IAS_CONFIG_DEBUG_COLOR +#define BLE_IAS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// BLE_LBS_C_ENABLED - ble_lbs_c - Nordic LED Button Service Client + + +#ifndef BLE_LBS_C_ENABLED +#define BLE_LBS_C_ENABLED 0 +#endif + +// BLE_LBS_ENABLED - ble_lbs - LED Button Service + + +#ifndef BLE_LBS_ENABLED +#define BLE_LBS_ENABLED 0 +#endif + +// BLE_LLS_ENABLED - ble_lls - Link Loss Service + + +#ifndef BLE_LLS_ENABLED +#define BLE_LLS_ENABLED 0 +#endif + +// BLE_NUS_C_ENABLED - ble_nus_c - Nordic UART Central Service + + +#ifndef BLE_NUS_C_ENABLED +#define BLE_NUS_C_ENABLED 0 +#endif + +// BLE_NUS_ENABLED - ble_nus - Nordic UART Service +//========================================================== +#ifndef BLE_NUS_ENABLED +#define BLE_NUS_ENABLED 1 +#endif +// BLE_NUS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef BLE_NUS_CONFIG_LOG_ENABLED +#define BLE_NUS_CONFIG_LOG_ENABLED 0 +#endif +// BLE_NUS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef BLE_NUS_CONFIG_LOG_LEVEL +#define BLE_NUS_CONFIG_LOG_LEVEL 3 +#endif + +// BLE_NUS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef BLE_NUS_CONFIG_INFO_COLOR +#define BLE_NUS_CONFIG_INFO_COLOR 0 +#endif + +// BLE_NUS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef BLE_NUS_CONFIG_DEBUG_COLOR +#define BLE_NUS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// BLE_RSCS_C_ENABLED - ble_rscs_c - Running Speed and Cadence Client + + +#ifndef BLE_RSCS_C_ENABLED +#define BLE_RSCS_C_ENABLED 0 +#endif + +// BLE_RSCS_ENABLED - ble_rscs - Running Speed and Cadence Service + + +#ifndef BLE_RSCS_ENABLED +#define BLE_RSCS_ENABLED 0 +#endif + +// BLE_TPS_ENABLED - ble_tps - TX Power Service + + +#ifndef BLE_TPS_ENABLED +#define BLE_TPS_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_Core + +//========================================================== +// NRF_MPU_LIB_ENABLED - nrf_mpu_lib - Module for MPU +//========================================================== +#ifndef NRF_MPU_LIB_ENABLED +#define NRF_MPU_LIB_ENABLED 0 +#endif +// NRF_MPU_LIB_CLI_CMDS - Enable CLI commands specific to the module. + + +#ifndef NRF_MPU_LIB_CLI_CMDS +#define NRF_MPU_LIB_CLI_CMDS 0 +#endif + +// + +// NRF_STACK_GUARD_ENABLED - nrf_stack_guard - Stack guard +//========================================================== +#ifndef NRF_STACK_GUARD_ENABLED +#define NRF_STACK_GUARD_ENABLED 0 +#endif +// NRF_STACK_GUARD_CONFIG_SIZE - Size of the stack guard. + +// <5=> 32 bytes +// <6=> 64 bytes +// <7=> 128 bytes +// <8=> 256 bytes +// <9=> 512 bytes +// <10=> 1024 bytes +// <11=> 2048 bytes +// <12=> 4096 bytes + +#ifndef NRF_STACK_GUARD_CONFIG_SIZE +#define NRF_STACK_GUARD_CONFIG_SIZE 7 +#endif + +// + +// +//========================================================== + +// nRF_Crypto + +//========================================================== +// NRF_CRYPTO_ENABLED - nrf_crypto - Cryptography library. +//========================================================== +#ifndef NRF_CRYPTO_ENABLED +#define NRF_CRYPTO_ENABLED 1 +#endif +// NRF_CRYPTO_ALLOCATOR - Memory allocator + + +// Choose memory allocator used by nrf_crypto. Default is alloca if possible or nrf_malloc otherwise. If 'User macros' are selected, the user has to create 'nrf_crypto_allocator.h' file that contains NRF_CRYPTO_ALLOC, NRF_CRYPTO_FREE, and NRF_CRYPTO_ALLOC_ON_STACK. +// <0=> Default +// <1=> User macros +// <2=> On stack (alloca) +// <3=> C dynamic memory (malloc) +// <4=> SDK Memory Manager (nrf_malloc) + +#ifndef NRF_CRYPTO_ALLOCATOR +#define NRF_CRYPTO_ALLOCATOR 0 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_ENABLED - Enable the ARM Cryptocell CC310 reduced backend. + +// The CC310 hardware-accelerated cryptography backend with reduced functionality and footprint (only available on nRF52840). +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED - Enable the secp224r1 elliptic curve support using CC310_BL. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED - Enable the secp256r1 elliptic curve support using CC310_BL. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED - CC310_BL SHA-256 hash functionality. + + +// CC310_BL backend implementation for hardware-accelerated SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED - nrf_cc310_bl buffers to RAM before running hash operation + + +// Enabling this makes hashing of addresses in FLASH range possible. Size of buffer allocated for hashing is set by NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE - nrf_cc310_bl hash outputs digests in little endian +// Makes the nrf_cc310_bl hash functions output digests in little endian format. Only for use in nRF SDK DFU! + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE +#define NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE 4096 +#endif + +// NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED - Enable Interrupts while support using CC310 bl. + + +// Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used + +#ifndef NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_BL_INTERRUPTS_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_CC310_ENABLED - Enable the ARM Cryptocell CC310 backend. + +// The CC310 hardware-accelerated cryptography backend (only available on nRF52840). +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_CC310_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED - Enable the AES CBC mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED - Enable the AES CTR mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CTR_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED - Enable the AES ECB mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_ECB_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED - Enable the AES CBC_MAC mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED - Enable the AES CMAC mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CMAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED - Enable the AES CCM mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED - Enable the AES CCM* mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED - Enable the CHACHA-POLY mode using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED - Enable the secp160r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED - Enable the secp160r2 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED - Enable the secp192r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED - Enable the secp224r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED - Enable the secp256r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED - Enable the secp384r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED - Enable the secp521r1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED - Enable the secp160k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED - Enable the secp192k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED - Enable the secp224k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED - Enable the secp256k1 elliptic curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED - Enable the Curve25519 curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_CURVE25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED - Enable the Ed25519 curve support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_ECC_ED25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED - CC310 SHA-256 hash functionality. + + +// CC310 backend implementation for hardware-accelerated SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED - CC310 SHA-512 hash functionality + + +// CC310 backend implementation for SHA-512 (in software). + +#ifndef NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HASH_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED - CC310 HMAC using SHA-256 + + +// CC310 backend implementation for HMAC using hardware-accelerated SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED - CC310 HMAC using SHA-512 + + +// CC310 backend implementation for HMAC using SHA-512 (in software). + +#ifndef NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED - Enable RNG support using CC310. + + +#ifndef NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_RNG_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED - Enable Interrupts while support using CC310. + + +// Select a library version compatible with the configuration. When interrupts are disable, a version named _noint must be used + +#ifndef NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED +#define NRF_CRYPTO_BACKEND_CC310_INTERRUPTS_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_CIFRA_ENABLED - Enable the Cifra backend. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_CIFRA_ENABLED +#define NRF_CRYPTO_BACKEND_CIFRA_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED - Enable the AES EAX mode using Cifra. + + +#ifndef NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED +#define NRF_CRYPTO_BACKEND_CIFRA_AES_EAX_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED - Enable the mbed TLS backend. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED - Enable the AES CBC mode mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED - Enable the AES CTR mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED - Enable the AES CFB mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED - Enable the AES ECB mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED - Enable the AES CBC MAC mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED - Enable the AES CMAC mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED - Enable the AES CCM mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED - Enable the AES GCM mode using mbed TLS. + + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED - Enable secp192r1 (NIST 192-bit) curve + + +// Enable this setting if you need secp192r1 (NIST 192-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED - Enable secp224r1 (NIST 224-bit) curve + + +// Enable this setting if you need secp224r1 (NIST 224-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED - Enable secp256r1 (NIST 256-bit) curve + + +// Enable this setting if you need secp256r1 (NIST 256-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED - Enable secp384r1 (NIST 384-bit) curve + + +// Enable this setting if you need secp384r1 (NIST 384-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED - Enable secp521r1 (NIST 521-bit) curve + + +// Enable this setting if you need secp521r1 (NIST 521-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED - Enable secp192k1 (Koblitz 192-bit) curve + + +// Enable this setting if you need secp192k1 (Koblitz 192-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED - Enable secp224k1 (Koblitz 224-bit) curve + + +// Enable this setting if you need secp224k1 (Koblitz 224-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED - Enable secp256k1 (Koblitz 256-bit) curve + + +// Enable this setting if you need secp256k1 (Koblitz 256-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED - Enable bp256r1 (Brainpool 256-bit) curve + + +// Enable this setting if you need bp256r1 (Brainpool 256-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED - Enable bp384r1 (Brainpool 384-bit) curve + + +// Enable this setting if you need bp384r1 (Brainpool 384-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED - Enable bp512r1 (Brainpool 512-bit) curve + + +// Enable this setting if you need bp512r1 (Brainpool 512-bit) support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED - Enable Curve25519 curve + + +// Enable this setting if you need Curve25519 support using MBEDTLS + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED - Enable mbed TLS SHA-256 hash functionality. + + +// mbed TLS backend implementation for SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED - Enable mbed TLS SHA-512 hash functionality. + + +// mbed TLS backend implementation for SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED - Enable mbed TLS HMAC using SHA-256. + + +// mbed TLS backend implementation for HMAC using SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED - Enable mbed TLS HMAC using SHA-512. + + +// mbed TLS backend implementation for HMAC using SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED - Enable the micro-ecc backend. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ENABLED 1 +#endif +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED - Enable secp192r1 (NIST 192-bit) curve + + +// Enable this setting if you need secp192r1 (NIST 192-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED - Enable secp224r1 (NIST 224-bit) curve + + +// Enable this setting if you need secp224r1 (NIST 224-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED - Enable secp256r1 (NIST 256-bit) curve + + +// Enable this setting if you need secp256r1 (NIST 256-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED - Enable secp256k1 (Koblitz 256-bit) curve + + +// Enable this setting if you need secp256k1 (Koblitz 256-bit) support using micro-ecc + +#ifndef NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED +#define NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED - Enable the nRF HW RNG backend. + +// The nRF HW backend provide access to RNG peripheral in nRF5x devices. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_ENABLED 1 +#endif +// NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED - Enable mbed TLS CTR-DRBG algorithm. + +// Always recommended when using the nRF HW RNG as the context and temporary buffers are small. Consider disabling if using the CC310 RNG in a RAM constrained application. In this case, memory must be provided to nrf_crypto_rng_init, or it can be allocated internally provided that NRF_CRYPTO_ALLOCATOR does not allocate memory on the stack. + +#ifndef NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED +#define NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED 1 +#endif + + +// Enable mbed TLS CTR-DRBG standardized by NIST (NIST SP 800-90A Rev. 1). The nRF HW RNG is used as an entropy source for seeding. + +#ifndef NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_NRF_SW_ENABLED - Enable the legacy nRFx sw for crypto. + +// The nRF SW cryptography backend (only used in bootloader context). +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_NRF_SW_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_SW_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED - nRF SW hash backend support for SHA-256 + + +// The nRF SW backend provide access to nRF SDK legacy hash implementation of SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_OBERON_ENABLED - Enable the Oberon backend + +// The Oberon backend +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_OBERON_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED - Enable the CHACHA-POLY mode using Oberon. + + +#ifndef NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED - Enable secp256r1 curve + + +// Enable this setting if you need secp256r1 curve support using Oberon library + +#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED - Enable Curve25519 ECDH + + +// Enable this setting if you need Curve25519 ECDH support using Oberon library + +#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED - Enable Ed25519 signature scheme + + +// Enable this setting if you need Ed25519 support using Oberon library + +#ifndef NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED - Oberon SHA-256 hash functionality + + +// Oberon backend implementation for SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED - Oberon SHA-512 hash functionality + + +// Oberon backend implementation for SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED - Oberon HMAC using SHA-256 + + +// Oberon backend implementation for HMAC using SHA-256. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256_ENABLED 1 +#endif + +// NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED - Oberon HMAC using SHA-512 + + +// Oberon backend implementation for HMAC using SHA-512. + +#ifndef NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED +#define NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_BACKEND_OPTIGA_ENABLED - Enable the nrf_crypto Optiga Trust X backend. + +// Enables the nrf_crypto backend for Optiga Trust X devices. +//========================================================== +#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ENABLED +#define NRF_CRYPTO_BACKEND_OPTIGA_ENABLED 0 +#endif +// NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED - Optiga backend support for RNG + + +// The Optiga backend provide external chip RNG. + +#ifndef NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED +#define NRF_CRYPTO_BACKEND_OPTIGA_RNG_ENABLED 0 +#endif + +// NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED - Optiga backend support for ECC secp256r1 + + +// The Optiga backend provide external chip ECC using secp256r1. + +#ifndef NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED +#define NRF_CRYPTO_BACKEND_OPTIGA_ECC_SECP256R1_ENABLED 1 +#endif + +// + +// NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED - Big-endian byte order in raw Curve25519 data + + +// Enable big-endian byte order in Curve25519 API, if set to 1. Use little-endian, if set to 0. + +#ifndef NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED +#define NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED 0 +#endif + +// + +// +//========================================================== + +// nRF_DFU + +//========================================================== +// ble_dfu - Device Firmware Update + +//========================================================== +// BLE_DFU_ENABLED - Enable DFU Service. + + +#ifndef BLE_DFU_ENABLED +#define BLE_DFU_ENABLED 0 +#endif + +// NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS - Buttonless DFU supports bonds. + + +#ifndef NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS +#define NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_Drivers + +//========================================================== +// COMP_ENABLED - nrf_drv_comp - COMP peripheral driver - legacy layer +//========================================================== +#ifndef COMP_ENABLED +#define COMP_ENABLED 0 +#endif +// COMP_CONFIG_REF - Reference voltage + +// <0=> Internal 1.2V +// <1=> Internal 1.8V +// <2=> Internal 2.4V +// <4=> VDD +// <7=> ARef + +#ifndef COMP_CONFIG_REF +#define COMP_CONFIG_REF 1 +#endif + +// COMP_CONFIG_MAIN_MODE - Main mode + +// <0=> Single ended +// <1=> Differential + +#ifndef COMP_CONFIG_MAIN_MODE +#define COMP_CONFIG_MAIN_MODE 0 +#endif + +// COMP_CONFIG_SPEED_MODE - Speed mode + +// <0=> Low power +// <1=> Normal +// <2=> High speed + +#ifndef COMP_CONFIG_SPEED_MODE +#define COMP_CONFIG_SPEED_MODE 2 +#endif + +// COMP_CONFIG_HYST - Hystheresis + +// <0=> No +// <1=> 50mV + +#ifndef COMP_CONFIG_HYST +#define COMP_CONFIG_HYST 0 +#endif + +// COMP_CONFIG_ISOURCE - Current Source + +// <0=> Off +// <1=> 2.5 uA +// <2=> 5 uA +// <3=> 10 uA + +#ifndef COMP_CONFIG_ISOURCE +#define COMP_CONFIG_ISOURCE 0 +#endif + +// COMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef COMP_CONFIG_INPUT +#define COMP_CONFIG_INPUT 0 +#endif + +// COMP_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef COMP_CONFIG_IRQ_PRIORITY +#define COMP_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// EGU_ENABLED - nrf_drv_swi - SWI(EGU) peripheral driver - legacy layer + + +#ifndef EGU_ENABLED +#define EGU_ENABLED 0 +#endif + +// GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver - legacy layer +//========================================================== +#ifndef GPIOTE_ENABLED +#define GPIOTE_ENABLED 1 +#endif +// GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins +#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 +#endif + +// GPIOTE_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef GPIOTE_CONFIG_IRQ_PRIORITY +#define GPIOTE_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// I2S_ENABLED - nrf_drv_i2s - I2S peripheral driver - legacy layer +//========================================================== +#ifndef I2S_ENABLED +#define I2S_ENABLED 0 +#endif +// I2S_CONFIG_SCK_PIN - SCK pin <0-31> + + +#ifndef I2S_CONFIG_SCK_PIN +#define I2S_CONFIG_SCK_PIN 31 +#endif + +// I2S_CONFIG_LRCK_PIN - LRCK pin <1-31> + + +#ifndef I2S_CONFIG_LRCK_PIN +#define I2S_CONFIG_LRCK_PIN 30 +#endif + +// I2S_CONFIG_MCK_PIN - MCK pin +#ifndef I2S_CONFIG_MCK_PIN +#define I2S_CONFIG_MCK_PIN 255 +#endif + +// I2S_CONFIG_SDOUT_PIN - SDOUT pin <0-31> + + +#ifndef I2S_CONFIG_SDOUT_PIN +#define I2S_CONFIG_SDOUT_PIN 29 +#endif + +// I2S_CONFIG_SDIN_PIN - SDIN pin <0-31> + + +#ifndef I2S_CONFIG_SDIN_PIN +#define I2S_CONFIG_SDIN_PIN 28 +#endif + +// I2S_CONFIG_MASTER - Mode + +// <0=> Master +// <1=> Slave + +#ifndef I2S_CONFIG_MASTER +#define I2S_CONFIG_MASTER 0 +#endif + +// I2S_CONFIG_FORMAT - Format + +// <0=> I2S +// <1=> Aligned + +#ifndef I2S_CONFIG_FORMAT +#define I2S_CONFIG_FORMAT 0 +#endif + +// I2S_CONFIG_ALIGN - Alignment + +// <0=> Left +// <1=> Right + +#ifndef I2S_CONFIG_ALIGN +#define I2S_CONFIG_ALIGN 0 +#endif + +// I2S_CONFIG_SWIDTH - Sample width (bits) + +// <0=> 8 +// <1=> 16 +// <2=> 24 + +#ifndef I2S_CONFIG_SWIDTH +#define I2S_CONFIG_SWIDTH 1 +#endif + +// I2S_CONFIG_CHANNELS - Channels + +// <0=> Stereo +// <1=> Left +// <2=> Right + +#ifndef I2S_CONFIG_CHANNELS +#define I2S_CONFIG_CHANNELS 1 +#endif + +// I2S_CONFIG_MCK_SETUP - MCK behavior + +// <0=> Disabled +// <2147483648=> 32MHz/2 +// <1342177280=> 32MHz/3 +// <1073741824=> 32MHz/4 +// <805306368=> 32MHz/5 +// <671088640=> 32MHz/6 +// <536870912=> 32MHz/8 +// <402653184=> 32MHz/10 +// <369098752=> 32MHz/11 +// <285212672=> 32MHz/15 +// <268435456=> 32MHz/16 +// <201326592=> 32MHz/21 +// <184549376=> 32MHz/23 +// <142606336=> 32MHz/30 +// <138412032=> 32MHz/31 +// <134217728=> 32MHz/32 +// <100663296=> 32MHz/42 +// <68157440=> 32MHz/63 +// <34340864=> 32MHz/125 + +#ifndef I2S_CONFIG_MCK_SETUP +#define I2S_CONFIG_MCK_SETUP 536870912 +#endif + +// I2S_CONFIG_RATIO - MCK/LRCK ratio + +// <0=> 32x +// <1=> 48x +// <2=> 64x +// <3=> 96x +// <4=> 128x +// <5=> 192x +// <6=> 256x +// <7=> 384x +// <8=> 512x + +#ifndef I2S_CONFIG_RATIO +#define I2S_CONFIG_RATIO 2000 +#endif + +// I2S_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef I2S_CONFIG_IRQ_PRIORITY +#define I2S_CONFIG_IRQ_PRIORITY 6 +#endif + +// I2S_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef I2S_CONFIG_LOG_ENABLED +#define I2S_CONFIG_LOG_ENABLED 0 +#endif +// I2S_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef I2S_CONFIG_LOG_LEVEL +#define I2S_CONFIG_LOG_LEVEL 3 +#endif + +// I2S_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef I2S_CONFIG_INFO_COLOR +#define I2S_CONFIG_INFO_COLOR 0 +#endif + +// I2S_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef I2S_CONFIG_DEBUG_COLOR +#define I2S_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver - legacy layer +//========================================================== +#ifndef LPCOMP_ENABLED +#define LPCOMP_ENABLED 0 +#endif +// LPCOMP_CONFIG_REFERENCE - Reference voltage + +// <0=> Supply 1/8 +// <1=> Supply 2/8 +// <2=> Supply 3/8 +// <3=> Supply 4/8 +// <4=> Supply 5/8 +// <5=> Supply 6/8 +// <6=> Supply 7/8 +// <8=> Supply 1/16 (nRF52) +// <9=> Supply 3/16 (nRF52) +// <10=> Supply 5/16 (nRF52) +// <11=> Supply 7/16 (nRF52) +// <12=> Supply 9/16 (nRF52) +// <13=> Supply 11/16 (nRF52) +// <14=> Supply 13/16 (nRF52) +// <15=> Supply 15/16 (nRF52) +// <7=> External Ref 0 +// <65543=> External Ref 1 + +#ifndef LPCOMP_CONFIG_REFERENCE +#define LPCOMP_CONFIG_REFERENCE 3 +#endif + +// LPCOMP_CONFIG_DETECTION - Detection + +// <0=> Crossing +// <1=> Up +// <2=> Down + +#ifndef LPCOMP_CONFIG_DETECTION +#define LPCOMP_CONFIG_DETECTION 2 +#endif + +// LPCOMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef LPCOMP_CONFIG_INPUT +#define LPCOMP_CONFIG_INPUT 0 +#endif + +// LPCOMP_CONFIG_HYST - Hysteresis + + +#ifndef LPCOMP_CONFIG_HYST +#define LPCOMP_CONFIG_HYST 0 +#endif + +// LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef LPCOMP_CONFIG_IRQ_PRIORITY +#define LPCOMP_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// NRFX_CLOCK_ENABLED - nrfx_clock - CLOCK peripheral driver +//========================================================== +#ifndef NRFX_CLOCK_ENABLED +#define NRFX_CLOCK_ENABLED 1 +#endif +// NRFX_CLOCK_CONFIG_LF_SRC - LF Clock Source + +// <0=> RC +// <1=> XTAL +// <2=> Synth +// <131073=> External Low Swing +// <196609=> External Full Swing + +#ifndef NRFX_CLOCK_CONFIG_LF_SRC +#define NRFX_CLOCK_CONFIG_LF_SRC 1 +#endif + +// NRFX_CLOCK_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_CLOCK_CONFIG_IRQ_PRIORITY +#define NRFX_CLOCK_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_CLOCK_CONFIG_LOG_ENABLED +#define NRFX_CLOCK_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_CLOCK_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_CLOCK_CONFIG_LOG_LEVEL +#define NRFX_CLOCK_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_CLOCK_CONFIG_INFO_COLOR +#define NRFX_CLOCK_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_CLOCK_CONFIG_DEBUG_COLOR +#define NRFX_CLOCK_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_COMP_ENABLED - nrfx_comp - COMP peripheral driver +//========================================================== +#ifndef NRFX_COMP_ENABLED +#define NRFX_COMP_ENABLED 0 +#endif +// NRFX_COMP_CONFIG_REF - Reference voltage + +// <0=> Internal 1.2V +// <1=> Internal 1.8V +// <2=> Internal 2.4V +// <4=> VDD +// <7=> ARef + +#ifndef NRFX_COMP_CONFIG_REF +#define NRFX_COMP_CONFIG_REF 1 +#endif + +// NRFX_COMP_CONFIG_MAIN_MODE - Main mode + +// <0=> Single ended +// <1=> Differential + +#ifndef NRFX_COMP_CONFIG_MAIN_MODE +#define NRFX_COMP_CONFIG_MAIN_MODE 0 +#endif + +// NRFX_COMP_CONFIG_SPEED_MODE - Speed mode + +// <0=> Low power +// <1=> Normal +// <2=> High speed + +#ifndef NRFX_COMP_CONFIG_SPEED_MODE +#define NRFX_COMP_CONFIG_SPEED_MODE 2 +#endif + +// NRFX_COMP_CONFIG_HYST - Hystheresis + +// <0=> No +// <1=> 50mV + +#ifndef NRFX_COMP_CONFIG_HYST +#define NRFX_COMP_CONFIG_HYST 0 +#endif + +// NRFX_COMP_CONFIG_ISOURCE - Current Source + +// <0=> Off +// <1=> 2.5 uA +// <2=> 5 uA +// <3=> 10 uA + +#ifndef NRFX_COMP_CONFIG_ISOURCE +#define NRFX_COMP_CONFIG_ISOURCE 0 +#endif + +// NRFX_COMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_COMP_CONFIG_INPUT +#define NRFX_COMP_CONFIG_INPUT 0 +#endif + +// NRFX_COMP_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_COMP_CONFIG_IRQ_PRIORITY +#define NRFX_COMP_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_COMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_COMP_CONFIG_LOG_ENABLED +#define NRFX_COMP_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_COMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_COMP_CONFIG_LOG_LEVEL +#define NRFX_COMP_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_COMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_COMP_CONFIG_INFO_COLOR +#define NRFX_COMP_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_COMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_COMP_CONFIG_DEBUG_COLOR +#define NRFX_COMP_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_GPIOTE_ENABLED - nrfx_gpiote - GPIOTE peripheral driver +//========================================================== +#ifndef NRFX_GPIOTE_ENABLED +#define NRFX_GPIOTE_ENABLED 1 +#endif +// NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins +#ifndef NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS +#define NRFX_GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 +#endif + +// NRFX_GPIOTE_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_GPIOTE_CONFIG_IRQ_PRIORITY +#define NRFX_GPIOTE_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_GPIOTE_CONFIG_LOG_ENABLED +#define NRFX_GPIOTE_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_GPIOTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_GPIOTE_CONFIG_LOG_LEVEL +#define NRFX_GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_GPIOTE_CONFIG_INFO_COLOR +#define NRFX_GPIOTE_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_GPIOTE_CONFIG_DEBUG_COLOR +#define NRFX_GPIOTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_I2S_ENABLED - nrfx_i2s - I2S peripheral driver +//========================================================== +#ifndef NRFX_I2S_ENABLED +#define NRFX_I2S_ENABLED 0 +#endif +// NRFX_I2S_CONFIG_SCK_PIN - SCK pin <0-31> + + +#ifndef NRFX_I2S_CONFIG_SCK_PIN +#define NRFX_I2S_CONFIG_SCK_PIN 31 +#endif + +// NRFX_I2S_CONFIG_LRCK_PIN - LRCK pin <1-31> + + +#ifndef NRFX_I2S_CONFIG_LRCK_PIN +#define NRFX_I2S_CONFIG_LRCK_PIN 30 +#endif + +// NRFX_I2S_CONFIG_MCK_PIN - MCK pin +#ifndef NRFX_I2S_CONFIG_MCK_PIN +#define NRFX_I2S_CONFIG_MCK_PIN 255 +#endif + +// NRFX_I2S_CONFIG_SDOUT_PIN - SDOUT pin <0-31> + + +#ifndef NRFX_I2S_CONFIG_SDOUT_PIN +#define NRFX_I2S_CONFIG_SDOUT_PIN 29 +#endif + +// NRFX_I2S_CONFIG_SDIN_PIN - SDIN pin <0-31> + + +#ifndef NRFX_I2S_CONFIG_SDIN_PIN +#define NRFX_I2S_CONFIG_SDIN_PIN 28 +#endif + +// NRFX_I2S_CONFIG_MASTER - Mode + +// <0=> Master +// <1=> Slave + +#ifndef NRFX_I2S_CONFIG_MASTER +#define NRFX_I2S_CONFIG_MASTER 0 +#endif + +// NRFX_I2S_CONFIG_FORMAT - Format + +// <0=> I2S +// <1=> Aligned + +#ifndef NRFX_I2S_CONFIG_FORMAT +#define NRFX_I2S_CONFIG_FORMAT 0 +#endif + +// NRFX_I2S_CONFIG_ALIGN - Alignment + +// <0=> Left +// <1=> Right + +#ifndef NRFX_I2S_CONFIG_ALIGN +#define NRFX_I2S_CONFIG_ALIGN 0 +#endif + +// NRFX_I2S_CONFIG_SWIDTH - Sample width (bits) + +// <0=> 8 +// <1=> 16 +// <2=> 24 + +#ifndef NRFX_I2S_CONFIG_SWIDTH +#define NRFX_I2S_CONFIG_SWIDTH 1 +#endif + +// NRFX_I2S_CONFIG_CHANNELS - Channels + +// <0=> Stereo +// <1=> Left +// <2=> Right + +#ifndef NRFX_I2S_CONFIG_CHANNELS +#define NRFX_I2S_CONFIG_CHANNELS 1 +#endif + +// NRFX_I2S_CONFIG_MCK_SETUP - MCK behavior + +// <0=> Disabled +// <2147483648=> 32MHz/2 +// <1342177280=> 32MHz/3 +// <1073741824=> 32MHz/4 +// <805306368=> 32MHz/5 +// <671088640=> 32MHz/6 +// <536870912=> 32MHz/8 +// <402653184=> 32MHz/10 +// <369098752=> 32MHz/11 +// <285212672=> 32MHz/15 +// <268435456=> 32MHz/16 +// <201326592=> 32MHz/21 +// <184549376=> 32MHz/23 +// <142606336=> 32MHz/30 +// <138412032=> 32MHz/31 +// <134217728=> 32MHz/32 +// <100663296=> 32MHz/42 +// <68157440=> 32MHz/63 +// <34340864=> 32MHz/125 + +#ifndef NRFX_I2S_CONFIG_MCK_SETUP +#define NRFX_I2S_CONFIG_MCK_SETUP 536870912 +#endif + +// NRFX_I2S_CONFIG_RATIO - MCK/LRCK ratio + +// <0=> 32x +// <1=> 48x +// <2=> 64x +// <3=> 96x +// <4=> 128x +// <5=> 192x +// <6=> 256x +// <7=> 384x +// <8=> 512x + +#ifndef NRFX_I2S_CONFIG_RATIO +#define NRFX_I2S_CONFIG_RATIO 2000 +#endif + +// NRFX_I2S_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_I2S_CONFIG_IRQ_PRIORITY +#define NRFX_I2S_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_I2S_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_I2S_CONFIG_LOG_ENABLED +#define NRFX_I2S_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_I2S_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_I2S_CONFIG_LOG_LEVEL +#define NRFX_I2S_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_I2S_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_I2S_CONFIG_INFO_COLOR +#define NRFX_I2S_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_I2S_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_I2S_CONFIG_DEBUG_COLOR +#define NRFX_I2S_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_LPCOMP_ENABLED - nrfx_lpcomp - LPCOMP peripheral driver +//========================================================== +#ifndef NRFX_LPCOMP_ENABLED +#define NRFX_LPCOMP_ENABLED 0 +#endif +// NRFX_LPCOMP_CONFIG_REFERENCE - Reference voltage + +// <0=> Supply 1/8 +// <1=> Supply 2/8 +// <2=> Supply 3/8 +// <3=> Supply 4/8 +// <4=> Supply 5/8 +// <5=> Supply 6/8 +// <6=> Supply 7/8 +// <8=> Supply 1/16 (nRF52) +// <9=> Supply 3/16 (nRF52) +// <10=> Supply 5/16 (nRF52) +// <11=> Supply 7/16 (nRF52) +// <12=> Supply 9/16 (nRF52) +// <13=> Supply 11/16 (nRF52) +// <14=> Supply 13/16 (nRF52) +// <15=> Supply 15/16 (nRF52) +// <7=> External Ref 0 +// <65543=> External Ref 1 + +#ifndef NRFX_LPCOMP_CONFIG_REFERENCE +#define NRFX_LPCOMP_CONFIG_REFERENCE 3 +#endif + +// NRFX_LPCOMP_CONFIG_DETECTION - Detection + +// <0=> Crossing +// <1=> Up +// <2=> Down + +#ifndef NRFX_LPCOMP_CONFIG_DETECTION +#define NRFX_LPCOMP_CONFIG_DETECTION 2 +#endif + +// NRFX_LPCOMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_LPCOMP_CONFIG_INPUT +#define NRFX_LPCOMP_CONFIG_INPUT 0 +#endif + +// NRFX_LPCOMP_CONFIG_HYST - Hysteresis + + +#ifndef NRFX_LPCOMP_CONFIG_HYST +#define NRFX_LPCOMP_CONFIG_HYST 0 +#endif + +// NRFX_LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_LPCOMP_CONFIG_IRQ_PRIORITY +#define NRFX_LPCOMP_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_LPCOMP_CONFIG_LOG_ENABLED +#define NRFX_LPCOMP_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_LPCOMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_LPCOMP_CONFIG_LOG_LEVEL +#define NRFX_LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_LPCOMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_LPCOMP_CONFIG_INFO_COLOR +#define NRFX_LPCOMP_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_LPCOMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_LPCOMP_CONFIG_DEBUG_COLOR +#define NRFX_LPCOMP_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_NFCT_ENABLED - nrfx_nfct - NFCT peripheral driver +//========================================================== +#ifndef NRFX_NFCT_ENABLED +#define NRFX_NFCT_ENABLED 0 +#endif +// NRFX_NFCT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_NFCT_CONFIG_IRQ_PRIORITY +#define NRFX_NFCT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_NFCT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_NFCT_CONFIG_LOG_ENABLED +#define NRFX_NFCT_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_NFCT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_NFCT_CONFIG_LOG_LEVEL +#define NRFX_NFCT_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_NFCT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_NFCT_CONFIG_INFO_COLOR +#define NRFX_NFCT_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_NFCT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_NFCT_CONFIG_DEBUG_COLOR +#define NRFX_NFCT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_PDM_ENABLED - nrfx_pdm - PDM peripheral driver +//========================================================== +#ifndef NRFX_PDM_ENABLED +#define NRFX_PDM_ENABLED 0 +#endif +// NRFX_PDM_CONFIG_MODE - Mode + +// <0=> Stereo +// <1=> Mono + +#ifndef NRFX_PDM_CONFIG_MODE +#define NRFX_PDM_CONFIG_MODE 1 +#endif + +// NRFX_PDM_CONFIG_EDGE - Edge + +// <0=> Left falling +// <1=> Left rising + +#ifndef NRFX_PDM_CONFIG_EDGE +#define NRFX_PDM_CONFIG_EDGE 0 +#endif + +// NRFX_PDM_CONFIG_CLOCK_FREQ - Clock frequency + +// <134217728=> 1000k +// <138412032=> 1032k (default) +// <142606336=> 1067k + +#ifndef NRFX_PDM_CONFIG_CLOCK_FREQ +#define NRFX_PDM_CONFIG_CLOCK_FREQ 138412032 +#endif + +// NRFX_PDM_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_PDM_CONFIG_IRQ_PRIORITY +#define NRFX_PDM_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_PDM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_PDM_CONFIG_LOG_ENABLED +#define NRFX_PDM_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_PDM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_PDM_CONFIG_LOG_LEVEL +#define NRFX_PDM_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_PDM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PDM_CONFIG_INFO_COLOR +#define NRFX_PDM_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_PDM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PDM_CONFIG_DEBUG_COLOR +#define NRFX_PDM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_POWER_ENABLED - nrfx_power - POWER peripheral driver +//========================================================== +#ifndef NRFX_POWER_ENABLED +#define NRFX_POWER_ENABLED 0 +#endif +// NRFX_POWER_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_POWER_CONFIG_IRQ_PRIORITY +#define NRFX_POWER_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCEN +#define NRFX_POWER_CONFIG_DEFAULT_DCDCEN 0 +#endif + +// NRFX_POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCENHV +#define NRFX_POWER_CONFIG_DEFAULT_DCDCENHV 0 +#endif + +// + +// NRFX_PPI_ENABLED - nrfx_ppi - PPI peripheral allocator +//========================================================== +#ifndef NRFX_PPI_ENABLED +#define NRFX_PPI_ENABLED 0 +#endif +// NRFX_PPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_PPI_CONFIG_LOG_ENABLED +#define NRFX_PPI_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_PPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_PPI_CONFIG_LOG_LEVEL +#define NRFX_PPI_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_PPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PPI_CONFIG_INFO_COLOR +#define NRFX_PPI_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_PPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PPI_CONFIG_DEBUG_COLOR +#define NRFX_PPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_PRS_ENABLED - nrfx_prs - Peripheral Resource Sharing module +//========================================================== +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 1 +#endif +// NRFX_PRS_BOX_0_ENABLED - Enables box 0 in the module. + + +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +// NRFX_PRS_BOX_1_ENABLED - Enables box 1 in the module. + + +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + +// NRFX_PRS_BOX_2_ENABLED - Enables box 2 in the module. + + +#ifndef NRFX_PRS_BOX_2_ENABLED +#define NRFX_PRS_BOX_2_ENABLED 0 +#endif + +// NRFX_PRS_BOX_3_ENABLED - Enables box 3 in the module. + + +#ifndef NRFX_PRS_BOX_3_ENABLED +#define NRFX_PRS_BOX_3_ENABLED 0 +#endif + +// NRFX_PRS_BOX_4_ENABLED - Enables box 4 in the module. + + +#ifndef NRFX_PRS_BOX_4_ENABLED +#define NRFX_PRS_BOX_4_ENABLED 1 +#endif + +// NRFX_PRS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_PRS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_PRS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PRS_CONFIG_INFO_COLOR +#define NRFX_PRS_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_PRS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PRS_CONFIG_DEBUG_COLOR +#define NRFX_PRS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_PWM_ENABLED - nrfx_pwm - PWM peripheral driver +//========================================================== +#ifndef NRFX_PWM_ENABLED +#define NRFX_PWM_ENABLED 0 +#endif +// NRFX_PWM0_ENABLED - Enable PWM0 instance + + +#ifndef NRFX_PWM0_ENABLED +#define NRFX_PWM0_ENABLED 0 +#endif + +// NRFX_PWM1_ENABLED - Enable PWM1 instance + + +#ifndef NRFX_PWM1_ENABLED +#define NRFX_PWM1_ENABLED 0 +#endif + +// NRFX_PWM2_ENABLED - Enable PWM2 instance + + +#ifndef NRFX_PWM2_ENABLED +#define NRFX_PWM2_ENABLED 0 +#endif + +// NRFX_PWM3_ENABLED - Enable PWM3 instance + + +#ifndef NRFX_PWM3_ENABLED +#define NRFX_PWM3_ENABLED 0 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin <0-31> + + +#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN +#define NRFX_PWM_DEFAULT_CONFIG_OUT0_PIN 31 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin <0-31> + + +#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN +#define NRFX_PWM_DEFAULT_CONFIG_OUT1_PIN 31 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin <0-31> + + +#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN +#define NRFX_PWM_DEFAULT_CONFIG_OUT2_PIN 31 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin <0-31> + + +#ifndef NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN +#define NRFX_PWM_DEFAULT_CONFIG_OUT3_PIN 31 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK - Base clock + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 kHz + +#ifndef NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK +#define NRFX_PWM_DEFAULT_CONFIG_BASE_CLOCK 4 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE - Count mode + +// <0=> Up +// <1=> Up and Down + +#ifndef NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE +#define NRFX_PWM_DEFAULT_CONFIG_COUNT_MODE 0 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE - Top value +#ifndef NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE +#define NRFX_PWM_DEFAULT_CONFIG_TOP_VALUE 1000 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE - Load mode + +// <0=> Common +// <1=> Grouped +// <2=> Individual +// <3=> Waveform + +#ifndef NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE +#define NRFX_PWM_DEFAULT_CONFIG_LOAD_MODE 0 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_STEP_MODE - Step mode + +// <0=> Auto +// <1=> Triggered + +#ifndef NRFX_PWM_DEFAULT_CONFIG_STEP_MODE +#define NRFX_PWM_DEFAULT_CONFIG_STEP_MODE 0 +#endif + +// NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_PWM_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_PWM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_PWM_CONFIG_LOG_ENABLED +#define NRFX_PWM_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_PWM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_PWM_CONFIG_LOG_LEVEL +#define NRFX_PWM_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PWM_CONFIG_INFO_COLOR +#define NRFX_PWM_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_PWM_CONFIG_DEBUG_COLOR +#define NRFX_PWM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_QDEC_ENABLED - nrfx_qdec - QDEC peripheral driver +//========================================================== +#ifndef NRFX_QDEC_ENABLED +#define NRFX_QDEC_ENABLED 0 +#endif +// NRFX_QDEC_CONFIG_REPORTPER - Report period + +// <0=> 10 Samples +// <1=> 40 Samples +// <2=> 80 Samples +// <3=> 120 Samples +// <4=> 160 Samples +// <5=> 200 Samples +// <6=> 240 Samples +// <7=> 280 Samples + +#ifndef NRFX_QDEC_CONFIG_REPORTPER +#define NRFX_QDEC_CONFIG_REPORTPER 0 +#endif + +// NRFX_QDEC_CONFIG_SAMPLEPER - Sample period + +// <0=> 128 us +// <1=> 256 us +// <2=> 512 us +// <3=> 1024 us +// <4=> 2048 us +// <5=> 4096 us +// <6=> 8192 us +// <7=> 16384 us + +#ifndef NRFX_QDEC_CONFIG_SAMPLEPER +#define NRFX_QDEC_CONFIG_SAMPLEPER 7 +#endif + +// NRFX_QDEC_CONFIG_PIO_A - A pin <0-31> + + +#ifndef NRFX_QDEC_CONFIG_PIO_A +#define NRFX_QDEC_CONFIG_PIO_A 31 +#endif + +// NRFX_QDEC_CONFIG_PIO_B - B pin <0-31> + + +#ifndef NRFX_QDEC_CONFIG_PIO_B +#define NRFX_QDEC_CONFIG_PIO_B 31 +#endif + +// NRFX_QDEC_CONFIG_PIO_LED - LED pin <0-31> + + +#ifndef NRFX_QDEC_CONFIG_PIO_LED +#define NRFX_QDEC_CONFIG_PIO_LED 31 +#endif + +// NRFX_QDEC_CONFIG_LEDPRE - LED pre +#ifndef NRFX_QDEC_CONFIG_LEDPRE +#define NRFX_QDEC_CONFIG_LEDPRE 511 +#endif + +// NRFX_QDEC_CONFIG_LEDPOL - LED polarity + +// <0=> Active low +// <1=> Active high + +#ifndef NRFX_QDEC_CONFIG_LEDPOL +#define NRFX_QDEC_CONFIG_LEDPOL 1 +#endif + +// NRFX_QDEC_CONFIG_DBFEN - Debouncing enable + + +#ifndef NRFX_QDEC_CONFIG_DBFEN +#define NRFX_QDEC_CONFIG_DBFEN 0 +#endif + +// NRFX_QDEC_CONFIG_SAMPLE_INTEN - Sample ready interrupt enable + + +#ifndef NRFX_QDEC_CONFIG_SAMPLE_INTEN +#define NRFX_QDEC_CONFIG_SAMPLE_INTEN 0 +#endif + +// NRFX_QDEC_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_QDEC_CONFIG_IRQ_PRIORITY +#define NRFX_QDEC_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_QDEC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_QDEC_CONFIG_LOG_ENABLED +#define NRFX_QDEC_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_QDEC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_QDEC_CONFIG_LOG_LEVEL +#define NRFX_QDEC_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_QDEC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_QDEC_CONFIG_INFO_COLOR +#define NRFX_QDEC_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_QDEC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_QDEC_CONFIG_DEBUG_COLOR +#define NRFX_QDEC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_QSPI_ENABLED - nrfx_qspi - QSPI peripheral driver +//========================================================== +#ifndef NRFX_QSPI_ENABLED +#define NRFX_QSPI_ENABLED 0 +#endif +// NRFX_QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns). <0-255> + + +#ifndef NRFX_QSPI_CONFIG_SCK_DELAY +#define NRFX_QSPI_CONFIG_SCK_DELAY 1 +#endif + +// NRFX_QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. +#ifndef NRFX_QSPI_CONFIG_XIP_OFFSET +#define NRFX_QSPI_CONFIG_XIP_OFFSET 0 +#endif + +// NRFX_QSPI_CONFIG_READOC - Number of data lines and opcode used for reading. + +// <0=> FastRead +// <1=> Read2O +// <2=> Read2IO +// <3=> Read4O +// <4=> Read4IO + +#ifndef NRFX_QSPI_CONFIG_READOC +#define NRFX_QSPI_CONFIG_READOC 0 +#endif + +// NRFX_QSPI_CONFIG_WRITEOC - Number of data lines and opcode used for writing. + +// <0=> PP +// <1=> PP2O +// <2=> PP4O +// <3=> PP4IO + +#ifndef NRFX_QSPI_CONFIG_WRITEOC +#define NRFX_QSPI_CONFIG_WRITEOC 0 +#endif + +// NRFX_QSPI_CONFIG_ADDRMODE - Addressing mode. + +// <0=> 24bit +// <1=> 32bit + +#ifndef NRFX_QSPI_CONFIG_ADDRMODE +#define NRFX_QSPI_CONFIG_ADDRMODE 0 +#endif + +// NRFX_QSPI_CONFIG_MODE - SPI mode. + +// <0=> Mode 0 +// <1=> Mode 1 + +#ifndef NRFX_QSPI_CONFIG_MODE +#define NRFX_QSPI_CONFIG_MODE 0 +#endif + +// NRFX_QSPI_CONFIG_FREQUENCY - Frequency divider. + +// <0=> 32MHz/1 +// <1=> 32MHz/2 +// <2=> 32MHz/3 +// <3=> 32MHz/4 +// <4=> 32MHz/5 +// <5=> 32MHz/6 +// <6=> 32MHz/7 +// <7=> 32MHz/8 +// <8=> 32MHz/9 +// <9=> 32MHz/10 +// <10=> 32MHz/11 +// <11=> 32MHz/12 +// <12=> 32MHz/13 +// <13=> 32MHz/14 +// <14=> 32MHz/15 +// <15=> 32MHz/16 + +#ifndef NRFX_QSPI_CONFIG_FREQUENCY +#define NRFX_QSPI_CONFIG_FREQUENCY 15 +#endif + +// NRFX_QSPI_PIN_SCK - SCK pin value. +#ifndef NRFX_QSPI_PIN_SCK +#define NRFX_QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// NRFX_QSPI_PIN_CSN - CSN pin value. +#ifndef NRFX_QSPI_PIN_CSN +#define NRFX_QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// NRFX_QSPI_PIN_IO0 - IO0 pin value. +#ifndef NRFX_QSPI_PIN_IO0 +#define NRFX_QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// NRFX_QSPI_PIN_IO1 - IO1 pin value. +#ifndef NRFX_QSPI_PIN_IO1 +#define NRFX_QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// NRFX_QSPI_PIN_IO2 - IO2 pin value. +#ifndef NRFX_QSPI_PIN_IO2 +#define NRFX_QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// NRFX_QSPI_PIN_IO3 - IO3 pin value. +#ifndef NRFX_QSPI_PIN_IO3 +#define NRFX_QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// NRFX_QSPI_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_QSPI_CONFIG_IRQ_PRIORITY +#define NRFX_QSPI_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// NRFX_RNG_ENABLED - nrfx_rng - RNG peripheral driver +//========================================================== +#ifndef NRFX_RNG_ENABLED +#define NRFX_RNG_ENABLED 1 +#endif +// NRFX_RNG_CONFIG_ERROR_CORRECTION - Error correction + + +#ifndef NRFX_RNG_CONFIG_ERROR_CORRECTION +#define NRFX_RNG_CONFIG_ERROR_CORRECTION 1 +#endif + +// NRFX_RNG_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_RNG_CONFIG_IRQ_PRIORITY +#define NRFX_RNG_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_RNG_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_RNG_CONFIG_LOG_ENABLED +#define NRFX_RNG_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_RNG_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_RNG_CONFIG_LOG_LEVEL +#define NRFX_RNG_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_RNG_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_RNG_CONFIG_INFO_COLOR +#define NRFX_RNG_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_RNG_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_RNG_CONFIG_DEBUG_COLOR +#define NRFX_RNG_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_RTC_ENABLED - nrfx_rtc - RTC peripheral driver +//========================================================== +#ifndef NRFX_RTC_ENABLED +#define NRFX_RTC_ENABLED 0 +#endif +// NRFX_RTC0_ENABLED - Enable RTC0 instance + + +#ifndef NRFX_RTC0_ENABLED +#define NRFX_RTC0_ENABLED 0 +#endif + +// NRFX_RTC1_ENABLED - Enable RTC1 instance + + +#ifndef NRFX_RTC1_ENABLED +#define NRFX_RTC1_ENABLED 0 +#endif + +// NRFX_RTC2_ENABLED - Enable RTC2 instance + + +#ifndef NRFX_RTC2_ENABLED +#define NRFX_RTC2_ENABLED 0 +#endif + +// NRFX_RTC_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt +#ifndef NRFX_RTC_MAXIMUM_LATENCY_US +#define NRFX_RTC_MAXIMUM_LATENCY_US 2000 +#endif + +// NRFX_RTC_DEFAULT_CONFIG_FREQUENCY - Frequency <16-32768> + + +#ifndef NRFX_RTC_DEFAULT_CONFIG_FREQUENCY +#define NRFX_RTC_DEFAULT_CONFIG_FREQUENCY 32768 +#endif + +// NRFX_RTC_DEFAULT_CONFIG_RELIABLE - Ensures safe compare event triggering + + +#ifndef NRFX_RTC_DEFAULT_CONFIG_RELIABLE +#define NRFX_RTC_DEFAULT_CONFIG_RELIABLE 0 +#endif + +// NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_RTC_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_RTC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_RTC_CONFIG_LOG_ENABLED +#define NRFX_RTC_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_RTC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_RTC_CONFIG_LOG_LEVEL +#define NRFX_RTC_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_RTC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_RTC_CONFIG_INFO_COLOR +#define NRFX_RTC_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_RTC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_RTC_CONFIG_DEBUG_COLOR +#define NRFX_RTC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_SAADC_ENABLED - nrfx_saadc - SAADC peripheral driver +//========================================================== +#ifndef NRFX_SAADC_ENABLED +#define NRFX_SAADC_ENABLED 0 +#endif +// NRFX_SAADC_CONFIG_RESOLUTION - Resolution + +// <0=> 8 bit +// <1=> 10 bit +// <2=> 12 bit +// <3=> 14 bit + +#ifndef NRFX_SAADC_CONFIG_RESOLUTION +#define NRFX_SAADC_CONFIG_RESOLUTION 1 +#endif + +// NRFX_SAADC_CONFIG_OVERSAMPLE - Sample period + +// <0=> Disabled +// <1=> 2x +// <2=> 4x +// <3=> 8x +// <4=> 16x +// <5=> 32x +// <6=> 64x +// <7=> 128x +// <8=> 256x + +#ifndef NRFX_SAADC_CONFIG_OVERSAMPLE +#define NRFX_SAADC_CONFIG_OVERSAMPLE 0 +#endif + +// NRFX_SAADC_CONFIG_LP_MODE - Enabling low power mode + + +#ifndef NRFX_SAADC_CONFIG_LP_MODE +#define NRFX_SAADC_CONFIG_LP_MODE 0 +#endif + +// NRFX_SAADC_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_SAADC_CONFIG_IRQ_PRIORITY +#define NRFX_SAADC_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_SAADC_CONFIG_LOG_ENABLED +#define NRFX_SAADC_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_SAADC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_SAADC_CONFIG_LOG_LEVEL +#define NRFX_SAADC_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SAADC_CONFIG_INFO_COLOR +#define NRFX_SAADC_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SAADC_CONFIG_DEBUG_COLOR +#define NRFX_SAADC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_SPIM_ENABLED - nrfx_spim - SPIM peripheral driver +//========================================================== +#ifndef NRFX_SPIM_ENABLED +#define NRFX_SPIM_ENABLED 1 +#endif +// NRFX_SPIM0_ENABLED - Enable SPIM0 instance + + +#ifndef NRFX_SPIM0_ENABLED +#define NRFX_SPIM0_ENABLED 0 +#endif + +// NRFX_SPIM1_ENABLED - Enable SPIM1 instance + + +#ifndef NRFX_SPIM1_ENABLED +#define NRFX_SPIM1_ENABLED 0 +#endif + +// NRFX_SPIM2_ENABLED - Enable SPIM2 instance + + +#ifndef NRFX_SPIM2_ENABLED +#define NRFX_SPIM2_ENABLED 0 +#endif + +// NRFX_SPIM3_ENABLED - Enable SPIM3 instance + + +#ifndef NRFX_SPIM3_ENABLED +#define NRFX_SPIM3_ENABLED 0 +#endif + +// NRFX_SPIM_EXTENDED_ENABLED - Enable extended SPIM features + + +#ifndef NRFX_SPIM_EXTENDED_ENABLED +#define NRFX_SPIM_EXTENDED_ENABLED 0 +#endif + +// NRFX_SPIM_MISO_PULL_CFG - MISO pin pull configuration. + +// <0=> NRF_GPIO_PIN_NOPULL +// <1=> NRF_GPIO_PIN_PULLDOWN +// <3=> NRF_GPIO_PIN_PULLUP + +#ifndef NRFX_SPIM_MISO_PULL_CFG +#define NRFX_SPIM_MISO_PULL_CFG 1 +#endif + +// NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIM_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_SPIM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_SPIM_CONFIG_LOG_ENABLED +#define NRFX_SPIM_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_SPIM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_SPIM_CONFIG_LOG_LEVEL +#define NRFX_SPIM_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_SPIM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SPIM_CONFIG_INFO_COLOR +#define NRFX_SPIM_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_SPIM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SPIM_CONFIG_DEBUG_COLOR +#define NRFX_SPIM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_SPIS_ENABLED - nrfx_spis - SPIS peripheral driver +//========================================================== +#ifndef NRFX_SPIS_ENABLED +#define NRFX_SPIS_ENABLED 0 +#endif +// NRFX_SPIS0_ENABLED - Enable SPIS0 instance + + +#ifndef NRFX_SPIS0_ENABLED +#define NRFX_SPIS0_ENABLED 0 +#endif + +// NRFX_SPIS1_ENABLED - Enable SPIS1 instance + + +#ifndef NRFX_SPIS1_ENABLED +#define NRFX_SPIS1_ENABLED 0 +#endif + +// NRFX_SPIS2_ENABLED - Enable SPIS2 instance + + +#ifndef NRFX_SPIS2_ENABLED +#define NRFX_SPIS2_ENABLED 0 +#endif + +// NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_SPIS_DEFAULT_DEF - SPIS default DEF character <0-255> + + +#ifndef NRFX_SPIS_DEFAULT_DEF +#define NRFX_SPIS_DEFAULT_DEF 255 +#endif + +// NRFX_SPIS_DEFAULT_ORC - SPIS default ORC character <0-255> + + +#ifndef NRFX_SPIS_DEFAULT_ORC +#define NRFX_SPIS_DEFAULT_ORC 255 +#endif + +// NRFX_SPIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_SPIS_CONFIG_LOG_ENABLED +#define NRFX_SPIS_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_SPIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_SPIS_CONFIG_LOG_LEVEL +#define NRFX_SPIS_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_SPIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SPIS_CONFIG_INFO_COLOR +#define NRFX_SPIS_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_SPIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SPIS_CONFIG_DEBUG_COLOR +#define NRFX_SPIS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver +//========================================================== +#ifndef NRFX_SPI_ENABLED +#define NRFX_SPI_ENABLED 1 +#endif +// NRFX_SPI0_ENABLED - Enable SPI0 instance + + +#ifndef NRFX_SPI0_ENABLED +#define NRFX_SPI0_ENABLED 0 +#endif + +// NRFX_SPI1_ENABLED - Enable SPI1 instance + + +#ifndef NRFX_SPI1_ENABLED +#define NRFX_SPI1_ENABLED 0 +#endif + +// NRFX_SPI2_ENABLED - Enable SPI2 instance + + +#ifndef NRFX_SPI2_ENABLED +#define NRFX_SPI2_ENABLED 0 +#endif + +// NRFX_SPI_MISO_PULL_CFG - MISO pin pull configuration. + +// <0=> NRF_GPIO_PIN_NOPULL +// <1=> NRF_GPIO_PIN_PULLDOWN +// <3=> NRF_GPIO_PIN_PULLUP + +#ifndef NRFX_SPI_MISO_PULL_CFG +#define NRFX_SPI_MISO_PULL_CFG 1 +#endif + +// NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_SPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_SPI_CONFIG_LOG_ENABLED +#define NRFX_SPI_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_SPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_SPI_CONFIG_LOG_LEVEL +#define NRFX_SPI_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_SPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SPI_CONFIG_INFO_COLOR +#define NRFX_SPI_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_SPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SPI_CONFIG_DEBUG_COLOR +#define NRFX_SPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_SWI_ENABLED - nrfx_swi - SWI/EGU peripheral allocator +//========================================================== +#ifndef NRFX_SWI_ENABLED +#define NRFX_SWI_ENABLED 0 +#endif +// NRFX_EGU_ENABLED - Enable EGU support + + +#ifndef NRFX_EGU_ENABLED +#define NRFX_EGU_ENABLED 0 +#endif + +// NRFX_SWI0_DISABLED - Exclude SWI0 from being utilized by the driver + + +#ifndef NRFX_SWI0_DISABLED +#define NRFX_SWI0_DISABLED 0 +#endif + +// NRFX_SWI1_DISABLED - Exclude SWI1 from being utilized by the driver + + +#ifndef NRFX_SWI1_DISABLED +#define NRFX_SWI1_DISABLED 0 +#endif + +// NRFX_SWI2_DISABLED - Exclude SWI2 from being utilized by the driver + + +#ifndef NRFX_SWI2_DISABLED +#define NRFX_SWI2_DISABLED 0 +#endif + +// NRFX_SWI3_DISABLED - Exclude SWI3 from being utilized by the driver + + +#ifndef NRFX_SWI3_DISABLED +#define NRFX_SWI3_DISABLED 0 +#endif + +// NRFX_SWI4_DISABLED - Exclude SWI4 from being utilized by the driver + + +#ifndef NRFX_SWI4_DISABLED +#define NRFX_SWI4_DISABLED 0 +#endif + +// NRFX_SWI5_DISABLED - Exclude SWI5 from being utilized by the driver + + +#ifndef NRFX_SWI5_DISABLED +#define NRFX_SWI5_DISABLED 0 +#endif + +// NRFX_SWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_SWI_CONFIG_LOG_ENABLED +#define NRFX_SWI_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_SWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_SWI_CONFIG_LOG_LEVEL +#define NRFX_SWI_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_SWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SWI_CONFIG_INFO_COLOR +#define NRFX_SWI_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_SWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_SWI_CONFIG_DEBUG_COLOR +#define NRFX_SWI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_TIMER_ENABLED - nrfx_timer - TIMER periperal driver +//========================================================== +#ifndef NRFX_TIMER_ENABLED +#define NRFX_TIMER_ENABLED 0 +#endif +// NRFX_TIMER0_ENABLED - Enable TIMER0 instance + + +#ifndef NRFX_TIMER0_ENABLED +#define NRFX_TIMER0_ENABLED 0 +#endif + +// NRFX_TIMER1_ENABLED - Enable TIMER1 instance + + +#ifndef NRFX_TIMER1_ENABLED +#define NRFX_TIMER1_ENABLED 0 +#endif + +// NRFX_TIMER2_ENABLED - Enable TIMER2 instance + + +#ifndef NRFX_TIMER2_ENABLED +#define NRFX_TIMER2_ENABLED 0 +#endif + +// NRFX_TIMER3_ENABLED - Enable TIMER3 instance + + +#ifndef NRFX_TIMER3_ENABLED +#define NRFX_TIMER3_ENABLED 0 +#endif + +// NRFX_TIMER4_ENABLED - Enable TIMER4 instance + + +#ifndef NRFX_TIMER4_ENABLED +#define NRFX_TIMER4_ENABLED 0 +#endif + +// NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY - Timer frequency if in Timer mode + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 kHz +// <8=> 62.5 kHz +// <9=> 31.25 kHz + +#ifndef NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY +#define NRFX_TIMER_DEFAULT_CONFIG_FREQUENCY 0 +#endif + +// NRFX_TIMER_DEFAULT_CONFIG_MODE - Timer mode or operation + +// <0=> Timer +// <1=> Counter + +#ifndef NRFX_TIMER_DEFAULT_CONFIG_MODE +#define NRFX_TIMER_DEFAULT_CONFIG_MODE 0 +#endif + +// NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH - Timer counter bit width + +// <0=> 16 bit +// <1=> 8 bit +// <2=> 24 bit +// <3=> 32 bit + +#ifndef NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH +#define NRFX_TIMER_DEFAULT_CONFIG_BIT_WIDTH 0 +#endif + +// NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_TIMER_CONFIG_LOG_ENABLED +#define NRFX_TIMER_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_TIMER_CONFIG_LOG_LEVEL +#define NRFX_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TIMER_CONFIG_INFO_COLOR +#define NRFX_TIMER_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TIMER_CONFIG_DEBUG_COLOR +#define NRFX_TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_TWIM_ENABLED - nrfx_twim - TWIM peripheral driver +//========================================================== +#ifndef NRFX_TWIM_ENABLED +#define NRFX_TWIM_ENABLED 0 +#endif +// NRFX_TWIM0_ENABLED - Enable TWIM0 instance + + +#ifndef NRFX_TWIM0_ENABLED +#define NRFX_TWIM0_ENABLED 0 +#endif + +// NRFX_TWIM1_ENABLED - Enable TWIM1 instance + + +#ifndef NRFX_TWIM1_ENABLED +#define NRFX_TWIM1_ENABLED 0 +#endif + +// NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY - Frequency + +// <26738688=> 100k +// <67108864=> 250k +// <104857600=> 400k + +#ifndef NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY +#define NRFX_TWIM_DEFAULT_CONFIG_FREQUENCY 26738688 +#endif + +// NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit + + +#ifndef NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT +#define NRFX_TWIM_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 +#endif + +// NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIM_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_TWIM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_TWIM_CONFIG_LOG_ENABLED +#define NRFX_TWIM_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_TWIM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_TWIM_CONFIG_LOG_LEVEL +#define NRFX_TWIM_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_TWIM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TWIM_CONFIG_INFO_COLOR +#define NRFX_TWIM_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_TWIM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TWIM_CONFIG_DEBUG_COLOR +#define NRFX_TWIM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_TWIS_ENABLED - nrfx_twis - TWIS peripheral driver +//========================================================== +#ifndef NRFX_TWIS_ENABLED +#define NRFX_TWIS_ENABLED 0 +#endif +// NRFX_TWIS0_ENABLED - Enable TWIS0 instance + + +#ifndef NRFX_TWIS0_ENABLED +#define NRFX_TWIS0_ENABLED 0 +#endif + +// NRFX_TWIS1_ENABLED - Enable TWIS1 instance + + +#ifndef NRFX_TWIS1_ENABLED +#define NRFX_TWIS1_ENABLED 0 +#endif + +// NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once + + +// Optimization flag. Registers used by TWIS are shared by other peripherals. Normally, during initialization driver tries to clear all registers to known state before doing the initialization itself. This gives initialization safe procedure, no matter when it would be called. If you activate TWIS only once and do never uninitialize it - set this flag to 1 what gives more optimal code. + +#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +// NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode + + +// Synchronous mode would be used in specific situations. And it uses some additional code and data memory to safely process state machine by polling it in status functions. If this functionality is not required it may be disabled to free some resources. + +#ifndef NRFX_TWIS_NO_SYNC_MODE +#define NRFX_TWIS_NO_SYNC_MODE 0 +#endif + +// NRFX_TWIS_DEFAULT_CONFIG_ADDR0 - Address0 +#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR0 +#define NRFX_TWIS_DEFAULT_CONFIG_ADDR0 0 +#endif + +// NRFX_TWIS_DEFAULT_CONFIG_ADDR1 - Address1 +#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR1 +#define NRFX_TWIS_DEFAULT_CONFIG_ADDR1 0 +#endif + +// NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL - SCL pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL +#define NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL 0 +#endif + +// NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL - SDA pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL +#define NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL 0 +#endif + +// NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_TWIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_TWIS_CONFIG_LOG_ENABLED +#define NRFX_TWIS_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_TWIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_TWIS_CONFIG_LOG_LEVEL +#define NRFX_TWIS_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_TWIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TWIS_CONFIG_INFO_COLOR +#define NRFX_TWIS_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_TWIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TWIS_CONFIG_DEBUG_COLOR +#define NRFX_TWIS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_TWI_ENABLED - nrfx_twi - TWI peripheral driver +//========================================================== +#ifndef NRFX_TWI_ENABLED +#define NRFX_TWI_ENABLED 0 +#endif +// NRFX_TWI0_ENABLED - Enable TWI0 instance + + +#ifndef NRFX_TWI0_ENABLED +#define NRFX_TWI0_ENABLED 0 +#endif + +// NRFX_TWI1_ENABLED - Enable TWI1 instance + + +#ifndef NRFX_TWI1_ENABLED +#define NRFX_TWI1_ENABLED 0 +#endif + +// NRFX_TWI_DEFAULT_CONFIG_FREQUENCY - Frequency + +// <26738688=> 100k +// <67108864=> 250k +// <104857600=> 400k + +#ifndef NRFX_TWI_DEFAULT_CONFIG_FREQUENCY +#define NRFX_TWI_DEFAULT_CONFIG_FREQUENCY 26738688 +#endif + +// NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit + + +#ifndef NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT +#define NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 +#endif + +// NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_TWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_TWI_CONFIG_LOG_ENABLED +#define NRFX_TWI_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_TWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_TWI_CONFIG_LOG_LEVEL +#define NRFX_TWI_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TWI_CONFIG_INFO_COLOR +#define NRFX_TWI_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_TWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_TWI_CONFIG_DEBUG_COLOR +#define NRFX_TWI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_UARTE_ENABLED - nrfx_uarte - UARTE peripheral driver +//========================================================== +#ifndef NRFX_UARTE_ENABLED +#define NRFX_UARTE_ENABLED 1 +#endif +// NRFX_UARTE0_ENABLED - Enable UARTE0 instance +#ifndef NRFX_UARTE0_ENABLED +#define NRFX_UARTE0_ENABLED 0 +#endif + +// NRFX_UARTE1_ENABLED - Enable UARTE1 instance +#ifndef NRFX_UARTE1_ENABLED +#define NRFX_UARTE1_ENABLED 0 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_HWFC +#define NRFX_UARTE_DEFAULT_CONFIG_HWFC 0 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_PARITY +#define NRFX_UARTE_DEFAULT_CONFIG_PARITY 0 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <8388608=> 31250 baud +// <10289152=> 38400 baud +// <15007744=> 56000 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE +#define NRFX_UARTE_DEFAULT_CONFIG_BAUDRATE 30801920 +#endif + +// NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_UARTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_UARTE_CONFIG_LOG_ENABLED +#define NRFX_UARTE_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_UARTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_UARTE_CONFIG_LOG_LEVEL +#define NRFX_UARTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_UARTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UARTE_CONFIG_INFO_COLOR +#define NRFX_UARTE_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_UARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UARTE_CONFIG_DEBUG_COLOR +#define NRFX_UARTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_UART_ENABLED - nrfx_uart - UART peripheral driver +//========================================================== +#ifndef NRFX_UART_ENABLED +#define NRFX_UART_ENABLED 1 +#endif +// NRFX_UART0_ENABLED - Enable UART0 instance +#ifndef NRFX_UART0_ENABLED +#define NRFX_UART0_ENABLED 0 +#endif + +// NRFX_UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef NRFX_UART_DEFAULT_CONFIG_HWFC +#define NRFX_UART_DEFAULT_CONFIG_HWFC 0 +#endif + +// NRFX_UART_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef NRFX_UART_DEFAULT_CONFIG_PARITY +#define NRFX_UART_DEFAULT_CONFIG_PARITY 0 +#endif + +// NRFX_UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3866624=> 14400 baud +// <5152768=> 19200 baud +// <7729152=> 28800 baud +// <8388608=> 31250 baud +// <10309632=> 38400 baud +// <15007744=> 56000 baud +// <15462400=> 57600 baud +// <20615168=> 76800 baud +// <30924800=> 115200 baud +// <61845504=> 230400 baud +// <67108864=> 250000 baud +// <123695104=> 460800 baud +// <247386112=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef NRFX_UART_DEFAULT_CONFIG_BAUDRATE +#define NRFX_UART_DEFAULT_CONFIG_BAUDRATE 30924800 +#endif + +// NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY +#define NRFX_UART_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_UART_CONFIG_LOG_ENABLED +#define NRFX_UART_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_UART_CONFIG_LOG_LEVEL +#define NRFX_UART_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UART_CONFIG_INFO_COLOR +#define NRFX_UART_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_UART_CONFIG_DEBUG_COLOR +#define NRFX_UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRFX_USBD_ENABLED - nrfx_usbd - USBD peripheral driver +//========================================================== +#ifndef NRFX_USBD_ENABLED +#define NRFX_USBD_ENABLED 0 +#endif +// NRFX_USBD_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_USBD_CONFIG_IRQ_PRIORITY +#define NRFX_USBD_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_USBD_CONFIG_DMASCHEDULER_MODE - USBD DMA scheduler working scheme + +// <0=> Prioritized access +// <1=> Round Robin + +#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_MODE +#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE 0 +#endif + +// NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers + + +// This option gives priority to isochronous transfers. +// Enabling it assures that isochronous transfers are always processed, +// even if multiple other transfers are pending. +// Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm +// function is called, so the option is independent of the algorithm chosen. + +#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST +#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1 +#endif + +// NRFX_USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready + + +// If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent. +// Else, there will be no response. + +#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP +#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0 +#endif + +// NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 - Use workaround for anomaly 211 + + +// If set, workaround for anomaly 211 will be enabled. +// Anomaly 211 - Device remains in SUSPEND too long when host resumes +// bus activity (sending SOF packets) without a RESUME condition. + +#ifndef NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 +#define NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 0 +#endif + +// + +// NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver +//========================================================== +#ifndef NRFX_WDT_ENABLED +#define NRFX_WDT_ENABLED 0 +#endif +// NRFX_WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode + +// <1=> Run in SLEEP, Pause in HALT +// <8=> Pause in SLEEP, Run in HALT +// <9=> Run in SLEEP and HALT +// <0=> Pause in SLEEP and HALT + +#ifndef NRFX_WDT_CONFIG_BEHAVIOUR +#define NRFX_WDT_CONFIG_BEHAVIOUR 1 +#endif + +// NRFX_WDT_CONFIG_RELOAD_VALUE - Reload value in ms <1-131072000> + + +#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE +#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000 +#endif + +// NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver + +// <0=> Include WDT IRQ handling +// <1=> Remove WDT IRQ handling + +#ifndef NRFX_WDT_CONFIG_NO_IRQ +#define NRFX_WDT_CONFIG_NO_IRQ 0 +#endif + +// NRFX_WDT_CONFIG_IRQ_PRIORITY - Interrupt priority + +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef NRFX_WDT_CONFIG_IRQ_PRIORITY +#define NRFX_WDT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRFX_WDT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRFX_WDT_CONFIG_LOG_ENABLED +#define NRFX_WDT_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_WDT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_WDT_CONFIG_LOG_LEVEL +#define NRFX_WDT_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_WDT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_WDT_CONFIG_INFO_COLOR +#define NRFX_WDT_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_WDT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_WDT_CONFIG_DEBUG_COLOR +#define NRFX_WDT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// + +// NRF_CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver - legacy layer +//========================================================== +#ifndef NRF_CLOCK_ENABLED +#define NRF_CLOCK_ENABLED 1 +#endif +// CLOCK_CONFIG_LF_SRC - LF Clock Source + +// <0=> RC +// <1=> XTAL +// <2=> Synth +// <131073=> External Low Swing +// <196609=> External Full Swing + +#ifndef CLOCK_CONFIG_LF_SRC +#define CLOCK_CONFIG_LF_SRC 1 +#endif + +// CLOCK_CONFIG_LF_CAL_ENABLED - Calibration enable for LF Clock Source + + +#ifndef CLOCK_CONFIG_LF_CAL_ENABLED +#define CLOCK_CONFIG_LF_CAL_ENABLED 0 +#endif + +// CLOCK_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef CLOCK_CONFIG_IRQ_PRIORITY +#define CLOCK_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// PDM_ENABLED - nrf_drv_pdm - PDM peripheral driver - legacy layer +//========================================================== +#ifndef PDM_ENABLED +#define PDM_ENABLED 0 +#endif +// PDM_CONFIG_MODE - Mode + +// <0=> Stereo +// <1=> Mono + +#ifndef PDM_CONFIG_MODE +#define PDM_CONFIG_MODE 1 +#endif + +// PDM_CONFIG_EDGE - Edge + +// <0=> Left falling +// <1=> Left rising + +#ifndef PDM_CONFIG_EDGE +#define PDM_CONFIG_EDGE 0 +#endif + +// PDM_CONFIG_CLOCK_FREQ - Clock frequency + +// <134217728=> 1000k +// <138412032=> 1032k (default) +// <142606336=> 1067k + +#ifndef PDM_CONFIG_CLOCK_FREQ +#define PDM_CONFIG_CLOCK_FREQ 138412032 +#endif + +// PDM_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef PDM_CONFIG_IRQ_PRIORITY +#define PDM_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// POWER_ENABLED - nrf_drv_power - POWER peripheral driver - legacy layer +//========================================================== +#ifndef POWER_ENABLED +#define POWER_ENABLED 0 +#endif +// POWER_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef POWER_CONFIG_IRQ_PRIORITY +#define POWER_CONFIG_IRQ_PRIORITY 6 +#endif + +// POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef POWER_CONFIG_DEFAULT_DCDCEN +#define POWER_CONFIG_DEFAULT_DCDCEN 0 +#endif + +// POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef POWER_CONFIG_DEFAULT_DCDCENHV +#define POWER_CONFIG_DEFAULT_DCDCENHV 0 +#endif + +// + +// PPI_ENABLED - nrf_drv_ppi - PPI peripheral driver - legacy layer + + +#ifndef PPI_ENABLED +#define PPI_ENABLED 0 +#endif + +// PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver - legacy layer +//========================================================== +#ifndef PWM_ENABLED +#define PWM_ENABLED 0 +#endif +// PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT0_PIN +#define PWM_DEFAULT_CONFIG_OUT0_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT1_PIN +#define PWM_DEFAULT_CONFIG_OUT1_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT2_PIN +#define PWM_DEFAULT_CONFIG_OUT2_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT3_PIN +#define PWM_DEFAULT_CONFIG_OUT3_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_BASE_CLOCK - Base clock + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 kHz + +#ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK +#define PWM_DEFAULT_CONFIG_BASE_CLOCK 4 +#endif + +// PWM_DEFAULT_CONFIG_COUNT_MODE - Count mode + +// <0=> Up +// <1=> Up and Down + +#ifndef PWM_DEFAULT_CONFIG_COUNT_MODE +#define PWM_DEFAULT_CONFIG_COUNT_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_TOP_VALUE - Top value +#ifndef PWM_DEFAULT_CONFIG_TOP_VALUE +#define PWM_DEFAULT_CONFIG_TOP_VALUE 1000 +#endif + +// PWM_DEFAULT_CONFIG_LOAD_MODE - Load mode + +// <0=> Common +// <1=> Grouped +// <2=> Individual +// <3=> Waveform + +#ifndef PWM_DEFAULT_CONFIG_LOAD_MODE +#define PWM_DEFAULT_CONFIG_LOAD_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_STEP_MODE - Step mode + +// <0=> Auto +// <1=> Triggered + +#ifndef PWM_DEFAULT_CONFIG_STEP_MODE +#define PWM_DEFAULT_CONFIG_STEP_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// PWM0_ENABLED - Enable PWM0 instance + + +#ifndef PWM0_ENABLED +#define PWM0_ENABLED 0 +#endif + +// PWM1_ENABLED - Enable PWM1 instance + + +#ifndef PWM1_ENABLED +#define PWM1_ENABLED 0 +#endif + +// PWM2_ENABLED - Enable PWM2 instance + + +#ifndef PWM2_ENABLED +#define PWM2_ENABLED 0 +#endif + +// PWM3_ENABLED - Enable PWM3 instance + + +#ifndef PWM3_ENABLED +#define PWM3_ENABLED 0 +#endif + +// + +// QDEC_ENABLED - nrf_drv_qdec - QDEC peripheral driver - legacy layer +//========================================================== +#ifndef QDEC_ENABLED +#define QDEC_ENABLED 0 +#endif +// QDEC_CONFIG_REPORTPER - Report period + +// <0=> 10 Samples +// <1=> 40 Samples +// <2=> 80 Samples +// <3=> 120 Samples +// <4=> 160 Samples +// <5=> 200 Samples +// <6=> 240 Samples +// <7=> 280 Samples + +#ifndef QDEC_CONFIG_REPORTPER +#define QDEC_CONFIG_REPORTPER 0 +#endif + +// QDEC_CONFIG_SAMPLEPER - Sample period + +// <0=> 128 us +// <1=> 256 us +// <2=> 512 us +// <3=> 1024 us +// <4=> 2048 us +// <5=> 4096 us +// <6=> 8192 us +// <7=> 16384 us + +#ifndef QDEC_CONFIG_SAMPLEPER +#define QDEC_CONFIG_SAMPLEPER 7 +#endif + +// QDEC_CONFIG_PIO_A - A pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_A +#define QDEC_CONFIG_PIO_A 31 +#endif + +// QDEC_CONFIG_PIO_B - B pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_B +#define QDEC_CONFIG_PIO_B 31 +#endif + +// QDEC_CONFIG_PIO_LED - LED pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_LED +#define QDEC_CONFIG_PIO_LED 31 +#endif + +// QDEC_CONFIG_LEDPRE - LED pre +#ifndef QDEC_CONFIG_LEDPRE +#define QDEC_CONFIG_LEDPRE 511 +#endif + +// QDEC_CONFIG_LEDPOL - LED polarity + +// <0=> Active low +// <1=> Active high + +#ifndef QDEC_CONFIG_LEDPOL +#define QDEC_CONFIG_LEDPOL 1 +#endif + +// QDEC_CONFIG_DBFEN - Debouncing enable + + +#ifndef QDEC_CONFIG_DBFEN +#define QDEC_CONFIG_DBFEN 0 +#endif + +// QDEC_CONFIG_SAMPLE_INTEN - Sample ready interrupt enable + + +#ifndef QDEC_CONFIG_SAMPLE_INTEN +#define QDEC_CONFIG_SAMPLE_INTEN 0 +#endif + +// QDEC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef QDEC_CONFIG_IRQ_PRIORITY +#define QDEC_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver - legacy layer +//========================================================== +#ifndef QSPI_ENABLED +#define QSPI_ENABLED 0 +#endif +// QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns). <0-255> + + +#ifndef QSPI_CONFIG_SCK_DELAY +#define QSPI_CONFIG_SCK_DELAY 1 +#endif + +// QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. +#ifndef QSPI_CONFIG_XIP_OFFSET +#define QSPI_CONFIG_XIP_OFFSET 0 +#endif + +// QSPI_CONFIG_READOC - Number of data lines and opcode used for reading. + +// <0=> FastRead +// <1=> Read2O +// <2=> Read2IO +// <3=> Read4O +// <4=> Read4IO + +#ifndef QSPI_CONFIG_READOC +#define QSPI_CONFIG_READOC 0 +#endif + +// QSPI_CONFIG_WRITEOC - Number of data lines and opcode used for writing. + +// <0=> PP +// <1=> PP2O +// <2=> PP4O +// <3=> PP4IO + +#ifndef QSPI_CONFIG_WRITEOC +#define QSPI_CONFIG_WRITEOC 0 +#endif + +// QSPI_CONFIG_ADDRMODE - Addressing mode. + +// <0=> 24bit +// <1=> 32bit + +#ifndef QSPI_CONFIG_ADDRMODE +#define QSPI_CONFIG_ADDRMODE 0 +#endif + +// QSPI_CONFIG_MODE - SPI mode. + +// <0=> Mode 0 +// <1=> Mode 1 + +#ifndef QSPI_CONFIG_MODE +#define QSPI_CONFIG_MODE 0 +#endif + +// QSPI_CONFIG_FREQUENCY - Frequency divider. + +// <0=> 32MHz/1 +// <1=> 32MHz/2 +// <2=> 32MHz/3 +// <3=> 32MHz/4 +// <4=> 32MHz/5 +// <5=> 32MHz/6 +// <6=> 32MHz/7 +// <7=> 32MHz/8 +// <8=> 32MHz/9 +// <9=> 32MHz/10 +// <10=> 32MHz/11 +// <11=> 32MHz/12 +// <12=> 32MHz/13 +// <13=> 32MHz/14 +// <14=> 32MHz/15 +// <15=> 32MHz/16 + +#ifndef QSPI_CONFIG_FREQUENCY +#define QSPI_CONFIG_FREQUENCY 15 +#endif + +// QSPI_PIN_SCK - SCK pin value. +#ifndef QSPI_PIN_SCK +#define QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// QSPI_PIN_CSN - CSN pin value. +#ifndef QSPI_PIN_CSN +#define QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// QSPI_PIN_IO0 - IO0 pin value. +#ifndef QSPI_PIN_IO0 +#define QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// QSPI_PIN_IO1 - IO1 pin value. +#ifndef QSPI_PIN_IO1 +#define QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// QSPI_PIN_IO2 - IO2 pin value. +#ifndef QSPI_PIN_IO2 +#define QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// QSPI_PIN_IO3 - IO3 pin value. +#ifndef QSPI_PIN_IO3 +#define QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED +#endif + +// QSPI_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef QSPI_CONFIG_IRQ_PRIORITY +#define QSPI_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// RNG_ENABLED - nrf_drv_rng - RNG peripheral driver - legacy layer +//========================================================== +#ifndef RNG_ENABLED +#define RNG_ENABLED 1 +#endif +// RNG_CONFIG_ERROR_CORRECTION - Error correction + + +#ifndef RNG_CONFIG_ERROR_CORRECTION +#define RNG_CONFIG_ERROR_CORRECTION 1 +#endif + +// RNG_CONFIG_POOL_SIZE - Pool size +#ifndef RNG_CONFIG_POOL_SIZE +#define RNG_CONFIG_POOL_SIZE 64 +#endif + +// RNG_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef RNG_CONFIG_IRQ_PRIORITY +#define RNG_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver - legacy layer +//========================================================== +#ifndef RTC_ENABLED +#define RTC_ENABLED 0 +#endif +// RTC_DEFAULT_CONFIG_FREQUENCY - Frequency <16-32768> + + +#ifndef RTC_DEFAULT_CONFIG_FREQUENCY +#define RTC_DEFAULT_CONFIG_FREQUENCY 32768 +#endif + +// RTC_DEFAULT_CONFIG_RELIABLE - Ensures safe compare event triggering + + +#ifndef RTC_DEFAULT_CONFIG_RELIABLE +#define RTC_DEFAULT_CONFIG_RELIABLE 0 +#endif + +// RTC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define RTC_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// RTC0_ENABLED - Enable RTC0 instance + + +#ifndef RTC0_ENABLED +#define RTC0_ENABLED 0 +#endif + +// RTC1_ENABLED - Enable RTC1 instance + + +#ifndef RTC1_ENABLED +#define RTC1_ENABLED 0 +#endif + +// RTC2_ENABLED - Enable RTC2 instance + + +#ifndef RTC2_ENABLED +#define RTC2_ENABLED 0 +#endif + +// NRF_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt +#ifndef NRF_MAXIMUM_LATENCY_US +#define NRF_MAXIMUM_LATENCY_US 2000 +#endif + +// + +// SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver - legacy layer +//========================================================== +#ifndef SAADC_ENABLED +#define SAADC_ENABLED 0 +#endif +// SAADC_CONFIG_RESOLUTION - Resolution + +// <0=> 8 bit +// <1=> 10 bit +// <2=> 12 bit +// <3=> 14 bit + +#ifndef SAADC_CONFIG_RESOLUTION +#define SAADC_CONFIG_RESOLUTION 1 +#endif + +// SAADC_CONFIG_OVERSAMPLE - Sample period + +// <0=> Disabled +// <1=> 2x +// <2=> 4x +// <3=> 8x +// <4=> 16x +// <5=> 32x +// <6=> 64x +// <7=> 128x +// <8=> 256x + +#ifndef SAADC_CONFIG_OVERSAMPLE +#define SAADC_CONFIG_OVERSAMPLE 0 +#endif + +// SAADC_CONFIG_LP_MODE - Enabling low power mode + + +#ifndef SAADC_CONFIG_LP_MODE +#define SAADC_CONFIG_LP_MODE 0 +#endif + +// SAADC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef SAADC_CONFIG_IRQ_PRIORITY +#define SAADC_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// SPIS_ENABLED - nrf_drv_spis - SPIS peripheral driver - legacy layer +//========================================================== +#ifndef SPIS_ENABLED +#define SPIS_ENABLED 0 +#endif +// SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// SPIS_DEFAULT_MODE - Mode + +// <0=> MODE_0 +// <1=> MODE_1 +// <2=> MODE_2 +// <3=> MODE_3 + +#ifndef SPIS_DEFAULT_MODE +#define SPIS_DEFAULT_MODE 0 +#endif + +// SPIS_DEFAULT_BIT_ORDER - SPIS default bit order + +// <0=> MSB first +// <1=> LSB first + +#ifndef SPIS_DEFAULT_BIT_ORDER +#define SPIS_DEFAULT_BIT_ORDER 0 +#endif + +// SPIS_DEFAULT_DEF - SPIS default DEF character <0-255> + + +#ifndef SPIS_DEFAULT_DEF +#define SPIS_DEFAULT_DEF 255 +#endif + +// SPIS_DEFAULT_ORC - SPIS default ORC character <0-255> + + +#ifndef SPIS_DEFAULT_ORC +#define SPIS_DEFAULT_ORC 255 +#endif + +// SPIS0_ENABLED - Enable SPIS0 instance + + +#ifndef SPIS0_ENABLED +#define SPIS0_ENABLED 0 +#endif + +// SPIS1_ENABLED - Enable SPIS1 instance + + +#ifndef SPIS1_ENABLED +#define SPIS1_ENABLED 0 +#endif + +// SPIS2_ENABLED - Enable SPIS2 instance + + +#ifndef SPIS2_ENABLED +#define SPIS2_ENABLED 0 +#endif + +// + +// SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver - legacy layer +//========================================================== +#ifndef SPI_ENABLED +#define SPI_ENABLED 1 +#endif +// SPI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY +#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// NRF_SPI_DRV_MISO_PULLUP_CFG - MISO PIN pull-up configuration. + +// <0=> NRF_GPIO_PIN_NOPULL +// <1=> NRF_GPIO_PIN_PULLDOWN +// <3=> NRF_GPIO_PIN_PULLUP + +#ifndef NRF_SPI_DRV_MISO_PULLUP_CFG +#define NRF_SPI_DRV_MISO_PULLUP_CFG 1 +#endif + +// SPI0_ENABLED - Enable SPI0 instance +//========================================================== +#ifndef SPI0_ENABLED +#define SPI0_ENABLED 1 +#endif +// SPI0_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI0_USE_EASY_DMA +#define SPI0_USE_EASY_DMA 1 +#endif + +// + +// SPI1_ENABLED - Enable SPI1 instance +//========================================================== +#ifndef SPI1_ENABLED +#define SPI1_ENABLED 0 +#endif +// SPI1_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI1_USE_EASY_DMA +#define SPI1_USE_EASY_DMA 1 +#endif + +// + +// SPI2_ENABLED - Enable SPI2 instance +//========================================================== +#ifndef SPI2_ENABLED +#define SPI2_ENABLED 0 +#endif +// SPI2_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI2_USE_EASY_DMA +#define SPI2_USE_EASY_DMA 1 +#endif + +// + +// + +// TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver - legacy layer +//========================================================== +#ifndef TIMER_ENABLED +#define TIMER_ENABLED 0 +#endif +// TIMER_DEFAULT_CONFIG_FREQUENCY - Timer frequency if in Timer mode + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 kHz +// <8=> 62.5 kHz +// <9=> 31.25 kHz + +#ifndef TIMER_DEFAULT_CONFIG_FREQUENCY +#define TIMER_DEFAULT_CONFIG_FREQUENCY 0 +#endif + +// TIMER_DEFAULT_CONFIG_MODE - Timer mode or operation + +// <0=> Timer +// <1=> Counter + +#ifndef TIMER_DEFAULT_CONFIG_MODE +#define TIMER_DEFAULT_CONFIG_MODE 0 +#endif + +// TIMER_DEFAULT_CONFIG_BIT_WIDTH - Timer counter bit width + +// <0=> 16 bit +// <1=> 8 bit +// <2=> 24 bit +// <3=> 32 bit + +#ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH +#define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0 +#endif + +// TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// TIMER0_ENABLED - Enable TIMER0 instance + + +#ifndef TIMER0_ENABLED +#define TIMER0_ENABLED 0 +#endif + +// TIMER1_ENABLED - Enable TIMER1 instance + + +#ifndef TIMER1_ENABLED +#define TIMER1_ENABLED 0 +#endif + +// TIMER2_ENABLED - Enable TIMER2 instance + + +#ifndef TIMER2_ENABLED +#define TIMER2_ENABLED 0 +#endif + +// TIMER3_ENABLED - Enable TIMER3 instance + + +#ifndef TIMER3_ENABLED +#define TIMER3_ENABLED 0 +#endif + +// TIMER4_ENABLED - Enable TIMER4 instance + + +#ifndef TIMER4_ENABLED +#define TIMER4_ENABLED 0 +#endif + +// + +// TWIS_ENABLED - nrf_drv_twis - TWIS peripheral driver - legacy layer +//========================================================== +#ifndef TWIS_ENABLED +#define TWIS_ENABLED 0 +#endif +// TWIS0_ENABLED - Enable TWIS0 instance + + +#ifndef TWIS0_ENABLED +#define TWIS0_ENABLED 0 +#endif + +// TWIS1_ENABLED - Enable TWIS1 instance + + +#ifndef TWIS1_ENABLED +#define TWIS1_ENABLED 0 +#endif + +// TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once + + +// Optimization flag. Registers used by TWIS are shared by other peripherals. Normally, during initialization driver tries to clear all registers to known state before doing the initialization itself. This gives initialization safe procedure, no matter when it would be called. If you activate TWIS only once and do never uninitialize it - set this flag to 1 what gives more optimal code. + +#ifndef TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +// TWIS_NO_SYNC_MODE - Remove support for synchronous mode + + +// Synchronous mode would be used in specific situations. And it uses some additional code and data memory to safely process state machine by polling it in status functions. If this functionality is not required it may be disabled to free some resources. + +#ifndef TWIS_NO_SYNC_MODE +#define TWIS_NO_SYNC_MODE 0 +#endif + +// TWIS_DEFAULT_CONFIG_ADDR0 - Address0 +#ifndef TWIS_DEFAULT_CONFIG_ADDR0 +#define TWIS_DEFAULT_CONFIG_ADDR0 0 +#endif + +// TWIS_DEFAULT_CONFIG_ADDR1 - Address1 +#ifndef TWIS_DEFAULT_CONFIG_ADDR1 +#define TWIS_DEFAULT_CONFIG_ADDR1 0 +#endif + +// TWIS_DEFAULT_CONFIG_SCL_PULL - SCL pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef TWIS_DEFAULT_CONFIG_SCL_PULL +#define TWIS_DEFAULT_CONFIG_SCL_PULL 0 +#endif + +// TWIS_DEFAULT_CONFIG_SDA_PULL - SDA pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef TWIS_DEFAULT_CONFIG_SDA_PULL +#define TWIS_DEFAULT_CONFIG_SDA_PULL 0 +#endif + +// TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver - legacy layer +//========================================================== +#ifndef TWI_ENABLED +#define TWI_ENABLED 0 +#endif +// TWI_DEFAULT_CONFIG_FREQUENCY - Frequency + +// <26738688=> 100k +// <67108864=> 250k +// <104857600=> 400k + +#ifndef TWI_DEFAULT_CONFIG_FREQUENCY +#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688 +#endif + +// TWI_DEFAULT_CONFIG_CLR_BUS_INIT - Enables bus clearing procedure during init + + +#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT +#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0 +#endif + +// TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit + + +#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT +#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 +#endif + +// TWI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY +#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// TWI0_ENABLED - Enable TWI0 instance +//========================================================== +#ifndef TWI0_ENABLED +#define TWI0_ENABLED 0 +#endif +// TWI0_USE_EASY_DMA - Use EasyDMA (if present) + + +#ifndef TWI0_USE_EASY_DMA +#define TWI0_USE_EASY_DMA 0 +#endif + +// + +// TWI1_ENABLED - Enable TWI1 instance +//========================================================== +#ifndef TWI1_ENABLED +#define TWI1_ENABLED 0 +#endif +// TWI1_USE_EASY_DMA - Use EasyDMA (if present) + + +#ifndef TWI1_USE_EASY_DMA +#define TWI1_USE_EASY_DMA 0 +#endif + +// + +// + +// UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer +//========================================================== +#ifndef UART_ENABLED +#define UART_ENABLED 1 +#endif +// UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef UART_DEFAULT_CONFIG_HWFC +#define UART_DEFAULT_CONFIG_HWFC 0 +#endif + +// UART_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef UART_DEFAULT_CONFIG_PARITY +#define UART_DEFAULT_CONFIG_PARITY 0 +#endif + +// UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef UART_DEFAULT_CONFIG_BAUDRATE +#define UART_DEFAULT_CONFIG_BAUDRATE 30801920 +#endif + +// UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY +#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 6 +#endif + +// UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA + + +#ifndef UART_EASY_DMA_SUPPORT +#define UART_EASY_DMA_SUPPORT 1 +#endif + +// UART_LEGACY_SUPPORT - Driver supporting Legacy mode + + +#ifndef UART_LEGACY_SUPPORT +#define UART_LEGACY_SUPPORT 1 +#endif + +// UART0_ENABLED - Enable UART0 instance +//========================================================== +#ifndef UART0_ENABLED +#define UART0_ENABLED 1 +#endif +// UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA + + +#ifndef UART0_CONFIG_USE_EASY_DMA +#define UART0_CONFIG_USE_EASY_DMA 1 +#endif + +// + +// UART1_ENABLED - Enable UART1 instance +//========================================================== +#ifndef UART1_ENABLED +#define UART1_ENABLED 0 +#endif +// + +// + +// USBD_ENABLED - nrf_drv_usbd - Software Component +//========================================================== +#ifndef USBD_ENABLED +#define USBD_ENABLED 0 +#endif +// USBD_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef USBD_CONFIG_IRQ_PRIORITY +#define USBD_CONFIG_IRQ_PRIORITY 6 +#endif + +// USBD_CONFIG_DMASCHEDULER_MODE - USBD SMA scheduler working scheme + +// <0=> Prioritized access +// <1=> Round Robin + +#ifndef USBD_CONFIG_DMASCHEDULER_MODE +#define USBD_CONFIG_DMASCHEDULER_MODE 0 +#endif + +// USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers + + +// This option gives priority to isochronous transfers. +// Enabling it assures that isochronous transfers are always processed, +// even if multiple other transfers are pending. +// Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm +// function is called, so the option is independent of the algorithm chosen. + +#ifndef USBD_CONFIG_DMASCHEDULER_ISO_BOOST +#define USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1 +#endif + +// USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready + + +// If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent. +// Else, there will be no response. +// NOTE: This option does not work on Engineering A chip. + +#ifndef USBD_CONFIG_ISO_IN_ZLP +#define USBD_CONFIG_ISO_IN_ZLP 0 +#endif + +// + +// WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver - legacy layer +//========================================================== +#ifndef WDT_ENABLED +#define WDT_ENABLED 0 +#endif +// WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode + +// <1=> Run in SLEEP, Pause in HALT +// <8=> Pause in SLEEP, Run in HALT +// <9=> Run in SLEEP and HALT +// <0=> Pause in SLEEP and HALT + +#ifndef WDT_CONFIG_BEHAVIOUR +#define WDT_CONFIG_BEHAVIOUR 1 +#endif + +// WDT_CONFIG_RELOAD_VALUE - Reload value <15-4294967295> + + +#ifndef WDT_CONFIG_RELOAD_VALUE +#define WDT_CONFIG_RELOAD_VALUE 2000 +#endif + +// WDT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef WDT_CONFIG_IRQ_PRIORITY +#define WDT_CONFIG_IRQ_PRIORITY 6 +#endif + +// + +// +//========================================================== + +// nRF_Drivers_External + +//========================================================== +// NRF_TWI_SENSOR_ENABLED - nrf_twi_sensor - nRF TWI Sensor module + + +#ifndef NRF_TWI_SENSOR_ENABLED +#define NRF_TWI_SENSOR_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_Libraries + +//========================================================== +// APP_FIFO_ENABLED - app_fifo - Software FIFO implementation + + +#ifndef APP_FIFO_ENABLED +#define APP_FIFO_ENABLED 1 +#endif + +// APP_GPIOTE_ENABLED - app_gpiote - GPIOTE events dispatcher + + +#ifndef APP_GPIOTE_ENABLED +#define APP_GPIOTE_ENABLED 0 +#endif + +// APP_PWM_ENABLED - app_pwm - PWM functionality + + +#ifndef APP_PWM_ENABLED +#define APP_PWM_ENABLED 0 +#endif + +// APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler +//========================================================== +#ifndef APP_SCHEDULER_ENABLED +#define APP_SCHEDULER_ENABLED 1 +#endif +// APP_SCHEDULER_WITH_PAUSE - Enabling pause feature + + +#ifndef APP_SCHEDULER_WITH_PAUSE +#define APP_SCHEDULER_WITH_PAUSE 0 +#endif + +// APP_SCHEDULER_WITH_PROFILER - Enabling scheduler profiling + + +#ifndef APP_SCHEDULER_WITH_PROFILER +#define APP_SCHEDULER_WITH_PROFILER 0 +#endif + +// + +// APP_SDCARD_ENABLED - app_sdcard - SD/MMC card support using SPI +//========================================================== +#ifndef APP_SDCARD_ENABLED +#define APP_SDCARD_ENABLED 0 +#endif +// APP_SDCARD_SPI_INSTANCE - SPI instance used + +// <0=> 0 +// <1=> 1 +// <2=> 2 + +#ifndef APP_SDCARD_SPI_INSTANCE +#define APP_SDCARD_SPI_INSTANCE 0 +#endif + +// APP_SDCARD_FREQ_INIT - SPI frequency + +// <33554432=> 125 kHz +// <67108864=> 250 kHz +// <134217728=> 500 kHz +// <268435456=> 1 MHz +// <536870912=> 2 MHz +// <1073741824=> 4 MHz +// <2147483648=> 8 MHz + +#ifndef APP_SDCARD_FREQ_INIT +#define APP_SDCARD_FREQ_INIT 67108864 +#endif + +// APP_SDCARD_FREQ_DATA - SPI frequency + +// <33554432=> 125 kHz +// <67108864=> 250 kHz +// <134217728=> 500 kHz +// <268435456=> 1 MHz +// <536870912=> 2 MHz +// <1073741824=> 4 MHz +// <2147483648=> 8 MHz + +#ifndef APP_SDCARD_FREQ_DATA +#define APP_SDCARD_FREQ_DATA 1073741824 +#endif + +// + +// APP_TIMER_ENABLED - app_timer - Application timer functionality +//========================================================== +#ifndef APP_TIMER_ENABLED +#define APP_TIMER_ENABLED 1 +#endif +// APP_TIMER_CONFIG_RTC_FREQUENCY - Configure RTC prescaler. + +// <0=> 32768 Hz +// <1=> 16384 Hz +// <3=> 8192 Hz +// <7=> 4096 Hz +// <15=> 2048 Hz +// <31=> 1024 Hz + +#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY +#define APP_TIMER_CONFIG_RTC_FREQUENCY 1 +#endif + +// APP_TIMER_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef APP_TIMER_CONFIG_IRQ_PRIORITY +#define APP_TIMER_CONFIG_IRQ_PRIORITY 6 +#endif + +// APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. +// Size of the queue depends on how many timers are used +// in the system, how often timers are started and overall +// system latency. If queue size is too small app_timer calls +// will fail. + +#ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE +#define APP_TIMER_CONFIG_OP_QUEUE_SIZE 10 +#endif + +// APP_TIMER_CONFIG_USE_SCHEDULER - Enable scheduling app_timer events to app_scheduler + + +#ifndef APP_TIMER_CONFIG_USE_SCHEDULER +#define APP_TIMER_CONFIG_USE_SCHEDULER 0 +#endif + +// APP_TIMER_KEEPS_RTC_ACTIVE - Enable RTC always on + + +// If option is enabled RTC is kept running even if there is no active timers. +// This option can be used when app_timer is used for timestamping. + +#ifndef APP_TIMER_KEEPS_RTC_ACTIVE +#define APP_TIMER_KEEPS_RTC_ACTIVE 0 +#endif + +// APP_TIMER_SAFE_WINDOW_MS - Maximum possible latency (in milliseconds) of handling app_timer event. +// Maximum possible timeout that can be set is reduced by safe window. +// Example: RTC frequency 16384 Hz, maximum possible timeout 1024 seconds - APP_TIMER_SAFE_WINDOW_MS. +// Since RTC is not stopped when processor is halted in debugging session, this value +// must cover it if debugging is needed. It is possible to halt processor for APP_TIMER_SAFE_WINDOW_MS +// without corrupting app_timer behavior. + +#ifndef APP_TIMER_SAFE_WINDOW_MS +#define APP_TIMER_SAFE_WINDOW_MS 300000 +#endif + +// App Timer Legacy configuration - Legacy configuration. + +//========================================================== +// APP_TIMER_WITH_PROFILER - Enable app_timer profiling + + +#ifndef APP_TIMER_WITH_PROFILER +#define APP_TIMER_WITH_PROFILER 0 +#endif + +// APP_TIMER_CONFIG_SWI_NUMBER - Configure SWI instance used. + + +#ifndef APP_TIMER_CONFIG_SWI_NUMBER +#define APP_TIMER_CONFIG_SWI_NUMBER 0 +#endif + +// +//========================================================== + +// + +// APP_UART_ENABLED - app_uart - UART driver +//========================================================== +#ifndef APP_UART_ENABLED +#define APP_UART_ENABLED 1 +#endif +// APP_UART_DRIVER_INSTANCE - UART instance used + +// <0=> 0 + +#ifndef APP_UART_DRIVER_INSTANCE +#define APP_UART_DRIVER_INSTANCE 0 +#endif + +// + +// APP_USBD_AUDIO_ENABLED - app_usbd_audio - USB AUDIO class + + +#ifndef APP_USBD_AUDIO_ENABLED +#define APP_USBD_AUDIO_ENABLED 0 +#endif + +// APP_USBD_ENABLED - app_usbd - USB Device library +//========================================================== +#ifndef APP_USBD_ENABLED +#define APP_USBD_ENABLED 0 +#endif +// APP_USBD_VID - Vendor ID. <0x0000-0xFFFF> + + +// Note: This value is not editable in Configuration Wizard. +// Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/ + +#ifndef APP_USBD_VID +#define APP_USBD_VID 0 +#endif + +// APP_USBD_PID - Product ID. <0x0000-0xFFFF> + + +// Note: This value is not editable in Configuration Wizard. +// Selected Product ID + +#ifndef APP_USBD_PID +#define APP_USBD_PID 0 +#endif + +// APP_USBD_DEVICE_VER_MAJOR - Major device version <0-99> + + +// Major device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_MAJOR +#define APP_USBD_DEVICE_VER_MAJOR 1 +#endif + +// APP_USBD_DEVICE_VER_MINOR - Minor device version <0-9> + + +// Minor device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_MINOR +#define APP_USBD_DEVICE_VER_MINOR 0 +#endif + +// APP_USBD_DEVICE_VER_SUB - Sub-minor device version <0-9> + + +// Sub-minor device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_SUB +#define APP_USBD_DEVICE_VER_SUB 0 +#endif + +// APP_USBD_CONFIG_SELF_POWERED - Self-powered device, as opposed to bus-powered. + + +#ifndef APP_USBD_CONFIG_SELF_POWERED +#define APP_USBD_CONFIG_SELF_POWERED 1 +#endif + +// APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps. <0-500> + + +#ifndef APP_USBD_CONFIG_MAX_POWER +#define APP_USBD_CONFIG_MAX_POWER 100 +#endif + +// APP_USBD_CONFIG_POWER_EVENTS_PROCESS - Process power events. + + +// Enable processing power events in USB event handler. + +#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS +#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1 +#endif + +// APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue. + +// This is the default configuration when all the events are placed into internal queue. +// Disable it when an external queue is used like app_scheduler or if you wish to process all events inside interrupts. +// Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context. +// Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable, and disable. +//========================================================== +#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE +#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1 +#endif +// APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of the event queue. <16-64> + + +// The size of the queue for the events that would be processed in the main loop. + +#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE +#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32 +#endif + +// APP_USBD_CONFIG_SOF_HANDLING_MODE - Change SOF events handling mode. + + +// Normal queue - SOF events are pushed normally into the event queue. +// Compress queue - SOF events are counted and binded with other events or executed when the queue is empty. +// This prevents the queue from filling up with SOF events. +// Interrupt - SOF events are processed in interrupt. +// <0=> Normal queue +// <1=> Compress queue +// <2=> Interrupt + +#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE +#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1 +#endif + +// + +// APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE - Provide a function that generates timestamps for logs based on the current SOF. + + +// The function app_usbd_sof_timestamp_get is implemented if the logger is enabled. +// Use it when initializing the logger. +// SOF processing is always enabled when this configuration parameter is active. +// Note: This option is configured outside of APP_USBD_CONFIG_LOG_ENABLED. +// This means that it works even if the logging in this very module is disabled. + +#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE +#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 0 +#endif + +// APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor. <31-254> + + +// 31 characters can be stored in the internal USB buffer used for transfers. +// Any value higher than 31 creates an additional buffer just for descriptor strings. + +#ifndef APP_USBD_CONFIG_DESC_STRING_SIZE +#define APP_USBD_CONFIG_DESC_STRING_SIZE 31 +#endif + +// APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED - Enable UTF8 conversion. + + +// Enable UTF8-encoded characters. In normal processing, only ASCII characters are available. + +#ifndef APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED +#define APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED 0 +#endif + +// APP_USBD_STRINGS_LANGIDS - Supported languages identifiers. + +// Note: This value is not editable in Configuration Wizard. +// Comma-separated list of supported languages. +#ifndef APP_USBD_STRINGS_LANGIDS +#define APP_USBD_STRINGS_LANGIDS APP_USBD_LANG_AND_SUBLANG(APP_USBD_LANG_ENGLISH, APP_USBD_SUBLANG_ENGLISH_US) +#endif + +// APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID. + +// Setting ID to 0 disables the string. +//========================================================== +#ifndef APP_USBD_STRING_ID_MANUFACTURER +#define APP_USBD_STRING_ID_MANUFACTURER 1 +#endif +// APP_USBD_STRINGS_MANUFACTURER_EXTERN - Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by macro or declared as a global variable. + + +#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN +#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0 +#endif + +// APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name. + +// Note: This value is not editable in Configuration Wizard. +// Comma-separated list of manufacturer names for each defined language. +// Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string. +// Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values. +// Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values. +// Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor. +// Setting string to NULL disables that string. +// The order of manufacturer names must be the same like in @ref APP_USBD_STRINGS_LANGIDS. +#ifndef APP_USBD_STRINGS_MANUFACTURER +#define APP_USBD_STRINGS_MANUFACTURER APP_USBD_STRING_DESC("Nordic Semiconductor") +#endif + +// + +// APP_USBD_STRING_ID_PRODUCT - Define product string ID. + +// Setting ID to 0 disables the string. +//========================================================== +#ifndef APP_USBD_STRING_ID_PRODUCT +#define APP_USBD_STRING_ID_PRODUCT 2 +#endif +// APP_USBD_STRINGS_PRODUCT_EXTERN - Define whether @ref APP_USBD_STRINGS_PRODUCT is created by macro or declared as a global variable. + + +#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN +#define APP_USBD_STRINGS_PRODUCT_EXTERN 0 +#endif + +// APP_USBD_STRINGS_PRODUCT - String descriptor for the product name. + +// Note: This value is not editable in Configuration Wizard. +// List of product names that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER. +#ifndef APP_USBD_STRINGS_PRODUCT +#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF52 USB Product") +#endif + +// + +// APP_USBD_STRING_ID_SERIAL - Define serial number string ID. + +// Setting ID to 0 disables the string. +//========================================================== +#ifndef APP_USBD_STRING_ID_SERIAL +#define APP_USBD_STRING_ID_SERIAL 3 +#endif +// APP_USBD_STRING_SERIAL_EXTERN - Define whether @ref APP_USBD_STRING_SERIAL is created by macro or declared as a global variable. + + +#ifndef APP_USBD_STRING_SERIAL_EXTERN +#define APP_USBD_STRING_SERIAL_EXTERN 0 +#endif + +// APP_USBD_STRING_SERIAL - String descriptor for the serial number. + +// Note: This value is not editable in Configuration Wizard. +// Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER. +#ifndef APP_USBD_STRING_SERIAL +#define APP_USBD_STRING_SERIAL APP_USBD_STRING_DESC("000000000000") +#endif + +// + +// APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID. + +// Setting ID to 0 disables the string. +//========================================================== +#ifndef APP_USBD_STRING_ID_CONFIGURATION +#define APP_USBD_STRING_ID_CONFIGURATION 4 +#endif +// APP_USBD_STRING_CONFIGURATION_EXTERN - Define whether @ref APP_USBD_STRINGS_CONFIGURATION is created by macro or declared as global variable. + + +#ifndef APP_USBD_STRING_CONFIGURATION_EXTERN +#define APP_USBD_STRING_CONFIGURATION_EXTERN 0 +#endif + +// APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration. + +// Note: This value is not editable in Configuration Wizard. +// Configuration string that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER. +#ifndef APP_USBD_STRINGS_CONFIGURATION +#define APP_USBD_STRINGS_CONFIGURATION APP_USBD_STRING_DESC("Default configuration") +#endif + +// + +// APP_USBD_STRINGS_USER - Default values for user strings. + +// Note: This value is not editable in Configuration Wizard. +// This value stores all application specific user strings with the default initialization. +// The setup is done by X-macros. +// Expected macro parameters: +// @code +// X(mnemonic, [=str_idx], ...) +// @endcode +// - @c mnemonic: Mnemonic of the string descriptor that would be added to +// @ref app_usbd_string_desc_idx_t enumerator. +// - @c str_idx : String index value, can be set or left empty. +// For example, WinUSB driver requires descriptor to be present on 0xEE index. +// Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...))) +// - @c ... : List of string descriptors for each defined language. +#ifndef APP_USBD_STRINGS_USER +#define APP_USBD_STRINGS_USER X(APP_USER_1, , APP_USBD_STRING_DESC("User 1")) +#endif + +// + +// APP_USBD_HID_ENABLED - app_usbd_hid - USB HID class +//========================================================== +#ifndef APP_USBD_HID_ENABLED +#define APP_USBD_HID_ENABLED 0 +#endif +// APP_USBD_HID_DEFAULT_IDLE_RATE - Default idle rate for HID class. <0-255> + + +// 0 means indefinite duration, any other value is multiplied by 4 milliseconds. Refer to Chapter 7.2.4 of HID 1.11 Specification. + +#ifndef APP_USBD_HID_DEFAULT_IDLE_RATE +#define APP_USBD_HID_DEFAULT_IDLE_RATE 0 +#endif + +// APP_USBD_HID_REPORT_IDLE_TABLE_SIZE - Size of idle rate table. <1-255> + + +// Must be higher than the highest report ID used. + +#ifndef APP_USBD_HID_REPORT_IDLE_TABLE_SIZE +#define APP_USBD_HID_REPORT_IDLE_TABLE_SIZE 4 +#endif + +// + +// APP_USBD_HID_GENERIC_ENABLED - app_usbd_hid_generic - USB HID generic + + +#ifndef APP_USBD_HID_GENERIC_ENABLED +#define APP_USBD_HID_GENERIC_ENABLED 0 +#endif + +// APP_USBD_HID_KBD_ENABLED - app_usbd_hid_kbd - USB HID keyboard + + +#ifndef APP_USBD_HID_KBD_ENABLED +#define APP_USBD_HID_KBD_ENABLED 0 +#endif + +// APP_USBD_HID_MOUSE_ENABLED - app_usbd_hid_mouse - USB HID mouse + + +#ifndef APP_USBD_HID_MOUSE_ENABLED +#define APP_USBD_HID_MOUSE_ENABLED 0 +#endif + +// APP_USBD_MSC_ENABLED - app_usbd_msc - USB MSC class + + +#ifndef APP_USBD_MSC_ENABLED +#define APP_USBD_MSC_ENABLED 0 +#endif + +// CRC16_ENABLED - crc16 - CRC16 calculation routines + + +#ifndef CRC16_ENABLED +#define CRC16_ENABLED 0 +#endif + +// CRC32_ENABLED - crc32 - CRC32 calculation routines + + +#ifndef CRC32_ENABLED +#define CRC32_ENABLED 0 +#endif + +// ECC_ENABLED - ecc - Elliptic Curve Cryptography Library + + +#ifndef ECC_ENABLED +#define ECC_ENABLED 0 +#endif + +// FDS_ENABLED - fds - Flash data storage module +//========================================================== +#ifndef FDS_ENABLED +#define FDS_ENABLED 1 +#endif +// Pages - Virtual page settings + +// Configure the number of virtual pages to use and their size. +//========================================================== +// FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. +// One of the virtual pages is reserved by the system for garbage collection. +// Therefore, the minimum is two virtual pages: one page to store data and one page to be used by the system for garbage collection. +// The total amount of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES * @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes. + +#ifndef FDS_VIRTUAL_PAGES +#define FDS_VIRTUAL_PAGES 3 +#endif + +// FDS_VIRTUAL_PAGE_SIZE - The size of a virtual flash page. + + +// Expressed in number of 4-byte words. +// By default, a virtual page is the same size as a physical page. +// The size of a virtual page must be a multiple of the size of a physical page. +// <1024=> 1024 +// <2048=> 2048 + +#ifndef FDS_VIRTUAL_PAGE_SIZE +#define FDS_VIRTUAL_PAGE_SIZE 1024 +#endif + +// FDS_VIRTUAL_PAGES_RESERVED - The number of virtual flash pages that are used by other modules. +// FDS module stores its data in the last pages of the flash memory. +// By setting this value, you can move flash end address used by the FDS. +// As a result the reserved space can be used by other modules. + +#ifndef FDS_VIRTUAL_PAGES_RESERVED +#define FDS_VIRTUAL_PAGES_RESERVED 0 +#endif + +// +//========================================================== + +// Backend - Backend configuration + +// Configure which nrf_fstorage backend is used by FDS to write to flash. +//========================================================== +// FDS_BACKEND - FDS flash backend. + + +// NRF_FSTORAGE_SD uses the nrf_fstorage_sd backend implementation using the SoftDevice API. Use this if you have a SoftDevice present. +// NRF_FSTORAGE_NVMC uses the nrf_fstorage_nvmc implementation. Use this setting if you don't use the SoftDevice. +// <1=> NRF_FSTORAGE_NVMC +// <2=> NRF_FSTORAGE_SD + +#ifndef FDS_BACKEND +#define FDS_BACKEND 2 +#endif + +// +//========================================================== + +// Queue - Queue settings + +//========================================================== +// FDS_OP_QUEUE_SIZE - Size of the internal queue. +// Increase this value if you frequently get synchronous FDS_ERR_NO_SPACE_IN_QUEUES errors. + +#ifndef FDS_OP_QUEUE_SIZE +#define FDS_OP_QUEUE_SIZE 4 +#endif + +// +//========================================================== + +// CRC - CRC functionality + +//========================================================== +// FDS_CRC_CHECK_ON_READ - Enable CRC checks. + +// Save a record's CRC when it is written to flash and check it when the record is opened. +// Records with an incorrect CRC can still be 'seen' by the user using FDS functions, but they cannot be opened. +// Additionally, they will not be garbage collected until they are deleted. +//========================================================== +#ifndef FDS_CRC_CHECK_ON_READ +#define FDS_CRC_CHECK_ON_READ 0 +#endif +// FDS_CRC_CHECK_ON_WRITE - Perform a CRC check on newly written records. + + +// Perform a CRC check on newly written records. +// This setting can be used to make sure that the record data was not altered while being written to flash. +// <1=> Enabled +// <0=> Disabled + +#ifndef FDS_CRC_CHECK_ON_WRITE +#define FDS_CRC_CHECK_ON_WRITE 0 +#endif + +// + +// +//========================================================== + +// Users - Number of users + +//========================================================== +// FDS_MAX_USERS - Maximum number of callbacks that can be registered. +#ifndef FDS_MAX_USERS +#define FDS_MAX_USERS 4 +#endif + +// +//========================================================== + +// + +// HARDFAULT_HANDLER_ENABLED - hardfault_default - HardFault default handler for debugging and release + + +#ifndef HARDFAULT_HANDLER_ENABLED +#define HARDFAULT_HANDLER_ENABLED 0 +#endif + +// HCI_MEM_POOL_ENABLED - hci_mem_pool - memory pool implementation used by HCI +//========================================================== +#ifndef HCI_MEM_POOL_ENABLED +#define HCI_MEM_POOL_ENABLED 0 +#endif +// HCI_TX_BUF_SIZE - TX buffer size in bytes. +#ifndef HCI_TX_BUF_SIZE +#define HCI_TX_BUF_SIZE 600 +#endif + +// HCI_RX_BUF_SIZE - RX buffer size in bytes. +#ifndef HCI_RX_BUF_SIZE +#define HCI_RX_BUF_SIZE 600 +#endif + +// HCI_RX_BUF_QUEUE_SIZE - RX buffer queue size. +#ifndef HCI_RX_BUF_QUEUE_SIZE +#define HCI_RX_BUF_QUEUE_SIZE 4 +#endif + +// + +// HCI_SLIP_ENABLED - hci_slip - SLIP protocol implementation used by HCI +//========================================================== +#ifndef HCI_SLIP_ENABLED +#define HCI_SLIP_ENABLED 0 +#endif +// HCI_UART_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30801920=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 1000000 baud + +#ifndef HCI_UART_BAUDRATE +#define HCI_UART_BAUDRATE 30801920 +#endif + +// HCI_UART_FLOW_CONTROL - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef HCI_UART_FLOW_CONTROL +#define HCI_UART_FLOW_CONTROL 0 +#endif + +// HCI_UART_RX_PIN - UART RX pin +#ifndef HCI_UART_RX_PIN +#define HCI_UART_RX_PIN 8 +#endif + +// HCI_UART_TX_PIN - UART TX pin +#ifndef HCI_UART_TX_PIN +#define HCI_UART_TX_PIN 6 +#endif + +// HCI_UART_RTS_PIN - UART RTS pin +#ifndef HCI_UART_RTS_PIN +#define HCI_UART_RTS_PIN 5 +#endif + +// HCI_UART_CTS_PIN - UART CTS pin +#ifndef HCI_UART_CTS_PIN +#define HCI_UART_CTS_PIN 7 +#endif + +// + +// HCI_TRANSPORT_ENABLED - hci_transport - HCI transport +//========================================================== +#ifndef HCI_TRANSPORT_ENABLED +#define HCI_TRANSPORT_ENABLED 0 +#endif +// HCI_MAX_PACKET_SIZE_IN_BITS - Maximum size of a single application packet in bits. +#ifndef HCI_MAX_PACKET_SIZE_IN_BITS +#define HCI_MAX_PACKET_SIZE_IN_BITS 8000 +#endif + +// + +// LED_SOFTBLINK_ENABLED - led_softblink - led_softblink module + + +#ifndef LED_SOFTBLINK_ENABLED +#define LED_SOFTBLINK_ENABLED 0 +#endif + +// LOW_POWER_PWM_ENABLED - low_power_pwm - low_power_pwm module + + +#ifndef LOW_POWER_PWM_ENABLED +#define LOW_POWER_PWM_ENABLED 0 +#endif + +// MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator +//========================================================== +#ifndef MEM_MANAGER_ENABLED +#define MEM_MANAGER_ENABLED 0 +#endif +// MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block. <0-255> + + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT +#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1 +#endif + +// MEMORY_MANAGER_SMALL_BLOCK_SIZE - Size of each memory blocks identified as 'small' block. +// Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE +#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block. <0-255> + + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT +#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_SIZE - Size of each memory blocks identified as 'medium' block. +// Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE +#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block. <0-255> + + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT +#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_SIZE - Size of each memory blocks identified as 'large' block. +// Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE +#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_XLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra large' block. <0-255> + + +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT +#define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XLARGE_BLOCK_SIZE - Size of each memory blocks identified as 'extra large' block. +// Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XLARGE_BLOCK_SIZE +#define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 1320 +#endif + +// MEMORY_MANAGER_XXLARGE_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra large' block. <0-255> + + +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT +#define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XXLARGE_BLOCK_SIZE - Size of each memory blocks identified as 'extra extra large' block. +// Size of each memory blocks identified as 'extra extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_SIZE +#define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 3444 +#endif + +// MEMORY_MANAGER_XSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra small' block. <0-255> + + +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT +#define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XSMALL_BLOCK_SIZE - Size of each memory blocks identified as 'extra small' block. +// Size of each memory blocks identified as 'extra large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XSMALL_BLOCK_SIZE +#define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 64 +#endif + +// MEMORY_MANAGER_XXSMALL_BLOCK_COUNT - Size of each memory blocks identified as 'extra extra small' block. <0-255> + + +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT +#define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_XXSMALL_BLOCK_SIZE - Size of each memory blocks identified as 'extra extra small' block. +// Size of each memory blocks identified as 'extra extra small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_SIZE +#define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 32 +#endif + +// MEM_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef MEM_MANAGER_CONFIG_LOG_ENABLED +#define MEM_MANAGER_CONFIG_LOG_ENABLED 0 +#endif +// MEM_MANAGER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef MEM_MANAGER_CONFIG_LOG_LEVEL +#define MEM_MANAGER_CONFIG_LOG_LEVEL 3 +#endif + +// MEM_MANAGER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MEM_MANAGER_CONFIG_INFO_COLOR +#define MEM_MANAGER_CONFIG_INFO_COLOR 0 +#endif + +// MEM_MANAGER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MEM_MANAGER_CONFIG_DEBUG_COLOR +#define MEM_MANAGER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// MEM_MANAGER_DISABLE_API_PARAM_CHECK - Disable API parameter checks in the module. + + +#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK +#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0 +#endif + +// + +// NRF_BALLOC_ENABLED - nrf_balloc - Block allocator module +//========================================================== +#ifndef NRF_BALLOC_ENABLED +#define NRF_BALLOC_ENABLED 1 +#endif +// NRF_BALLOC_CONFIG_DEBUG_ENABLED - Enables debug mode in the module. +//========================================================== +#ifndef NRF_BALLOC_CONFIG_DEBUG_ENABLED +#define NRF_BALLOC_CONFIG_DEBUG_ENABLED 0 +#endif +// NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS - Number of words used as head guard. <0-255> + + +#ifndef NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS +#define NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS 1 +#endif + +// NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS - Number of words used as tail guard. <0-255> + + +#ifndef NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS +#define NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS 1 +#endif + +// NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED - Enables basic checks in this module. + + +#ifndef NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED +#define NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED 0 +#endif + +// NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED - Enables double memory free check in this module. + + +#ifndef NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED +#define NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED 0 +#endif + +// NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED - Enables free memory corruption check in this module. + + +#ifndef NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED +#define NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED 0 +#endif + +// NRF_BALLOC_CLI_CMDS - Enable CLI commands specific to the module + + +#ifndef NRF_BALLOC_CLI_CMDS +#define NRF_BALLOC_CLI_CMDS 0 +#endif + +// + +// + +// NRF_CSENSE_ENABLED - nrf_csense - Capacitive sensor module +//========================================================== +#ifndef NRF_CSENSE_ENABLED +#define NRF_CSENSE_ENABLED 0 +#endif +// NRF_CSENSE_PAD_HYSTERESIS - Minimum value of change required to determine that a pad was touched. +#ifndef NRF_CSENSE_PAD_HYSTERESIS +#define NRF_CSENSE_PAD_HYSTERESIS 15 +#endif + +// NRF_CSENSE_PAD_DEVIATION - Minimum value measured on a pad required to take it into account while calculating the step. +#ifndef NRF_CSENSE_PAD_DEVIATION +#define NRF_CSENSE_PAD_DEVIATION 70 +#endif + +// NRF_CSENSE_MIN_PAD_VALUE - Minimum normalized value on a pad required to take its value into account. +#ifndef NRF_CSENSE_MIN_PAD_VALUE +#define NRF_CSENSE_MIN_PAD_VALUE 20 +#endif + +// NRF_CSENSE_MAX_PADS_NUMBER - Maximum number of pads used for one instance. +#ifndef NRF_CSENSE_MAX_PADS_NUMBER +#define NRF_CSENSE_MAX_PADS_NUMBER 20 +#endif + +// NRF_CSENSE_MAX_VALUE - Maximum normalized value obtained from measurement. +#ifndef NRF_CSENSE_MAX_VALUE +#define NRF_CSENSE_MAX_VALUE 1000 +#endif + +// NRF_CSENSE_OUTPUT_PIN - Output pin used by the low-level module. +// This is used when capacitive sensor does not use COMP. + +#ifndef NRF_CSENSE_OUTPUT_PIN +#define NRF_CSENSE_OUTPUT_PIN 26 +#endif + +// + +// NRF_DRV_CSENSE_ENABLED - nrf_drv_csense - Capacitive sensor low-level module +//========================================================== +#ifndef NRF_DRV_CSENSE_ENABLED +#define NRF_DRV_CSENSE_ENABLED 0 +#endif +// USE_COMP - Use the comparator to implement the capacitive sensor driver. + +// Due to Anomaly 84, COMP I_SOURCE is not functional. It has too high a varation. +//========================================================== +#ifndef USE_COMP +#define USE_COMP 0 +#endif +// TIMER0_FOR_CSENSE - First TIMER instance used by the driver (not used on nRF51). +#ifndef TIMER0_FOR_CSENSE +#define TIMER0_FOR_CSENSE 1 +#endif + +// TIMER1_FOR_CSENSE - Second TIMER instance used by the driver (not used on nRF51). +#ifndef TIMER1_FOR_CSENSE +#define TIMER1_FOR_CSENSE 2 +#endif + +// MEASUREMENT_PERIOD - Single measurement period. +// Time of a single measurement can be calculated as +// T = (1/2)*MEASUREMENT_PERIOD*(1/f_OSC) where f_OSC = I_SOURCE / (2C*(VUP-VDOWN) ). +// I_SOURCE, VUP, and VDOWN are values used to initialize COMP and C is the capacitance of the used pad. + +#ifndef MEASUREMENT_PERIOD +#define MEASUREMENT_PERIOD 20 +#endif + +// + +// + +// NRF_FSTORAGE_ENABLED - nrf_fstorage - Flash abstraction library +//========================================================== +#ifndef NRF_FSTORAGE_ENABLED +#define NRF_FSTORAGE_ENABLED 1 +#endif +// nrf_fstorage - Common settings + +// Common settings to all fstorage implementations +//========================================================== +// NRF_FSTORAGE_PARAM_CHECK_DISABLED - Disable user input validation + + +// If selected, use ASSERT to validate user input. +// This effectively removes user input validation in production code. +// Recommended setting: OFF, only enable this setting if size is a major concern. + +#ifndef NRF_FSTORAGE_PARAM_CHECK_DISABLED +#define NRF_FSTORAGE_PARAM_CHECK_DISABLED 0 +#endif + +// +//========================================================== + +// nrf_fstorage_sd - Implementation using the SoftDevice + +// Configuration options for the fstorage implementation using the SoftDevice +//========================================================== +// NRF_FSTORAGE_SD_QUEUE_SIZE - Size of the internal queue of operations +// Increase this value if API calls frequently return the error @ref NRF_ERROR_NO_MEM. + +#ifndef NRF_FSTORAGE_SD_QUEUE_SIZE +#define NRF_FSTORAGE_SD_QUEUE_SIZE 4 +#endif + +// NRF_FSTORAGE_SD_MAX_RETRIES - Maximum number of attempts at executing an operation when the SoftDevice is busy +// Increase this value if events frequently return the @ref NRF_ERROR_TIMEOUT error. +// The SoftDevice might fail to schedule flash access due to high BLE activity. + +#ifndef NRF_FSTORAGE_SD_MAX_RETRIES +#define NRF_FSTORAGE_SD_MAX_RETRIES 8 +#endif + +// NRF_FSTORAGE_SD_MAX_WRITE_SIZE - Maximum number of bytes to be written to flash in a single operation +// This value must be a multiple of four. +// Lowering this value can increase the chances of the SoftDevice being able to execute flash operations in between radio activity. +// This value is bound by the maximum number of bytes that can be written to flash in a single call to @ref sd_flash_write. +// That is 1024 bytes for nRF51 ICs and 4096 bytes for nRF52 ICs. + +#ifndef NRF_FSTORAGE_SD_MAX_WRITE_SIZE +#define NRF_FSTORAGE_SD_MAX_WRITE_SIZE 4096 +#endif + +// +//========================================================== + +// + +// NRF_GFX_ENABLED - nrf_gfx - GFX module + + +#ifndef NRF_GFX_ENABLED +#define NRF_GFX_ENABLED 0 +#endif + +// NRF_MEMOBJ_ENABLED - nrf_memobj - Linked memory allocator module + + +#ifndef NRF_MEMOBJ_ENABLED +#define NRF_MEMOBJ_ENABLED 1 +#endif + +// NRF_PWR_MGMT_ENABLED - nrf_pwr_mgmt - Power management module +//========================================================== +#ifndef NRF_PWR_MGMT_ENABLED +#define NRF_PWR_MGMT_ENABLED 1 +#endif +// NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED - Enables pin debug in the module. + +// Selected pin will be set when CPU is in sleep mode. +//========================================================== +#ifndef NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED +#define NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED 0 +#endif +// NRF_PWR_MGMT_SLEEP_DEBUG_PIN - Pin number + +// <0=> 0 (P0.0) +// <1=> 1 (P0.1) +// <2=> 2 (P0.2) +// <3=> 3 (P0.3) +// <4=> 4 (P0.4) +// <5=> 5 (P0.5) +// <6=> 6 (P0.6) +// <7=> 7 (P0.7) +// <8=> 8 (P0.8) +// <9=> 9 (P0.9) +// <10=> 10 (P0.10) +// <11=> 11 (P0.11) +// <12=> 12 (P0.12) +// <13=> 13 (P0.13) +// <14=> 14 (P0.14) +// <15=> 15 (P0.15) +// <16=> 16 (P0.16) +// <17=> 17 (P0.17) +// <18=> 18 (P0.18) +// <19=> 19 (P0.19) +// <20=> 20 (P0.20) +// <21=> 21 (P0.21) +// <22=> 22 (P0.22) +// <23=> 23 (P0.23) +// <24=> 24 (P0.24) +// <25=> 25 (P0.25) +// <26=> 26 (P0.26) +// <27=> 27 (P0.27) +// <28=> 28 (P0.28) +// <29=> 29 (P0.29) +// <30=> 30 (P0.30) +// <31=> 31 (P0.31) +// <32=> 32 (P1.0) +// <33=> 33 (P1.1) +// <34=> 34 (P1.2) +// <35=> 35 (P1.3) +// <36=> 36 (P1.4) +// <37=> 37 (P1.5) +// <38=> 38 (P1.6) +// <39=> 39 (P1.7) +// <40=> 40 (P1.8) +// <41=> 41 (P1.9) +// <42=> 42 (P1.10) +// <43=> 43 (P1.11) +// <44=> 44 (P1.12) +// <45=> 45 (P1.13) +// <46=> 46 (P1.14) +// <47=> 47 (P1.15) +// <4294967295=> Not connected + +#ifndef NRF_PWR_MGMT_SLEEP_DEBUG_PIN +#define NRF_PWR_MGMT_SLEEP_DEBUG_PIN 31 +#endif + +// + +// NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED - Enables CPU usage monitor. + + +// Module will trace percentage of CPU usage in one second intervals. + +#ifndef NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED +#define NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED 0 +#endif + +// NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED - Enable standby timeout. +//========================================================== +#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED +#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED 0 +#endif +// NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S - Standby timeout (in seconds). +// Shutdown procedure will begin no earlier than after this number of seconds. + +#ifndef NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S +#define NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S 3 +#endif + +// + +// NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED - Enables FPU event cleaning. + + +#ifndef NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED +#define NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED 1 +#endif + +// NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY - Blocked shutdown procedure will be retried every second. + + +#ifndef NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY +#define NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY 0 +#endif + +// NRF_PWR_MGMT_CONFIG_USE_SCHEDULER - Module will use @ref app_scheduler. + + +#ifndef NRF_PWR_MGMT_CONFIG_USE_SCHEDULER +#define NRF_PWR_MGMT_CONFIG_USE_SCHEDULER 0 +#endif + +// NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT - The number of priorities for module handlers. +// The number of stages of the shutdown process. + +#ifndef NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT +#define NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT 3 +#endif + +// + +// NRF_QUEUE_ENABLED - nrf_queue - Queue module +//========================================================== +#ifndef NRF_QUEUE_ENABLED +#define NRF_QUEUE_ENABLED 1 +#endif +// NRF_QUEUE_CLI_CMDS - Enable CLI commands specific to the module + + +#ifndef NRF_QUEUE_CLI_CMDS +#define NRF_QUEUE_CLI_CMDS 0 +#endif + +// + +// NRF_SECTION_ITER_ENABLED - nrf_section_iter - Section iterator + + +#ifndef NRF_SECTION_ITER_ENABLED +#define NRF_SECTION_ITER_ENABLED 1 +#endif + +// NRF_SORTLIST_ENABLED - nrf_sortlist - Sorted list + + +#ifndef NRF_SORTLIST_ENABLED +#define NRF_SORTLIST_ENABLED 1 +#endif + +// NRF_SPI_MNGR_ENABLED - nrf_spi_mngr - SPI transaction manager + + +#ifndef NRF_SPI_MNGR_ENABLED +#define NRF_SPI_MNGR_ENABLED 0 +#endif + +// NRF_STRERROR_ENABLED - nrf_strerror - Library for converting error code to string. + + +#ifndef NRF_STRERROR_ENABLED +#define NRF_STRERROR_ENABLED 1 +#endif + +// NRF_TWI_MNGR_ENABLED - nrf_twi_mngr - TWI transaction manager + + +#ifndef NRF_TWI_MNGR_ENABLED +#define NRF_TWI_MNGR_ENABLED 0 +#endif + +// RETARGET_ENABLED - retarget - Retargeting stdio functions + + +#ifndef RETARGET_ENABLED +#define RETARGET_ENABLED 0 +#endif + +// SLIP_ENABLED - slip - SLIP encoding and decoding + + +#ifndef SLIP_ENABLED +#define SLIP_ENABLED 0 +#endif + +// TASK_MANAGER_ENABLED - task_manager - Task manager. +//========================================================== +#ifndef TASK_MANAGER_ENABLED +#define TASK_MANAGER_ENABLED 0 +#endif +// TASK_MANAGER_CLI_CMDS - Enable CLI commands specific to the module + + +#ifndef TASK_MANAGER_CLI_CMDS +#define TASK_MANAGER_CLI_CMDS 0 +#endif + +// TASK_MANAGER_CONFIG_MAX_TASKS - Maximum number of tasks which can be created +#ifndef TASK_MANAGER_CONFIG_MAX_TASKS +#define TASK_MANAGER_CONFIG_MAX_TASKS 2 +#endif + +// TASK_MANAGER_CONFIG_STACK_SIZE - Stack size for every task (power of 2) +#ifndef TASK_MANAGER_CONFIG_STACK_SIZE +#define TASK_MANAGER_CONFIG_STACK_SIZE 1024 +#endif + +// TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED - Enable stack profiling. + + +#ifndef TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED +#define TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED 1 +#endif + +// TASK_MANAGER_CONFIG_STACK_GUARD - Configures stack guard. + +// <0=> Disabled +// <4=> 32 bytes +// <5=> 64 bytes +// <6=> 128 bytes +// <7=> 256 bytes +// <8=> 512 bytes + +#ifndef TASK_MANAGER_CONFIG_STACK_GUARD +#define TASK_MANAGER_CONFIG_STACK_GUARD 7 +#endif + +// + +// app_button - buttons handling module + +//========================================================== +// BUTTON_ENABLED - Enables Button module + + +#ifndef BUTTON_ENABLED +#define BUTTON_ENABLED 1 +#endif + +// BUTTON_HIGH_ACCURACY_ENABLED - Enables GPIOTE high accuracy for buttons + + +#ifndef BUTTON_HIGH_ACCURACY_ENABLED +#define BUTTON_HIGH_ACCURACY_ENABLED 0 +#endif + +// +//========================================================== + +// app_usbd_cdc_acm - USB CDC ACM class + +//========================================================== +// APP_USBD_CDC_ACM_ENABLED - Enabling USBD CDC ACM Class library + + +#ifndef APP_USBD_CDC_ACM_ENABLED +#define APP_USBD_CDC_ACM_ENABLED 0 +#endif + +// APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE - Send ZLP on write with same size as endpoint + + +// If enabled, CDC ACM class will automatically send a zero length packet after transfer which has the same size as endpoint. +// This may limit throughput if a lot of binary data is sent, but in terminal mode operation it makes sure that the data is always displayed right after it is sent. + +#ifndef APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE +#define APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE 1 +#endif + +// +//========================================================== + +// nrf_cli - Command line interface + +//========================================================== +// NRF_CLI_ENABLED - Enable/disable the CLI module. + + +#ifndef NRF_CLI_ENABLED +#define NRF_CLI_ENABLED 0 +#endif + +// NRF_CLI_ARGC_MAX - Maximum number of parameters passed to the command handler. +#ifndef NRF_CLI_ARGC_MAX +#define NRF_CLI_ARGC_MAX 12 +#endif + +// NRF_CLI_BUILD_IN_CMDS_ENABLED - CLI built-in commands. + + +#ifndef NRF_CLI_BUILD_IN_CMDS_ENABLED +#define NRF_CLI_BUILD_IN_CMDS_ENABLED 1 +#endif + +// NRF_CLI_CMD_BUFF_SIZE - Maximum buffer size for a single command. +#ifndef NRF_CLI_CMD_BUFF_SIZE +#define NRF_CLI_CMD_BUFF_SIZE 128 +#endif + +// NRF_CLI_ECHO_STATUS - CLI echo status. If set, echo is ON. + + +#ifndef NRF_CLI_ECHO_STATUS +#define NRF_CLI_ECHO_STATUS 1 +#endif + +// NRF_CLI_WILDCARD_ENABLED - Enable wildcard functionality for CLI commands. + + +#ifndef NRF_CLI_WILDCARD_ENABLED +#define NRF_CLI_WILDCARD_ENABLED 0 +#endif + +// NRF_CLI_METAKEYS_ENABLED - Enable additional control keys for CLI commands like ctrl+a, ctrl+e, ctrl+w, ctrl+u + + +#ifndef NRF_CLI_METAKEYS_ENABLED +#define NRF_CLI_METAKEYS_ENABLED 0 +#endif + +// NRF_CLI_PRINTF_BUFF_SIZE - Maximum print buffer size. +#ifndef NRF_CLI_PRINTF_BUFF_SIZE +#define NRF_CLI_PRINTF_BUFF_SIZE 23 +#endif + +// NRF_CLI_HISTORY_ENABLED - Enable CLI history mode. +//========================================================== +#ifndef NRF_CLI_HISTORY_ENABLED +#define NRF_CLI_HISTORY_ENABLED 1 +#endif +// NRF_CLI_HISTORY_ELEMENT_SIZE - Size of one memory object reserved for CLI history. +#ifndef NRF_CLI_HISTORY_ELEMENT_SIZE +#define NRF_CLI_HISTORY_ELEMENT_SIZE 32 +#endif + +// NRF_CLI_HISTORY_ELEMENT_COUNT - Number of history memory objects. +#ifndef NRF_CLI_HISTORY_ELEMENT_COUNT +#define NRF_CLI_HISTORY_ELEMENT_COUNT 8 +#endif + +// + +// NRF_CLI_VT100_COLORS_ENABLED - CLI VT100 colors. + + +#ifndef NRF_CLI_VT100_COLORS_ENABLED +#define NRF_CLI_VT100_COLORS_ENABLED 1 +#endif + +// NRF_CLI_STATISTICS_ENABLED - Enable CLI statistics. + + +#ifndef NRF_CLI_STATISTICS_ENABLED +#define NRF_CLI_STATISTICS_ENABLED 1 +#endif + +// NRF_CLI_LOG_BACKEND - Enable logger backend interface. + + +#ifndef NRF_CLI_LOG_BACKEND +#define NRF_CLI_LOG_BACKEND 1 +#endif + +// NRF_CLI_USES_TASK_MANAGER_ENABLED - Enable CLI to use task_manager + + +#ifndef NRF_CLI_USES_TASK_MANAGER_ENABLED +#define NRF_CLI_USES_TASK_MANAGER_ENABLED 0 +#endif + +// +//========================================================== + +// nrf_fprintf - fprintf function. + +//========================================================== +// NRF_FPRINTF_ENABLED - Enable/disable fprintf module. + + +#ifndef NRF_FPRINTF_ENABLED +#define NRF_FPRINTF_ENABLED 1 +#endif + +// NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED - For each printed LF, function will add CR. + + +#ifndef NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED +#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 1 +#endif + +// NRF_FPRINTF_DOUBLE_ENABLED - Enable IEEE-754 double precision formatting. + + +#ifndef NRF_FPRINTF_DOUBLE_ENABLED +#define NRF_FPRINTF_DOUBLE_ENABLED 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_Log + +//========================================================== +// NRF_LOG_BACKEND_RTT_ENABLED - nrf_log_backend_rtt - Log RTT backend +//========================================================== +#ifndef NRF_LOG_BACKEND_RTT_ENABLED +#define NRF_LOG_BACKEND_RTT_ENABLED 1 +#endif +// NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE - Size of buffer for partially processed strings. +// Size of the buffer is a trade-off between RAM usage and processing. +// if buffer is smaller then strings will often be fragmented. +// It is recommended to use size which will fit typical log and only the +// longer one will be fragmented. + +#ifndef NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE +#define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64 +#endif + +// NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS - Period before retrying writing to RTT +#ifndef NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS +#define NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS 1 +#endif + +// NRF_LOG_BACKEND_RTT_TX_RETRY_CNT - Writing to RTT retries. +// If RTT fails to accept any new data after retries +// module assumes that host is not active and on next +// request it will perform only one write attempt. +// On successful writing, module assumes that host is active +// and scheme with retry is applied again. + +#ifndef NRF_LOG_BACKEND_RTT_TX_RETRY_CNT +#define NRF_LOG_BACKEND_RTT_TX_RETRY_CNT 3 +#endif + +// + +// NRF_LOG_ENABLED - nrf_log - Logger +//========================================================== +#ifndef NRF_LOG_ENABLED +#define NRF_LOG_ENABLED 1 +#endif +// Log message pool - Configuration of log message pool + +//========================================================== +// NRF_LOG_MSGPOOL_ELEMENT_SIZE - Size of a single element in the pool of memory objects. +// If a small value is set, then performance of logs processing +// is degraded because data is fragmented. Bigger value impacts +// RAM memory utilization. The size is set to fit a message with +// a timestamp and up to 2 arguments in a single memory object. + +#ifndef NRF_LOG_MSGPOOL_ELEMENT_SIZE +#define NRF_LOG_MSGPOOL_ELEMENT_SIZE 20 +#endif + +// NRF_LOG_MSGPOOL_ELEMENT_COUNT - Number of elements in the pool of memory objects +// If a small value is set, then it may lead to a deadlock +// in certain cases if backend has high latency and holds +// multiple messages for long time. Bigger value impacts +// RAM memory usage. + +#ifndef NRF_LOG_MSGPOOL_ELEMENT_COUNT +#define NRF_LOG_MSGPOOL_ELEMENT_COUNT 8 +#endif + +// +//========================================================== + +// NRF_LOG_ALLOW_OVERFLOW - Configures behavior when circular buffer is full. + + +// If set then oldest logs are overwritten. Otherwise a +// marker is injected informing about overflow. + +#ifndef NRF_LOG_ALLOW_OVERFLOW +#define NRF_LOG_ALLOW_OVERFLOW 1 +#endif + +// NRF_LOG_BUFSIZE - Size of the buffer for storing logs (in bytes). + + +// Must be power of 2 and multiple of 4. +// If NRF_LOG_DEFERRED = 0 then buffer size can be reduced to minimum. +// <128=> 128 +// <256=> 256 +// <512=> 512 +// <1024=> 1024 +// <2048=> 2048 +// <4096=> 4096 +// <8192=> 8192 +// <16384=> 16384 + +#ifndef NRF_LOG_BUFSIZE +#define NRF_LOG_BUFSIZE 1024 +#endif + +// NRF_LOG_CLI_CMDS - Enable CLI commands for the module. + + +#ifndef NRF_LOG_CLI_CMDS +#define NRF_LOG_CLI_CMDS 0 +#endif + +// NRF_LOG_DEFAULT_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_LOG_DEFAULT_LEVEL +#define NRF_LOG_DEFAULT_LEVEL 3 +#endif + +// NRF_LOG_DEFERRED - Enable deffered logger. + + +// Log data is buffered and can be processed in idle. + +#ifndef NRF_LOG_DEFERRED +#define NRF_LOG_DEFERRED 1 +#endif + +// NRF_LOG_FILTERS_ENABLED - Enable dynamic filtering of logs. + + +#ifndef NRF_LOG_FILTERS_ENABLED +#define NRF_LOG_FILTERS_ENABLED 0 +#endif + +// NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED - Enable use of critical region for non deffered mode when flushing logs. + + +// When enabled NRF_LOG_FLUSH is called from critical section when non deffered mode is used. +// Log output will never be corrupted as access to the log backend is exclusive +// but system will spend significant amount of time in critical section + +#ifndef NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED +#define NRF_LOG_NON_DEFFERED_CRITICAL_REGION_ENABLED 0 +#endif + +// NRF_LOG_STR_PUSH_BUFFER_SIZE - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH. + +// <16=> 16 +// <32=> 32 +// <64=> 64 +// <128=> 128 +// <256=> 256 +// <512=> 512 +// <1024=> 1024 + +#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE +#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128 +#endif + +// NRF_LOG_STR_PUSH_BUFFER_SIZE - Size of the buffer dedicated for strings stored using @ref NRF_LOG_PUSH. + +// <16=> 16 +// <32=> 32 +// <64=> 64 +// <128=> 128 +// <256=> 256 +// <512=> 512 +// <1024=> 1024 + +#ifndef NRF_LOG_STR_PUSH_BUFFER_SIZE +#define NRF_LOG_STR_PUSH_BUFFER_SIZE 128 +#endif + +// NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string +//========================================================== +#ifndef NRF_LOG_USES_COLORS +#define NRF_LOG_USES_COLORS 0 +#endif +// NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_COLOR_DEFAULT +#define NRF_LOG_COLOR_DEFAULT 0 +#endif + +// NRF_LOG_ERROR_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_ERROR_COLOR +#define NRF_LOG_ERROR_COLOR 2 +#endif + +// NRF_LOG_WARNING_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_WARNING_COLOR +#define NRF_LOG_WARNING_COLOR 4 +#endif + +// + +// NRF_LOG_USES_TIMESTAMP - Enable timestamping + +// Function for getting the timestamp is provided by the user +//========================================================== +#ifndef NRF_LOG_USES_TIMESTAMP +#define NRF_LOG_USES_TIMESTAMP 0 +#endif +// NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY - Default frequency of the timestamp (in Hz) or 0 to use app_timer frequency. +#ifndef NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY +#define NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY 0 +#endif + +// + +// nrf_log module configuration + +//========================================================== +// nrf_log in nRF_Core + +//========================================================== +// NRF_MPU_LIB_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_MPU_LIB_CONFIG_LOG_ENABLED +#define NRF_MPU_LIB_CONFIG_LOG_ENABLED 0 +#endif +// NRF_MPU_LIB_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_MPU_LIB_CONFIG_LOG_LEVEL +#define NRF_MPU_LIB_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_MPU_LIB_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MPU_LIB_CONFIG_INFO_COLOR +#define NRF_MPU_LIB_CONFIG_INFO_COLOR 0 +#endif + +// NRF_MPU_LIB_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MPU_LIB_CONFIG_DEBUG_COLOR +#define NRF_MPU_LIB_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_STACK_GUARD_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_STACK_GUARD_CONFIG_LOG_ENABLED +#define NRF_STACK_GUARD_CONFIG_LOG_ENABLED 0 +#endif +// NRF_STACK_GUARD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_STACK_GUARD_CONFIG_LOG_LEVEL +#define NRF_STACK_GUARD_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_STACK_GUARD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_STACK_GUARD_CONFIG_INFO_COLOR +#define NRF_STACK_GUARD_CONFIG_INFO_COLOR 0 +#endif + +// NRF_STACK_GUARD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_STACK_GUARD_CONFIG_DEBUG_COLOR +#define NRF_STACK_GUARD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TASK_MANAGER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TASK_MANAGER_CONFIG_LOG_ENABLED +#define TASK_MANAGER_CONFIG_LOG_ENABLED 0 +#endif +// TASK_MANAGER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TASK_MANAGER_CONFIG_LOG_LEVEL +#define TASK_MANAGER_CONFIG_LOG_LEVEL 3 +#endif + +// TASK_MANAGER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TASK_MANAGER_CONFIG_INFO_COLOR +#define TASK_MANAGER_CONFIG_INFO_COLOR 0 +#endif + +// TASK_MANAGER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TASK_MANAGER_CONFIG_DEBUG_COLOR +#define TASK_MANAGER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// nrf_log in nRF_Drivers + +//========================================================== +// CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef CLOCK_CONFIG_LOG_ENABLED +#define CLOCK_CONFIG_LOG_ENABLED 0 +#endif +// CLOCK_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef CLOCK_CONFIG_LOG_LEVEL +#define CLOCK_CONFIG_LOG_LEVEL 3 +#endif + +// CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_INFO_COLOR +#define CLOCK_CONFIG_INFO_COLOR 0 +#endif + +// CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_DEBUG_COLOR +#define CLOCK_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// COMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef COMP_CONFIG_LOG_ENABLED +#define COMP_CONFIG_LOG_ENABLED 0 +#endif +// COMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef COMP_CONFIG_LOG_LEVEL +#define COMP_CONFIG_LOG_LEVEL 3 +#endif + +// COMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_INFO_COLOR +#define COMP_CONFIG_INFO_COLOR 0 +#endif + +// COMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_DEBUG_COLOR +#define COMP_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef GPIOTE_CONFIG_LOG_ENABLED +#define GPIOTE_CONFIG_LOG_ENABLED 0 +#endif +// GPIOTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef GPIOTE_CONFIG_LOG_LEVEL +#define GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +// GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_INFO_COLOR +#define GPIOTE_CONFIG_INFO_COLOR 0 +#endif + +// GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_DEBUG_COLOR +#define GPIOTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef LPCOMP_CONFIG_LOG_ENABLED +#define LPCOMP_CONFIG_LOG_ENABLED 0 +#endif +// LPCOMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef LPCOMP_CONFIG_LOG_LEVEL +#define LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +// LPCOMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_INFO_COLOR +#define LPCOMP_CONFIG_INFO_COLOR 0 +#endif + +// LPCOMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_DEBUG_COLOR +#define LPCOMP_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// MAX3421E_HOST_CONFIG_LOG_ENABLED - Enable logging in the module +//========================================================== +#ifndef MAX3421E_HOST_CONFIG_LOG_ENABLED +#define MAX3421E_HOST_CONFIG_LOG_ENABLED 0 +#endif +// MAX3421E_HOST_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef MAX3421E_HOST_CONFIG_LOG_LEVEL +#define MAX3421E_HOST_CONFIG_LOG_LEVEL 3 +#endif + +// MAX3421E_HOST_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MAX3421E_HOST_CONFIG_INFO_COLOR +#define MAX3421E_HOST_CONFIG_INFO_COLOR 0 +#endif + +// MAX3421E_HOST_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef MAX3421E_HOST_CONFIG_DEBUG_COLOR +#define MAX3421E_HOST_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRFX_USBD_CONFIG_LOG_ENABLED - Enable logging in the module +//========================================================== +#ifndef NRFX_USBD_CONFIG_LOG_ENABLED +#define NRFX_USBD_CONFIG_LOG_ENABLED 0 +#endif +// NRFX_USBD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRFX_USBD_CONFIG_LOG_LEVEL +#define NRFX_USBD_CONFIG_LOG_LEVEL 3 +#endif + +// NRFX_USBD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_USBD_CONFIG_INFO_COLOR +#define NRFX_USBD_CONFIG_INFO_COLOR 0 +#endif + +// NRFX_USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRFX_USBD_CONFIG_DEBUG_COLOR +#define NRFX_USBD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PDM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PDM_CONFIG_LOG_ENABLED +#define PDM_CONFIG_LOG_ENABLED 0 +#endif +// PDM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PDM_CONFIG_LOG_LEVEL +#define PDM_CONFIG_LOG_LEVEL 3 +#endif + +// PDM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_INFO_COLOR +#define PDM_CONFIG_INFO_COLOR 0 +#endif + +// PDM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_DEBUG_COLOR +#define PDM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PPI_CONFIG_LOG_ENABLED +#define PPI_CONFIG_LOG_ENABLED 0 +#endif +// PPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PPI_CONFIG_LOG_LEVEL +#define PPI_CONFIG_LOG_LEVEL 3 +#endif + +// PPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_INFO_COLOR +#define PPI_CONFIG_INFO_COLOR 0 +#endif + +// PPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_DEBUG_COLOR +#define PPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PWM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PWM_CONFIG_LOG_ENABLED +#define PWM_CONFIG_LOG_ENABLED 0 +#endif +// PWM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PWM_CONFIG_LOG_LEVEL +#define PWM_CONFIG_LOG_LEVEL 3 +#endif + +// PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_INFO_COLOR +#define PWM_CONFIG_INFO_COLOR 0 +#endif + +// PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_DEBUG_COLOR +#define PWM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// QDEC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef QDEC_CONFIG_LOG_ENABLED +#define QDEC_CONFIG_LOG_ENABLED 0 +#endif +// QDEC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef QDEC_CONFIG_LOG_LEVEL +#define QDEC_CONFIG_LOG_LEVEL 3 +#endif + +// QDEC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_INFO_COLOR +#define QDEC_CONFIG_INFO_COLOR 0 +#endif + +// QDEC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_DEBUG_COLOR +#define QDEC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// RNG_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RNG_CONFIG_LOG_ENABLED +#define RNG_CONFIG_LOG_ENABLED 0 +#endif +// RNG_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RNG_CONFIG_LOG_LEVEL +#define RNG_CONFIG_LOG_LEVEL 3 +#endif + +// RNG_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_INFO_COLOR +#define RNG_CONFIG_INFO_COLOR 0 +#endif + +// RNG_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_DEBUG_COLOR +#define RNG_CONFIG_DEBUG_COLOR 0 +#endif + +// RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED - Enables logging of random numbers. + + +#ifndef RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED +#define RNG_CONFIG_RANDOM_NUMBER_LOG_ENABLED 0 +#endif + +// + +// RTC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RTC_CONFIG_LOG_ENABLED +#define RTC_CONFIG_LOG_ENABLED 0 +#endif +// RTC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RTC_CONFIG_LOG_LEVEL +#define RTC_CONFIG_LOG_LEVEL 3 +#endif + +// RTC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_INFO_COLOR +#define RTC_CONFIG_INFO_COLOR 0 +#endif + +// RTC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_DEBUG_COLOR +#define RTC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SAADC_CONFIG_LOG_ENABLED +#define SAADC_CONFIG_LOG_ENABLED 0 +#endif +// SAADC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SAADC_CONFIG_LOG_LEVEL +#define SAADC_CONFIG_LOG_LEVEL 3 +#endif + +// SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_INFO_COLOR +#define SAADC_CONFIG_INFO_COLOR 0 +#endif + +// SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_DEBUG_COLOR +#define SAADC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// SPIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPIS_CONFIG_LOG_ENABLED +#define SPIS_CONFIG_LOG_ENABLED 0 +#endif +// SPIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPIS_CONFIG_LOG_LEVEL +#define SPIS_CONFIG_LOG_LEVEL 3 +#endif + +// SPIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_INFO_COLOR +#define SPIS_CONFIG_INFO_COLOR 0 +#endif + +// SPIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_DEBUG_COLOR +#define SPIS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// SPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPI_CONFIG_LOG_ENABLED +#define SPI_CONFIG_LOG_ENABLED 0 +#endif +// SPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPI_CONFIG_LOG_LEVEL +#define SPI_CONFIG_LOG_LEVEL 3 +#endif + +// SPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_INFO_COLOR +#define SPI_CONFIG_INFO_COLOR 0 +#endif + +// SPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_DEBUG_COLOR +#define SPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TIMER_CONFIG_LOG_ENABLED +#define TIMER_CONFIG_LOG_ENABLED 0 +#endif +// TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TIMER_CONFIG_LOG_LEVEL +#define TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_INFO_COLOR +#define TIMER_CONFIG_INFO_COLOR 0 +#endif + +// TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_DEBUG_COLOR +#define TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TWIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWIS_CONFIG_LOG_ENABLED +#define TWIS_CONFIG_LOG_ENABLED 0 +#endif +// TWIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWIS_CONFIG_LOG_LEVEL +#define TWIS_CONFIG_LOG_LEVEL 3 +#endif + +// TWIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_INFO_COLOR +#define TWIS_CONFIG_INFO_COLOR 0 +#endif + +// TWIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_DEBUG_COLOR +#define TWIS_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// TWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWI_CONFIG_LOG_ENABLED +#define TWI_CONFIG_LOG_ENABLED 0 +#endif +// TWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWI_CONFIG_LOG_LEVEL +#define TWI_CONFIG_LOG_LEVEL 3 +#endif + +// TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_INFO_COLOR +#define TWI_CONFIG_INFO_COLOR 0 +#endif + +// TWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_DEBUG_COLOR +#define TWI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef UART_CONFIG_LOG_ENABLED +#define UART_CONFIG_LOG_ENABLED 0 +#endif +// UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef UART_CONFIG_LOG_LEVEL +#define UART_CONFIG_LOG_LEVEL 3 +#endif + +// UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_INFO_COLOR +#define UART_CONFIG_INFO_COLOR 0 +#endif + +// UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_DEBUG_COLOR +#define UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// USBD_CONFIG_LOG_ENABLED - Enable logging in the module +//========================================================== +#ifndef USBD_CONFIG_LOG_ENABLED +#define USBD_CONFIG_LOG_ENABLED 0 +#endif +// USBD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef USBD_CONFIG_LOG_LEVEL +#define USBD_CONFIG_LOG_LEVEL 3 +#endif + +// USBD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef USBD_CONFIG_INFO_COLOR +#define USBD_CONFIG_INFO_COLOR 0 +#endif + +// USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef USBD_CONFIG_DEBUG_COLOR +#define USBD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// WDT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef WDT_CONFIG_LOG_ENABLED +#define WDT_CONFIG_LOG_ENABLED 0 +#endif +// WDT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef WDT_CONFIG_LOG_LEVEL +#define WDT_CONFIG_LOG_LEVEL 3 +#endif + +// WDT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_INFO_COLOR +#define WDT_CONFIG_INFO_COLOR 0 +#endif + +// WDT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_DEBUG_COLOR +#define WDT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// nrf_log in nRF_Libraries + +//========================================================== +// APP_BUTTON_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_BUTTON_CONFIG_LOG_ENABLED +#define APP_BUTTON_CONFIG_LOG_ENABLED 0 +#endif +// APP_BUTTON_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_BUTTON_CONFIG_LOG_LEVEL +#define APP_BUTTON_CONFIG_LOG_LEVEL 3 +#endif + +// APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL - Initial severity level if dynamic filtering is enabled. + + +// If module generates a lot of logs, initial log level can +// be decreased to prevent flooding. Severity level can be +// increased on instance basis. +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL +#define APP_BUTTON_CONFIG_INITIAL_LOG_LEVEL 3 +#endif + +// APP_BUTTON_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_BUTTON_CONFIG_INFO_COLOR +#define APP_BUTTON_CONFIG_INFO_COLOR 0 +#endif + +// APP_BUTTON_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_BUTTON_CONFIG_DEBUG_COLOR +#define APP_BUTTON_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_TIMER_CONFIG_LOG_ENABLED +#define APP_TIMER_CONFIG_LOG_ENABLED 0 +#endif +// APP_TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_TIMER_CONFIG_LOG_LEVEL +#define APP_TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// APP_TIMER_CONFIG_INITIAL_LOG_LEVEL - Initial severity level if dynamic filtering is enabled. + + +// If module generates a lot of logs, initial log level can +// be decreased to prevent flooding. Severity level can be +// increased on instance basis. +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_TIMER_CONFIG_INITIAL_LOG_LEVEL +#define APP_TIMER_CONFIG_INITIAL_LOG_LEVEL 3 +#endif + +// APP_TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_TIMER_CONFIG_INFO_COLOR +#define APP_TIMER_CONFIG_INFO_COLOR 0 +#endif + +// APP_TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_TIMER_CONFIG_DEBUG_COLOR +#define APP_TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED +#define APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL +#define APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_CDC_ACM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CDC_ACM_CONFIG_INFO_COLOR +#define APP_USBD_CDC_ACM_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR +#define APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_CONFIG_LOG_ENABLED - Enable logging in the module. +//========================================================== +#ifndef APP_USBD_CONFIG_LOG_ENABLED +#define APP_USBD_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_CONFIG_LOG_LEVEL +#define APP_USBD_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CONFIG_INFO_COLOR +#define APP_USBD_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_CONFIG_DEBUG_COLOR +#define APP_USBD_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_DUMMY_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_DUMMY_CONFIG_LOG_ENABLED +#define APP_USBD_DUMMY_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_DUMMY_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_DUMMY_CONFIG_LOG_LEVEL +#define APP_USBD_DUMMY_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_DUMMY_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_DUMMY_CONFIG_INFO_COLOR +#define APP_USBD_DUMMY_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_DUMMY_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_DUMMY_CONFIG_DEBUG_COLOR +#define APP_USBD_DUMMY_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_MSC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_MSC_CONFIG_LOG_ENABLED +#define APP_USBD_MSC_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_MSC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_MSC_CONFIG_LOG_LEVEL +#define APP_USBD_MSC_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_MSC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_MSC_CONFIG_INFO_COLOR +#define APP_USBD_MSC_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_MSC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_MSC_CONFIG_DEBUG_COLOR +#define APP_USBD_MSC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED 0 +#endif +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL 3 +#endif + +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR 0 +#endif + +// APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR +#define APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_ATFIFO_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_ATFIFO_CONFIG_LOG_ENABLED +#define NRF_ATFIFO_CONFIG_LOG_ENABLED 0 +#endif +// NRF_ATFIFO_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_ATFIFO_CONFIG_LOG_LEVEL +#define NRF_ATFIFO_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_ATFIFO_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_ATFIFO_CONFIG_INFO_COLOR +#define NRF_ATFIFO_CONFIG_INFO_COLOR 0 +#endif + +// NRF_ATFIFO_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_ATFIFO_CONFIG_DEBUG_COLOR +#define NRF_ATFIFO_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BALLOC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BALLOC_CONFIG_LOG_ENABLED +#define NRF_BALLOC_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BALLOC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BALLOC_CONFIG_LOG_LEVEL +#define NRF_BALLOC_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL - Initial severity level if dynamic filtering is enabled. + + +// If module generates a lot of logs, initial log level can +// be decreased to prevent flooding. Severity level can be +// increased on instance basis. +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL +#define NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL 3 +#endif + +// NRF_BALLOC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BALLOC_CONFIG_INFO_COLOR +#define NRF_BALLOC_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BALLOC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BALLOC_CONFIG_DEBUG_COLOR +#define NRF_BALLOC_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED +#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL +#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_BLOCK_DEV_EMPTY_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR +#define NRF_BLOCK_DEV_EMPTY_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR +#define NRF_BLOCK_DEV_EMPTY_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED +#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL +#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR +#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR +#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED +#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_ENABLED 0 +#endif +// NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL +#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_BLOCK_DEV_RAM_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR +#define NRF_BLOCK_DEV_RAM_CONFIG_INFO_COLOR 0 +#endif + +// NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR +#define NRF_BLOCK_DEV_RAM_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED +#define NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED 0 +#endif +// NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL +#define NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_CLI_BLE_UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_BLE_UART_CONFIG_INFO_COLOR +#define NRF_CLI_BLE_UART_CONFIG_INFO_COLOR 0 +#endif + +// NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR +#define NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED +#define NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED 0 +#endif +// NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL +#define NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR +#define NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR 0 +#endif + +// NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR +#define NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_CLI_UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_CLI_UART_CONFIG_LOG_ENABLED +#define NRF_CLI_UART_CONFIG_LOG_ENABLED 0 +#endif +// NRF_CLI_UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_CLI_UART_CONFIG_LOG_LEVEL +#define NRF_CLI_UART_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_CLI_UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_UART_CONFIG_INFO_COLOR +#define NRF_CLI_UART_CONFIG_INFO_COLOR 0 +#endif + +// NRF_CLI_UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_CLI_UART_CONFIG_DEBUG_COLOR +#define NRF_CLI_UART_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_LIBUARTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_LIBUARTE_CONFIG_LOG_ENABLED +#define NRF_LIBUARTE_CONFIG_LOG_ENABLED 0 +#endif +// NRF_LIBUARTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_LIBUARTE_CONFIG_LOG_LEVEL +#define NRF_LIBUARTE_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_LIBUARTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LIBUARTE_CONFIG_INFO_COLOR +#define NRF_LIBUARTE_CONFIG_INFO_COLOR 0 +#endif + +// NRF_LIBUARTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LIBUARTE_CONFIG_DEBUG_COLOR +#define NRF_LIBUARTE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_MEMOBJ_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_MEMOBJ_CONFIG_LOG_ENABLED +#define NRF_MEMOBJ_CONFIG_LOG_ENABLED 0 +#endif +// NRF_MEMOBJ_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_MEMOBJ_CONFIG_LOG_LEVEL +#define NRF_MEMOBJ_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_MEMOBJ_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MEMOBJ_CONFIG_INFO_COLOR +#define NRF_MEMOBJ_CONFIG_INFO_COLOR 0 +#endif + +// NRF_MEMOBJ_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_MEMOBJ_CONFIG_DEBUG_COLOR +#define NRF_MEMOBJ_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_PWR_MGMT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_PWR_MGMT_CONFIG_LOG_ENABLED +#define NRF_PWR_MGMT_CONFIG_LOG_ENABLED 0 +#endif +// NRF_PWR_MGMT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_PWR_MGMT_CONFIG_LOG_LEVEL +#define NRF_PWR_MGMT_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_PWR_MGMT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_PWR_MGMT_CONFIG_INFO_COLOR +#define NRF_PWR_MGMT_CONFIG_INFO_COLOR 0 +#endif + +// NRF_PWR_MGMT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_PWR_MGMT_CONFIG_DEBUG_COLOR +#define NRF_PWR_MGMT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_QUEUE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_QUEUE_CONFIG_LOG_ENABLED +#define NRF_QUEUE_CONFIG_LOG_ENABLED 0 +#endif +// NRF_QUEUE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_QUEUE_CONFIG_LOG_LEVEL +#define NRF_QUEUE_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL +#define NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL 3 +#endif + +// NRF_QUEUE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_QUEUE_CONFIG_INFO_COLOR +#define NRF_QUEUE_CONFIG_INFO_COLOR 0 +#endif + +// NRF_QUEUE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_QUEUE_CONFIG_DEBUG_COLOR +#define NRF_QUEUE_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_ANT_LOG_ENABLED - Enable logging in SoftDevice handler (ANT) module. +//========================================================== +#ifndef NRF_SDH_ANT_LOG_ENABLED +#define NRF_SDH_ANT_LOG_ENABLED 0 +#endif +// NRF_SDH_ANT_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_ANT_LOG_LEVEL +#define NRF_SDH_ANT_LOG_LEVEL 3 +#endif + +// NRF_SDH_ANT_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_ANT_INFO_COLOR +#define NRF_SDH_ANT_INFO_COLOR 0 +#endif + +// NRF_SDH_ANT_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_ANT_DEBUG_COLOR +#define NRF_SDH_ANT_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_BLE_LOG_ENABLED - Enable logging in SoftDevice handler (BLE) module. +//========================================================== +#ifndef NRF_SDH_BLE_LOG_ENABLED +#define NRF_SDH_BLE_LOG_ENABLED 1 +#endif +// NRF_SDH_BLE_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_BLE_LOG_LEVEL +#define NRF_SDH_BLE_LOG_LEVEL 3 +#endif + +// NRF_SDH_BLE_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_BLE_INFO_COLOR +#define NRF_SDH_BLE_INFO_COLOR 0 +#endif + +// NRF_SDH_BLE_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_BLE_DEBUG_COLOR +#define NRF_SDH_BLE_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_LOG_ENABLED - Enable logging in SoftDevice handler module. +//========================================================== +#ifndef NRF_SDH_LOG_ENABLED +#define NRF_SDH_LOG_ENABLED 1 +#endif +// NRF_SDH_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_LOG_LEVEL +#define NRF_SDH_LOG_LEVEL 3 +#endif + +// NRF_SDH_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_INFO_COLOR +#define NRF_SDH_INFO_COLOR 0 +#endif + +// NRF_SDH_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_DEBUG_COLOR +#define NRF_SDH_DEBUG_COLOR 0 +#endif + +// + +// NRF_SDH_SOC_LOG_ENABLED - Enable logging in SoftDevice handler (SoC) module. +//========================================================== +#ifndef NRF_SDH_SOC_LOG_ENABLED +#define NRF_SDH_SOC_LOG_ENABLED 1 +#endif +// NRF_SDH_SOC_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SDH_SOC_LOG_LEVEL +#define NRF_SDH_SOC_LOG_LEVEL 3 +#endif + +// NRF_SDH_SOC_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_SOC_INFO_COLOR +#define NRF_SDH_SOC_INFO_COLOR 0 +#endif + +// NRF_SDH_SOC_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SDH_SOC_DEBUG_COLOR +#define NRF_SDH_SOC_DEBUG_COLOR 0 +#endif + +// + +// NRF_SORTLIST_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_SORTLIST_CONFIG_LOG_ENABLED +#define NRF_SORTLIST_CONFIG_LOG_ENABLED 0 +#endif +// NRF_SORTLIST_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_SORTLIST_CONFIG_LOG_LEVEL +#define NRF_SORTLIST_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_SORTLIST_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SORTLIST_CONFIG_INFO_COLOR +#define NRF_SORTLIST_CONFIG_INFO_COLOR 0 +#endif + +// NRF_SORTLIST_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_SORTLIST_CONFIG_DEBUG_COLOR +#define NRF_SORTLIST_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// NRF_TWI_SENSOR_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NRF_TWI_SENSOR_CONFIG_LOG_ENABLED +#define NRF_TWI_SENSOR_CONFIG_LOG_ENABLED 0 +#endif +// NRF_TWI_SENSOR_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_TWI_SENSOR_CONFIG_LOG_LEVEL +#define NRF_TWI_SENSOR_CONFIG_LOG_LEVEL 3 +#endif + +// NRF_TWI_SENSOR_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_TWI_SENSOR_CONFIG_INFO_COLOR +#define NRF_TWI_SENSOR_CONFIG_INFO_COLOR 0 +#endif + +// NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR +#define NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// PM_LOG_ENABLED - Enable logging in Peer Manager and its submodules. +//========================================================== +#ifndef PM_LOG_ENABLED +#define PM_LOG_ENABLED 1 +#endif +// PM_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PM_LOG_LEVEL +#define PM_LOG_LEVEL 3 +#endif + +// PM_LOG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PM_LOG_INFO_COLOR +#define PM_LOG_INFO_COLOR 0 +#endif + +// PM_LOG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PM_LOG_DEBUG_COLOR +#define PM_LOG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// nrf_log in nRF_Serialization + +//========================================================== +// SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED +#define SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED 0 +#endif +// SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL +#define SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL 3 +#endif + +// SER_HAL_TRANSPORT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SER_HAL_TRANSPORT_CONFIG_INFO_COLOR +#define SER_HAL_TRANSPORT_CONFIG_INFO_COLOR 0 +#endif + +// SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR +#define SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR 0 +#endif + +// + +// +//========================================================== + +// +//========================================================== + +// + +// NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED - nrf_log_str_formatter - Log string formatter + + +#ifndef NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED +#define NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED 1 +#endif + +// +//========================================================== + +// nRF_NFC + +//========================================================== +// NFC_AC_REC_ENABLED - nfc_ac_rec - NFC NDEF Alternative Carrier record encoder + + +#ifndef NFC_AC_REC_ENABLED +#define NFC_AC_REC_ENABLED 0 +#endif + +// NFC_AC_REC_PARSER_ENABLED - nfc_ac_rec_parser - Alternative Carrier record parser + + +#ifndef NFC_AC_REC_PARSER_ENABLED +#define NFC_AC_REC_PARSER_ENABLED 0 +#endif + +// NFC_BLE_OOB_ADVDATA_ENABLED - nfc_ble_oob_advdata - AD data for OOB pairing encoder +//========================================================== +#ifndef NFC_BLE_OOB_ADVDATA_ENABLED +#define NFC_BLE_OOB_ADVDATA_ENABLED 0 +#endif +// ADVANCED_ADVDATA_SUPPORT - Non-mandatory AD types for BLE OOB pairing are encoded inside the NDEF message (e.g. service UUIDs) + +// <1=> Enabled +// <0=> Disabled + +#ifndef ADVANCED_ADVDATA_SUPPORT +#define ADVANCED_ADVDATA_SUPPORT 0 +#endif + +// + +// NFC_BLE_OOB_ADVDATA_PARSER_ENABLED - nfc_ble_oob_advdata_parser - BLE OOB pairing AD data parser + + +#ifndef NFC_BLE_OOB_ADVDATA_PARSER_ENABLED +#define NFC_BLE_OOB_ADVDATA_PARSER_ENABLED 0 +#endif + +// NFC_BLE_PAIR_LIB_ENABLED - nfc_ble_pair_lib - Library parameters +//========================================================== +#ifndef NFC_BLE_PAIR_LIB_ENABLED +#define NFC_BLE_PAIR_LIB_ENABLED 0 +#endif +// NFC_BLE_PAIR_LIB_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_BLE_PAIR_LIB_LOG_ENABLED +#define NFC_BLE_PAIR_LIB_LOG_ENABLED 0 +#endif +// NFC_BLE_PAIR_LIB_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_BLE_PAIR_LIB_LOG_LEVEL +#define NFC_BLE_PAIR_LIB_LOG_LEVEL 3 +#endif + +// NFC_BLE_PAIR_LIB_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_BLE_PAIR_LIB_INFO_COLOR +#define NFC_BLE_PAIR_LIB_INFO_COLOR 0 +#endif + +// NFC_BLE_PAIR_LIB_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_BLE_PAIR_LIB_DEBUG_COLOR +#define NFC_BLE_PAIR_LIB_DEBUG_COLOR 0 +#endif + +// + +// NFC_BLE_PAIR_LIB_SECURITY_PARAMETERS - Common Peer Manager security parameters. + +//========================================================== +// BLE_NFC_SEC_PARAM_BOND - Enables device bonding. + +// If bonding is enabled at least one of the BLE_NFC_SEC_PARAM_KDIST options must be enabled. +//========================================================== +#ifndef BLE_NFC_SEC_PARAM_BOND +#define BLE_NFC_SEC_PARAM_BOND 1 +#endif +// BLE_NFC_SEC_PARAM_KDIST_OWN_ENC - Enables Long Term Key and Master Identification distribution by device. + + +#ifndef BLE_NFC_SEC_PARAM_KDIST_OWN_ENC +#define BLE_NFC_SEC_PARAM_KDIST_OWN_ENC 1 +#endif + +// BLE_NFC_SEC_PARAM_KDIST_OWN_ID - Enables Identity Resolving Key and Identity Address Information distribution by device. + + +#ifndef BLE_NFC_SEC_PARAM_KDIST_OWN_ID +#define BLE_NFC_SEC_PARAM_KDIST_OWN_ID 1 +#endif + +// BLE_NFC_SEC_PARAM_KDIST_PEER_ENC - Enables Long Term Key and Master Identification distribution by peer. + + +#ifndef BLE_NFC_SEC_PARAM_KDIST_PEER_ENC +#define BLE_NFC_SEC_PARAM_KDIST_PEER_ENC 1 +#endif + +// BLE_NFC_SEC_PARAM_KDIST_PEER_ID - Enables Identity Resolving Key and Identity Address Information distribution by peer. + + +#ifndef BLE_NFC_SEC_PARAM_KDIST_PEER_ID +#define BLE_NFC_SEC_PARAM_KDIST_PEER_ID 1 +#endif + +// + +// BLE_NFC_SEC_PARAM_MIN_KEY_SIZE - Minimal size of a security key. + +// <7=> 7 +// <8=> 8 +// <9=> 9 +// <10=> 10 +// <11=> 11 +// <12=> 12 +// <13=> 13 +// <14=> 14 +// <15=> 15 +// <16=> 16 + +#ifndef BLE_NFC_SEC_PARAM_MIN_KEY_SIZE +#define BLE_NFC_SEC_PARAM_MIN_KEY_SIZE 7 +#endif + +// BLE_NFC_SEC_PARAM_MAX_KEY_SIZE - Maximal size of a security key. + +// <7=> 7 +// <8=> 8 +// <9=> 9 +// <10=> 10 +// <11=> 11 +// <12=> 12 +// <13=> 13 +// <14=> 14 +// <15=> 15 +// <16=> 16 + +#ifndef BLE_NFC_SEC_PARAM_MAX_KEY_SIZE +#define BLE_NFC_SEC_PARAM_MAX_KEY_SIZE 16 +#endif + +// +//========================================================== + +// + +// NFC_BLE_PAIR_MSG_ENABLED - nfc_ble_pair_msg - NDEF message for OOB pairing encoder + + +#ifndef NFC_BLE_PAIR_MSG_ENABLED +#define NFC_BLE_PAIR_MSG_ENABLED 0 +#endif + +// NFC_CH_COMMON_ENABLED - nfc_ble_pair_common - OOB pairing common data + + +#ifndef NFC_CH_COMMON_ENABLED +#define NFC_CH_COMMON_ENABLED 0 +#endif + +// NFC_EP_OOB_REC_ENABLED - nfc_ep_oob_rec - EP record for BLE pairing encoder + + +#ifndef NFC_EP_OOB_REC_ENABLED +#define NFC_EP_OOB_REC_ENABLED 0 +#endif + +// NFC_HS_REC_ENABLED - nfc_hs_rec - Handover Select NDEF record encoder + + +#ifndef NFC_HS_REC_ENABLED +#define NFC_HS_REC_ENABLED 0 +#endif + +// NFC_LE_OOB_REC_ENABLED - nfc_le_oob_rec - LE record for BLE pairing encoder + + +#ifndef NFC_LE_OOB_REC_ENABLED +#define NFC_LE_OOB_REC_ENABLED 0 +#endif + +// NFC_LE_OOB_REC_PARSER_ENABLED - nfc_le_oob_rec_parser - LE record parser + + +#ifndef NFC_LE_OOB_REC_PARSER_ENABLED +#define NFC_LE_OOB_REC_PARSER_ENABLED 0 +#endif + +// NFC_NDEF_LAUNCHAPP_MSG_ENABLED - nfc_launchapp_msg - Encoding data for NDEF Application Launching message for NFC Tag + + +#ifndef NFC_NDEF_LAUNCHAPP_MSG_ENABLED +#define NFC_NDEF_LAUNCHAPP_MSG_ENABLED 0 +#endif + +// NFC_NDEF_LAUNCHAPP_REC_ENABLED - nfc_launchapp_rec - Encoding data for NDEF Application Launching record for NFC Tag + + +#ifndef NFC_NDEF_LAUNCHAPP_REC_ENABLED +#define NFC_NDEF_LAUNCHAPP_REC_ENABLED 0 +#endif + +// NFC_NDEF_MSG_ENABLED - nfc_ndef_msg - NFC NDEF Message generator module +//========================================================== +#ifndef NFC_NDEF_MSG_ENABLED +#define NFC_NDEF_MSG_ENABLED 0 +#endif +// NFC_NDEF_MSG_TAG_TYPE - NFC Tag Type + +// <2=> Type 2 Tag +// <4=> Type 4 Tag + +#ifndef NFC_NDEF_MSG_TAG_TYPE +#define NFC_NDEF_MSG_TAG_TYPE 2 +#endif + +// + +// NFC_NDEF_MSG_PARSER_ENABLED - nfc_ndef_msg_parser - NFC NDEF message parser module +//========================================================== +#ifndef NFC_NDEF_MSG_PARSER_ENABLED +#define NFC_NDEF_MSG_PARSER_ENABLED 0 +#endif +// NFC_NDEF_MSG_PARSER_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NFC_NDEF_MSG_PARSER_LOG_ENABLED 0 +#endif +// NFC_NDEF_MSG_PARSER_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_NDEF_MSG_PARSER_LOG_LEVEL +#define NFC_NDEF_MSG_PARSER_LOG_LEVEL 3 +#endif + +// NFC_NDEF_MSG_PARSER_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_NDEF_MSG_PARSER_INFO_COLOR +#define NFC_NDEF_MSG_PARSER_INFO_COLOR 0 +#endif + +// + +// + +// NFC_NDEF_RECORD_ENABLED - nfc_ndef_record - NFC NDEF Record generator module + + +#ifndef NFC_NDEF_RECORD_ENABLED +#define NFC_NDEF_RECORD_ENABLED 0 +#endif + +// NFC_NDEF_RECORD_PARSER_ENABLED - nfc_ndef_record_parser - NFC NDEF Record parser module +//========================================================== +#ifndef NFC_NDEF_RECORD_PARSER_ENABLED +#define NFC_NDEF_RECORD_PARSER_ENABLED 0 +#endif +// NFC_NDEF_RECORD_PARSER_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NFC_NDEF_RECORD_PARSER_LOG_ENABLED 0 +#endif +// NFC_NDEF_RECORD_PARSER_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_NDEF_RECORD_PARSER_LOG_LEVEL +#define NFC_NDEF_RECORD_PARSER_LOG_LEVEL 3 +#endif + +// NFC_NDEF_RECORD_PARSER_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_NDEF_RECORD_PARSER_INFO_COLOR +#define NFC_NDEF_RECORD_PARSER_INFO_COLOR 0 +#endif + +// + +// + +// NFC_NDEF_TEXT_RECORD_ENABLED - nfc_text_rec - Encoding data for a text record for NFC Tag + + +#ifndef NFC_NDEF_TEXT_RECORD_ENABLED +#define NFC_NDEF_TEXT_RECORD_ENABLED 0 +#endif + +// NFC_NDEF_URI_MSG_ENABLED - nfc_uri_msg - Encoding data for NDEF message with URI record for NFC Tag + + +#ifndef NFC_NDEF_URI_MSG_ENABLED +#define NFC_NDEF_URI_MSG_ENABLED 0 +#endif + +// NFC_NDEF_URI_REC_ENABLED - nfc_uri_rec - Encoding data for a URI record for NFC Tag + + +#ifndef NFC_NDEF_URI_REC_ENABLED +#define NFC_NDEF_URI_REC_ENABLED 0 +#endif + +// NFC_PLATFORM_ENABLED - nfc_platform - NFC platform module for Clock control. +//========================================================== +#ifndef NFC_PLATFORM_ENABLED +#define NFC_PLATFORM_ENABLED 0 +#endif +// NFC_PLATFORM_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_PLATFORM_LOG_ENABLED +#define NFC_PLATFORM_LOG_ENABLED 0 +#endif +// NFC_PLATFORM_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_PLATFORM_LOG_LEVEL +#define NFC_PLATFORM_LOG_LEVEL 3 +#endif + +// NFC_PLATFORM_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_PLATFORM_INFO_COLOR +#define NFC_PLATFORM_INFO_COLOR 0 +#endif + +// NFC_PLATFORM_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_PLATFORM_DEBUG_COLOR +#define NFC_PLATFORM_DEBUG_COLOR 0 +#endif + +// + +// + +// NFC_T2T_PARSER_ENABLED - nfc_type_2_tag_parser - Parser for decoding Type 2 Tag data +//========================================================== +#ifndef NFC_T2T_PARSER_ENABLED +#define NFC_T2T_PARSER_ENABLED 0 +#endif +// NFC_T2T_PARSER_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_T2T_PARSER_LOG_ENABLED +#define NFC_T2T_PARSER_LOG_ENABLED 0 +#endif +// NFC_T2T_PARSER_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_T2T_PARSER_LOG_LEVEL +#define NFC_T2T_PARSER_LOG_LEVEL 3 +#endif + +// NFC_T2T_PARSER_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_T2T_PARSER_INFO_COLOR +#define NFC_T2T_PARSER_INFO_COLOR 0 +#endif + +// + +// + +// NFC_T4T_APDU_ENABLED - nfc_t4t_apdu - APDU encoder/decoder for Type 4 Tag +//========================================================== +#ifndef NFC_T4T_APDU_ENABLED +#define NFC_T4T_APDU_ENABLED 0 +#endif +// NFC_T4T_APDU_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_T4T_APDU_LOG_ENABLED +#define NFC_T4T_APDU_LOG_ENABLED 0 +#endif +// NFC_T4T_APDU_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_T4T_APDU_LOG_LEVEL +#define NFC_T4T_APDU_LOG_LEVEL 3 +#endif + +// NFC_T4T_APDU_LOG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_T4T_APDU_LOG_COLOR +#define NFC_T4T_APDU_LOG_COLOR 0 +#endif + +// + +// + +// NFC_T4T_CC_FILE_PARSER_ENABLED - nfc_t4t_cc_file - Capability Container file for Type 4 Tag +//========================================================== +#ifndef NFC_T4T_CC_FILE_PARSER_ENABLED +#define NFC_T4T_CC_FILE_PARSER_ENABLED 0 +#endif +// NFC_T4T_CC_FILE_PARSER_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NFC_T4T_CC_FILE_PARSER_LOG_ENABLED 0 +#endif +// NFC_T4T_CC_FILE_PARSER_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_T4T_CC_FILE_PARSER_LOG_LEVEL +#define NFC_T4T_CC_FILE_PARSER_LOG_LEVEL 3 +#endif + +// NFC_T4T_CC_FILE_PARSER_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_T4T_CC_FILE_PARSER_INFO_COLOR +#define NFC_T4T_CC_FILE_PARSER_INFO_COLOR 0 +#endif + +// + +// + +// NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED - nfc_t4t_hl_detection_procedures - NDEF Detection Procedure for Type 4 Tag +//========================================================== +#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED +#define NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED 0 +#endif +// NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED 0 +#endif +// NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL +#define NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL 3 +#endif + +// NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR +#define NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR 0 +#endif + +// + +// APDU_BUFF_SIZE - Size (in bytes) of the buffer for APDU storage +#ifndef APDU_BUFF_SIZE +#define APDU_BUFF_SIZE 250 +#endif + +// CC_STORAGE_BUFF_SIZE - Size (in bytes) of the buffer for CC file storage +#ifndef CC_STORAGE_BUFF_SIZE +#define CC_STORAGE_BUFF_SIZE 64 +#endif + +// + +// NFC_T4T_TLV_BLOCK_PARSER_ENABLED - nfc_t4t_tlv_block - TLV block for Type 4 Tag +//========================================================== +#ifndef NFC_T4T_TLV_BLOCK_PARSER_ENABLED +#define NFC_T4T_TLV_BLOCK_PARSER_ENABLED 0 +#endif +// NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED 0 +#endif +// NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL +#define NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL 3 +#endif + +// NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR +#define NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR 0 +#endif + +// + +// + +// +//========================================================== + +// nRF_Segger_RTT + +//========================================================== +// segger_rtt - SEGGER RTT + +//========================================================== +// SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. +// Note that either @ref NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE +// or this value is actually used. It depends on which one is bigger. + +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 512 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Maximum number of upstream buffers. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of downstream buffer. +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Maximum number of downstream buffers. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_DEFAULT_MODE - RTT behavior if the buffer is full. + + +// The following modes are supported: +// - SKIP - Do not block, output nothing. +// - TRIM - Do not block, output as much as fits. +// - BLOCK - Wait until there is space in the buffer. +// <0=> SKIP +// <1=> TRIM +// <2=> BLOCK_IF_FIFO_FULL + +#ifndef SEGGER_RTT_CONFIG_DEFAULT_MODE +#define SEGGER_RTT_CONFIG_DEFAULT_MODE 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_SoftDevice + +//========================================================== +// NRF_SDH_BLE_ENABLED - nrf_sdh_ble - SoftDevice BLE event handler +//========================================================== +#ifndef NRF_SDH_BLE_ENABLED +#define NRF_SDH_BLE_ENABLED 1 +#endif +// BLE Stack configuration - Stack configuration parameters + +// The SoftDevice handler will configure the stack with these parameters when calling @ref nrf_sdh_ble_default_cfg_set. +// Other libraries might depend on these values; keep them up-to-date even if you are not explicitely calling @ref nrf_sdh_ble_default_cfg_set. +//========================================================== +// NRF_SDH_BLE_GAP_DATA_LENGTH <27-251> + + +// Requested BLE GAP data length to be negotiated. + +#ifndef NRF_SDH_BLE_GAP_DATA_LENGTH +#define NRF_SDH_BLE_GAP_DATA_LENGTH 251 +#endif + +// NRF_SDH_BLE_PERIPHERAL_LINK_COUNT - Maximum number of peripheral links. +#ifndef NRF_SDH_BLE_PERIPHERAL_LINK_COUNT +#define NRF_SDH_BLE_PERIPHERAL_LINK_COUNT 1 +#endif + +// NRF_SDH_BLE_CENTRAL_LINK_COUNT - Maximum number of central links. +#ifndef NRF_SDH_BLE_CENTRAL_LINK_COUNT +#define NRF_SDH_BLE_CENTRAL_LINK_COUNT 0 +#endif + +// NRF_SDH_BLE_TOTAL_LINK_COUNT - Total link count. +// Maximum number of total concurrent connections using the default configuration. + +#ifndef NRF_SDH_BLE_TOTAL_LINK_COUNT +#define NRF_SDH_BLE_TOTAL_LINK_COUNT 1 +#endif + +// NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length. +// The time set aside for this connection on every connection interval in 1.25 ms units. + +#ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH +#define NRF_SDH_BLE_GAP_EVENT_LENGTH 6 +#endif + +// NRF_SDH_BLE_GATT_MAX_MTU_SIZE - Static maximum MTU size. +#ifndef NRF_SDH_BLE_GATT_MAX_MTU_SIZE +#define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247 +#endif + +// NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE - Attribute Table size in bytes. The size must be a multiple of 4. +#ifndef NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE +#define NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE 1408 +#endif + +// NRF_SDH_BLE_VS_UUID_COUNT - The number of vendor-specific UUIDs. +#ifndef NRF_SDH_BLE_VS_UUID_COUNT +#define NRF_SDH_BLE_VS_UUID_COUNT 1 +#endif + +// NRF_SDH_BLE_SERVICE_CHANGED - Include the Service Changed characteristic in the Attribute Table. + + +#ifndef NRF_SDH_BLE_SERVICE_CHANGED +#define NRF_SDH_BLE_SERVICE_CHANGED 0 +#endif + +// +//========================================================== + +// BLE Observers - Observers and priority levels + +//========================================================== +// NRF_SDH_BLE_OBSERVER_PRIO_LEVELS - Total number of priority levels for BLE observers. +// This setting configures the number of priority levels available for BLE event handlers. +// The priority level of a handler determines the order in which it receives events, with respect to other handlers. + +#ifndef NRF_SDH_BLE_OBSERVER_PRIO_LEVELS +#define NRF_SDH_BLE_OBSERVER_PRIO_LEVELS 4 +#endif + +// BLE Observers priorities - Invididual priorities + +//========================================================== +// BLE_ADV_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Advertising module. + +#ifndef BLE_ADV_BLE_OBSERVER_PRIO +#define BLE_ADV_BLE_OBSERVER_PRIO 1 +#endif + +// BLE_ANCS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Apple Notification Service Client. + +#ifndef BLE_ANCS_C_BLE_OBSERVER_PRIO +#define BLE_ANCS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_ANS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Alert Notification Service Client. + +#ifndef BLE_ANS_C_BLE_OBSERVER_PRIO +#define BLE_ANS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_BAS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Battery Service. + +#ifndef BLE_BAS_BLE_OBSERVER_PRIO +#define BLE_BAS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_BAS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Battery Service Client. + +#ifndef BLE_BAS_C_BLE_OBSERVER_PRIO +#define BLE_BAS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_BPS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Blood Pressure Service. + +#ifndef BLE_BPS_BLE_OBSERVER_PRIO +#define BLE_BPS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_CONN_PARAMS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Connection parameters module. + +#ifndef BLE_CONN_PARAMS_BLE_OBSERVER_PRIO +#define BLE_CONN_PARAMS_BLE_OBSERVER_PRIO 1 +#endif + +// BLE_CONN_STATE_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Connection State module. + +#ifndef BLE_CONN_STATE_BLE_OBSERVER_PRIO +#define BLE_CONN_STATE_BLE_OBSERVER_PRIO 0 +#endif + +// BLE_CSCS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Cycling Speed and Cadence Service. + +#ifndef BLE_CSCS_BLE_OBSERVER_PRIO +#define BLE_CSCS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_CTS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Current Time Service Client. + +#ifndef BLE_CTS_C_BLE_OBSERVER_PRIO +#define BLE_CTS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_DB_DISC_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Database Discovery module. + +#ifndef BLE_DB_DISC_BLE_OBSERVER_PRIO +#define BLE_DB_DISC_BLE_OBSERVER_PRIO 1 +#endif + +// BLE_DFU_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the DFU Service. + +#ifndef BLE_DFU_BLE_OBSERVER_PRIO +#define BLE_DFU_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_DIS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Device Information Client. + +#ifndef BLE_DIS_C_BLE_OBSERVER_PRIO +#define BLE_DIS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_GLS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Glucose Service. + +#ifndef BLE_GLS_BLE_OBSERVER_PRIO +#define BLE_GLS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_HIDS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Human Interface Device Service. + +#ifndef BLE_HIDS_BLE_OBSERVER_PRIO +#define BLE_HIDS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_HRS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Heart Rate Service. + +#ifndef BLE_HRS_BLE_OBSERVER_PRIO +#define BLE_HRS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_HRS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Heart Rate Service Client. + +#ifndef BLE_HRS_C_BLE_OBSERVER_PRIO +#define BLE_HRS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_HTS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Health Thermometer Service. + +#ifndef BLE_HTS_BLE_OBSERVER_PRIO +#define BLE_HTS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_IAS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Immediate Alert Service. + +#ifndef BLE_IAS_BLE_OBSERVER_PRIO +#define BLE_IAS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_IAS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Immediate Alert Service Client. + +#ifndef BLE_IAS_C_BLE_OBSERVER_PRIO +#define BLE_IAS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_LBS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the LED Button Service. + +#ifndef BLE_LBS_BLE_OBSERVER_PRIO +#define BLE_LBS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_LBS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the LED Button Service Client. + +#ifndef BLE_LBS_C_BLE_OBSERVER_PRIO +#define BLE_LBS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_LLS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Link Loss Service. + +#ifndef BLE_LLS_BLE_OBSERVER_PRIO +#define BLE_LLS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_LNS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Location Navigation Service. + +#ifndef BLE_LNS_BLE_OBSERVER_PRIO +#define BLE_LNS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_NUS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the UART Service. + +#ifndef BLE_NUS_BLE_OBSERVER_PRIO +#define BLE_NUS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_NUS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the UART Central Service. + +#ifndef BLE_NUS_C_BLE_OBSERVER_PRIO +#define BLE_NUS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_OTS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Object transfer service. + +#ifndef BLE_OTS_BLE_OBSERVER_PRIO +#define BLE_OTS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_OTS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Object transfer service client. + +#ifndef BLE_OTS_C_BLE_OBSERVER_PRIO +#define BLE_OTS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_RSCS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Running Speed and Cadence Service. + +#ifndef BLE_RSCS_BLE_OBSERVER_PRIO +#define BLE_RSCS_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_RSCS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Running Speed and Cadence Client. + +#ifndef BLE_RSCS_C_BLE_OBSERVER_PRIO +#define BLE_RSCS_C_BLE_OBSERVER_PRIO 2 +#endif + +// BLE_TPS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the TX Power Service. + +#ifndef BLE_TPS_BLE_OBSERVER_PRIO +#define BLE_TPS_BLE_OBSERVER_PRIO 2 +#endif + +// BSP_BTN_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Button Control module. + +#ifndef BSP_BTN_BLE_OBSERVER_PRIO +#define BSP_BTN_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the NFC pairing library. + +#ifndef NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO +#define NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO 1 +#endif + +// NRF_BLE_BMS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Bond Management Service. + +#ifndef NRF_BLE_BMS_BLE_OBSERVER_PRIO +#define NRF_BLE_BMS_BLE_OBSERVER_PRIO 2 +#endif + +// NRF_BLE_CGMS_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Contiuon Glucose Monitoring Service. + +#ifndef NRF_BLE_CGMS_BLE_OBSERVER_PRIO +#define NRF_BLE_CGMS_BLE_OBSERVER_PRIO 2 +#endif + +// NRF_BLE_ES_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Eddystone module. + +#ifndef NRF_BLE_ES_BLE_OBSERVER_PRIO +#define NRF_BLE_ES_BLE_OBSERVER_PRIO 2 +#endif + +// NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the GATT Service Client. + +#ifndef NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO +#define NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO 2 +#endif + +// NRF_BLE_GATT_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the GATT module. + +#ifndef NRF_BLE_GATT_BLE_OBSERVER_PRIO +#define NRF_BLE_GATT_BLE_OBSERVER_PRIO 1 +#endif + +// NRF_BLE_GQ_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the GATT Queue module. + +#ifndef NRF_BLE_GQ_BLE_OBSERVER_PRIO +#define NRF_BLE_GQ_BLE_OBSERVER_PRIO 1 +#endif + +// NRF_BLE_QWR_BLE_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the Queued writes module. + +#ifndef NRF_BLE_QWR_BLE_OBSERVER_PRIO +#define NRF_BLE_QWR_BLE_OBSERVER_PRIO 2 +#endif + +// NRF_BLE_SCAN_OBSERVER_PRIO +// Priority for dispatching the BLE events to the Scanning Module. + +#ifndef NRF_BLE_SCAN_OBSERVER_PRIO +#define NRF_BLE_SCAN_OBSERVER_PRIO 1 +#endif + +// PM_BLE_OBSERVER_PRIO - Priority with which BLE events are dispatched to the Peer Manager module. +#ifndef PM_BLE_OBSERVER_PRIO +#define PM_BLE_OBSERVER_PRIO 1 +#endif + +// +//========================================================== + +// +//========================================================== + + +// + +// NRF_SDH_ENABLED - nrf_sdh - SoftDevice handler +//========================================================== +#ifndef NRF_SDH_ENABLED +#define NRF_SDH_ENABLED 1 +#endif +// Dispatch model + +// This setting configures how Stack events are dispatched to the application. +//========================================================== +// NRF_SDH_DISPATCH_MODEL + + +// NRF_SDH_DISPATCH_MODEL_INTERRUPT: SoftDevice events are passed to the application from the interrupt context. +// NRF_SDH_DISPATCH_MODEL_APPSH: SoftDevice events are scheduled using @ref app_scheduler. +// NRF_SDH_DISPATCH_MODEL_POLLING: SoftDevice events are to be fetched manually. +// <0=> NRF_SDH_DISPATCH_MODEL_INTERRUPT +// <1=> NRF_SDH_DISPATCH_MODEL_APPSH +// <2=> NRF_SDH_DISPATCH_MODEL_POLLING + +#ifndef NRF_SDH_DISPATCH_MODEL +#define NRF_SDH_DISPATCH_MODEL 1 +#endif + +// +//========================================================== + +// Clock - SoftDevice clock configuration + +//========================================================== +// NRF_SDH_CLOCK_LF_SRC - SoftDevice clock source. + +// <0=> NRF_CLOCK_LF_SRC_RC +// <1=> NRF_CLOCK_LF_SRC_XTAL +// <2=> NRF_CLOCK_LF_SRC_SYNTH + +#ifndef NRF_SDH_CLOCK_LF_SRC +#define NRF_SDH_CLOCK_LF_SRC 1 +#endif + +// NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. +#ifndef NRF_SDH_CLOCK_LF_RC_CTIV +#define NRF_SDH_CLOCK_LF_RC_CTIV 0 +#endif + +// NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. +// How often (in number of calibration intervals) the RC oscillator shall be calibrated +// if the temperature has not changed. + +#ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV +#define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0 +#endif + +// NRF_SDH_CLOCK_LF_ACCURACY - External clock accuracy used in the LL to compute timing. + +// <0=> NRF_CLOCK_LF_ACCURACY_250_PPM +// <1=> NRF_CLOCK_LF_ACCURACY_500_PPM +// <2=> NRF_CLOCK_LF_ACCURACY_150_PPM +// <3=> NRF_CLOCK_LF_ACCURACY_100_PPM +// <4=> NRF_CLOCK_LF_ACCURACY_75_PPM +// <5=> NRF_CLOCK_LF_ACCURACY_50_PPM +// <6=> NRF_CLOCK_LF_ACCURACY_30_PPM +// <7=> NRF_CLOCK_LF_ACCURACY_20_PPM +// <8=> NRF_CLOCK_LF_ACCURACY_10_PPM +// <9=> NRF_CLOCK_LF_ACCURACY_5_PPM +// <10=> NRF_CLOCK_LF_ACCURACY_2_PPM +// <11=> NRF_CLOCK_LF_ACCURACY_1_PPM + +#ifndef NRF_SDH_CLOCK_LF_ACCURACY +#define NRF_SDH_CLOCK_LF_ACCURACY 7 +#endif + +// +//========================================================== + +// SDH Observers - Observers and priority levels + +//========================================================== +// NRF_SDH_REQ_OBSERVER_PRIO_LEVELS - Total number of priority levels for request observers. +// This setting configures the number of priority levels available for the SoftDevice request event handlers. +// The priority level of a handler determines the order in which it receives events, with respect to other handlers. + +#ifndef NRF_SDH_REQ_OBSERVER_PRIO_LEVELS +#define NRF_SDH_REQ_OBSERVER_PRIO_LEVELS 2 +#endif + +// NRF_SDH_STATE_OBSERVER_PRIO_LEVELS - Total number of priority levels for state observers. +// This setting configures the number of priority levels available for the SoftDevice state event handlers. +// The priority level of a handler determines the order in which it receives events, with respect to other handlers. + +#ifndef NRF_SDH_STATE_OBSERVER_PRIO_LEVELS +#define NRF_SDH_STATE_OBSERVER_PRIO_LEVELS 2 +#endif + +// NRF_SDH_STACK_OBSERVER_PRIO_LEVELS - Total number of priority levels for stack event observers. +// This setting configures the number of priority levels available for the SoftDevice stack event handlers (ANT, BLE, SoC). +// The priority level of a handler determines the order in which it receives events, with respect to other handlers. + +#ifndef NRF_SDH_STACK_OBSERVER_PRIO_LEVELS +#define NRF_SDH_STACK_OBSERVER_PRIO_LEVELS 2 +#endif + + +// State Observers priorities - Invididual priorities + +//========================================================== +// CLOCK_CONFIG_STATE_OBSERVER_PRIO +// Priority with which state events are dispatched to the Clock driver. + +#ifndef CLOCK_CONFIG_STATE_OBSERVER_PRIO +#define CLOCK_CONFIG_STATE_OBSERVER_PRIO 0 +#endif + +// POWER_CONFIG_STATE_OBSERVER_PRIO +// Priority with which state events are dispatched to the Power driver. + +#ifndef POWER_CONFIG_STATE_OBSERVER_PRIO +#define POWER_CONFIG_STATE_OBSERVER_PRIO 0 +#endif + +// RNG_CONFIG_STATE_OBSERVER_PRIO +// Priority with which state events are dispatched to this module. + +#ifndef RNG_CONFIG_STATE_OBSERVER_PRIO +#define RNG_CONFIG_STATE_OBSERVER_PRIO 0 +#endif + +// +//========================================================== + +// Stack Event Observers priorities - Invididual priorities + +//========================================================== +// NRF_SDH_ANT_STACK_OBSERVER_PRIO +// This setting configures the priority with which ANT events are processed with respect to other events coming from the stack. +// Modify this setting if you need to have ANT events dispatched before or after other stack events, such as BLE or SoC. +// Zero is the highest priority. + +#ifndef NRF_SDH_ANT_STACK_OBSERVER_PRIO +#define NRF_SDH_ANT_STACK_OBSERVER_PRIO 0 +#endif + +// NRF_SDH_BLE_STACK_OBSERVER_PRIO +// This setting configures the priority with which BLE events are processed with respect to other events coming from the stack. +// Modify this setting if you need to have BLE events dispatched before or after other stack events, such as ANT or SoC. +// Zero is the highest priority. + +#ifndef NRF_SDH_BLE_STACK_OBSERVER_PRIO +#define NRF_SDH_BLE_STACK_OBSERVER_PRIO 0 +#endif + +// NRF_SDH_SOC_STACK_OBSERVER_PRIO +// This setting configures the priority with which SoC events are processed with respect to other events coming from the stack. +// Modify this setting if you need to have SoC events dispatched before or after other stack events, such as ANT or BLE. +// Zero is the highest priority. + +#ifndef NRF_SDH_SOC_STACK_OBSERVER_PRIO +#define NRF_SDH_SOC_STACK_OBSERVER_PRIO 0 +#endif + +// +//========================================================== + +// +//========================================================== + + +// + +// NRF_SDH_SOC_ENABLED - nrf_sdh_soc - SoftDevice SoC event handler +//========================================================== +#ifndef NRF_SDH_SOC_ENABLED +#define NRF_SDH_SOC_ENABLED 1 +#endif +// SoC Observers - Observers and priority levels + +//========================================================== +// NRF_SDH_SOC_OBSERVER_PRIO_LEVELS - Total number of priority levels for SoC observers. +// This setting configures the number of priority levels available for the SoC event handlers. +// The priority level of a handler determines the order in which it receives events, with respect to other handlers. + +#ifndef NRF_SDH_SOC_OBSERVER_PRIO_LEVELS +#define NRF_SDH_SOC_OBSERVER_PRIO_LEVELS 2 +#endif + +// SoC Observers priorities - Invididual priorities + +//========================================================== +// BLE_DFU_SOC_OBSERVER_PRIO +// Priority with which BLE events are dispatched to the DFU Service. + +#ifndef BLE_DFU_SOC_OBSERVER_PRIO +#define BLE_DFU_SOC_OBSERVER_PRIO 1 +#endif + +// CLOCK_CONFIG_SOC_OBSERVER_PRIO +// Priority with which SoC events are dispatched to the Clock driver. + +#ifndef CLOCK_CONFIG_SOC_OBSERVER_PRIO +#define CLOCK_CONFIG_SOC_OBSERVER_PRIO 0 +#endif + +// POWER_CONFIG_SOC_OBSERVER_PRIO +// Priority with which SoC events are dispatched to the Power driver. + +#ifndef POWER_CONFIG_SOC_OBSERVER_PRIO +#define POWER_CONFIG_SOC_OBSERVER_PRIO 0 +#endif + +// +//========================================================== + +// +//========================================================== + + +// + +// +//========================================================== + +// <<< end of configuration section >>> +#endif //SDK_CONFIG_H + diff --git a/core/embed/ble_firmware/version.h b/core/embed/ble_firmware/version.h new file mode 100644 index 000000000..14de53045 --- /dev/null +++ b/core/embed/ble_firmware/version.h @@ -0,0 +1,4 @@ +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 +#define VERSION_PATCH 0 +#define VERSION_BUILD 0 diff --git a/core/site_scons/tools.py b/core/site_scons/tools.py index 7ad16f4d5..a228bcaed 100644 --- a/core/site_scons/tools.py +++ b/core/site_scons/tools.py @@ -98,6 +98,25 @@ def get_version(file: str) -> str: return f"{major}.{minor}.{patch}" +def get_version_int(file): + major = 0 + minor = 0 + patch = 0 + + file = PROJECT_ROOT / file + with open(file, 'r') as f: + for line in f: + if line.startswith('#define VERSION_MAJOR '): + major = int(line.split('VERSION_MAJOR')[1].strip()) + if line.startswith('#define VERSION_MINOR '): + minor = int(line.split('VERSION_MINOR')[1].strip()) + if line.startswith('#define VERSION_PATCH '): + patch = int(line.split('VERSION_PATCH')[1].strip()) + if major > 99 or minor > 99 or patch > 99: + raise Exception("Version number too large") + return major * 10000 + minor * 100 + patch + + def get_git_revision_hash() -> str: return subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii").strip() diff --git a/core/tools/convert_ble_firmware.py b/core/tools/convert_ble_firmware.py new file mode 100644 index 000000000..c7509ce3a --- /dev/null +++ b/core/tools/convert_ble_firmware.py @@ -0,0 +1,35 @@ +import click +import zipfile + + +def convert_file(archive, infile, outfile, name): + data = archive.read(infile) + with open(outfile, "w") as outfile: + outfile.write("// Firmware BLOB - automatically generated\n") + outfile.write("\n") + outfile.write(f"#ifndef __FW_BLOB_{name}_H__\n") + outfile.write(f"#define __FW_BLOB_{name}_H__ 1\n") + outfile.write("\n") + + outfile.write(f"uint8_t {name}[] = " + "{") + + for i, byte in enumerate(data): + if i % 16 == 0: + outfile.write("\n ") + outfile.write("0x{:02x}, ".format(byte)) + + outfile.write("\n};\n") + outfile.write("\n") + outfile.write("#endif\n") + + +@click.command() +@click.argument("infile", type=click.File("rb")) +def convert(infile): + with zipfile.ZipFile(infile) as archive: + convert_file(archive, "ble_firmware.bin", "./embed/firmware/dfu/ble_firmware_bin.h", "binfile") + convert_file(archive, "ble_firmware.dat", "./embed/firmware/dfu/ble_firmware_dat.h", "datfile") + + +if __name__ == "__main__": + convert() diff --git a/core/tools/generate_ble_bl_settings.sh b/core/tools/generate_ble_bl_settings.sh new file mode 100644 index 000000000..e407e8475 --- /dev/null +++ b/core/tools/generate_ble_bl_settings.sh @@ -0,0 +1 @@ +nrfutil settings generate --family NRF52 --bootloader-version 0 --bl-settings-version 2 --app-boot-validation VALIDATE_ECDSA_P256_SHA256 --application ./build/ble_firmware/ble_firmware.hex --application-version 0 --sd-boot-validation VALIDATE_ECDSA_P256_SHA256 --softdevice ./embed/sdk/nrf52/components/softdevice/s140/hex/s140_nrf52_7.2.0_softdevice.hex --key-file ./embed/ble_bootloader/priv.pem ./build/ble_bootloader/settings.hex diff --git a/tools/style.c.exclude b/tools/style.c.exclude index e643d7575..9b2c4a9fe 100644 --- a/tools/style.c.exclude +++ b/tools/style.c.exclude @@ -12,3 +12,5 @@ ^\./crypto/sha3 ^\./legacy/vendor ^\./core/embed/segger +^\./core/embed/ble_bootloader/uecc +^\./core/embed/sdk