'''Provides the necessary auxiliary functions for the translation.
'''
import re
from typing import List
from asm_analyser.blocks.code_block import CodeBlock
FUNC_DICT = {
'ldr4000': 'void ldr4000(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint32_t*)(_asm_analysis_.malloc_0+*address+offset));\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr4010': 'void ldr4010(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint32_t*)(_asm_analysis_.malloc_0+*address));\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr4100': 'void ldr4100(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint32_t*)(_asm_analysis_.malloc_0+*address+offset));\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr2000': 'void ldr2000(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint16_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xffff;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr2001': 'void ldr2001(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = (*((uint16_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xffff) << 16 >> 16;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr2010': 'void ldr2010(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint16_t*)(_asm_analysis_.malloc_0+*address)) & 0xffff;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr2011': 'void ldr2011(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = (*((uint16_t*)(_asm_analysis_.malloc_0+*address)) & 0xffff) << 16 >> 16;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr2100': 'void ldr2100(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint16_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xffff;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr2101': 'void ldr2101(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = (*((uint16_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xffff) << 16 >> 16;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr1000': 'void ldr1000(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint8_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xff;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr1001': 'void ldr1001(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = (*((uint8_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xff) << 24 >> 24;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr1010': 'void ldr1010(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint8_t*)(_asm_analysis_.malloc_0+*address)) & 0xff;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr1011': 'void ldr1011(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = (*((uint8_t*)(_asm_analysis_.malloc_0+*address)) & 0xff) << 24 >> 24;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr1100': 'void ldr1100(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = *((uint8_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xff;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'ldr1101': 'void ldr1101(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target = (*((uint8_t*)(_asm_analysis_.malloc_0+*address+offset)) & 0xff) << 24 >> 24;\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n',
'str4000': 'void str4000(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+offset)) = *target;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str4010': 'void str4010(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address)) = *target;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str4100': 'void str4100(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+offset)) = *target;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str2000': 'void str2000(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint16_t*)(_asm_analysis_.malloc_0+*address+offset)) = *target & 0xffff;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str2010': 'void str2010(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint16_t*)(_asm_analysis_.malloc_0+*address)) = *target & 0xffff;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str2100': 'void str2100(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint16_t*)(_asm_analysis_.malloc_0+*address+offset)) = *target & 0xffff;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str1000': 'void str1000(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*(_asm_analysis_.malloc_0+*address+offset) = *target & 0xff;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str1010': 'void str1010(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*(_asm_analysis_.malloc_0+*address) = *target & 0xff;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'str1100': 'void str1100(int32_t *target, int32_t *address, int32_t offset)\n' \
'{\n' \
'*(_asm_analysis_.malloc_0+*address+offset) = *target & 0xff;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n',
'ldr8000': 'void ldr8000(int32_t *target1, int32_t *target2, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target1 = *((uint32_t*)(_asm_analysis_.malloc_0+*address+offset));\n' \
'*target2 = *((uint32_t*)(_asm_analysis_.malloc_0+*address+offset+4));\n' \
'_asm_analysis_.load_counter += 2;\n' \
'}\n',
'ldr8010': 'void ldr8010(int32_t *target1, int32_t *target2, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target1 = *((uint32_t*)(_asm_analysis_.malloc_0+*address));\n' \
'*target2 = *((uint32_t*)(_asm_analysis_.malloc_0+*address+4));\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter += 2;\n' \
'}\n',
'ldr8100': 'void ldr8100(int32_t *target1, int32_t *target2, int32_t *address, int32_t offset)\n' \
'{\n' \
'*target1 = *((uint32_t*)(_asm_analysis_.malloc_0+*address+offset));\n' \
'*target2 = *((uint32_t*)(_asm_analysis_.malloc_0+*address+offset+4));\n' \
'*address += offset;\n' \
'_asm_analysis_.load_counter += 2;\n' \
'}\n',
'str8000': 'void str8000(int32_t *target1, int32_t *target2, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+offset)) = *target1;\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+offset+4)) = *target2;\n' \
'_asm_analysis_.store_counter += 2;\n' \
'}\n',
'str8010': 'void str8010(int32_t *target1, int32_t *target2, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address)) = *target1;\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+4)) = *target2;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter += 2;\n' \
'}\n',
'str8100': 'void str8100(int32_t *target1, int32_t *target2, int32_t *address, int32_t offset)\n' \
'{\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+offset)) = *target1;\n' \
'*((uint32_t*)(_asm_analysis_.malloc_0+*address+offset+4)) = *target2;\n' \
'*address += offset;\n' \
'_asm_analysis_.store_counter += 2;\n' \
'}\n',
'push': 'void push(int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'_asm_analysis_.sp.i -= 4;\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + _asm_analysis_.sp.i)) = *cur_arg;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'pop': 'void pop(int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + _asm_analysis_.sp.i));\n' \
'_asm_analysis_.sp.i += 4;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldm0': 'void ldm0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + tmp));\n' \
'tmp += 4;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldm1': 'void ldm1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + *address));\n' \
'*address += 4;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldmib0': 'void ldmib0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'tmp += 4;\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + tmp));\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldmib1': 'void ldmib1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*address += 4;\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + *address));\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldmda0': 'void ldmda0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + tmp));\n' \
'tmp -= 4;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldmda1': 'void ldmda1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + *address));\n' \
'*address -= 4;\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldmdb0': 'void ldmdb0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'tmp -= 4;\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + tmp));\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'ldmdb1': 'void ldmdb1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*address -= 4;\n' \
'*cur_arg = *((uint32_t*) (_asm_analysis_.malloc_0 + *address));\n' \
'_asm_analysis_.load_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stm0': 'void stm0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + tmp)) = *cur_arg;\n' \
'tmp += 4;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stm1': 'void stm1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + *address)) = *cur_arg;\n' \
'*address += 4;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stmib0': 'void stmib0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'tmp += 4;\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + tmp)) = *cur_arg;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stmib1': 'void stmib1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*address += 4;\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + *address)) = *cur_arg;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stmda0': 'void stmda0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + tmp)) = *cur_arg;\n' \
'tmp -= 4;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stmda1': 'void stmda1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + *address)) = *cur_arg;\n' \
'*address -= 4;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stmdb0': 'void stmdb0(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'int32_t tmp = *address;\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'tmp -= 4;\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + tmp)) = *cur_arg;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'stmdb1': 'void stmdb1(int32_t *address, int num, ...)\n' \
'{\n' \
'va_list args;\n' \
'va_start(args, num);\n' \
'for (int i=0; i < num; i++)\n' \
'{\n' \
'int32_t *cur_arg = va_arg(args, int32_t *);\n' \
'*address -= 4;\n' \
'*((uint32_t*) (_asm_analysis_.malloc_0 + *address)) = *cur_arg;\n' \
'_asm_analysis_.store_counter ++;\n' \
'}\n' \
'va_end(args);\n' \
'}\n',
'clz': 'void clz(int32_t *dest, int32_t *op)\n' \
'{\n' \
'int msb = 1 << (32 - 1);\n' \
'int count = 0;\n' \
'uint32_t num = (uint32_t)*op;\n' \
'for(int i=0; i<32; i++)\n' \
'{\n' \
'if((num << i) & msb)\n' \
'break;\n' \
'count++;\n' \
'}\n' \
'*dest = count;\n' \
'}\n',
'__aeabi_fadd': 'void fadd()\n' \
'{\n' \
'_asm_analysis_.r0.f = _asm_analysis_.r0.f + _asm_analysis_.r1.f;\n' \
'}\n',
'__aeabi_fsub': 'void fsub()\n' \
'{\n' \
'_asm_analysis_.r0.f = _asm_analysis_.r0.f - _asm_analysis_.r1.f;\n' \
'}\n',
'__aeabi_fmul': 'void fmul()\n' \
'{\n' \
'_asm_analysis_.r0.f = _asm_analysis_.r0.f * _asm_analysis_.r1.f;\n' \
'}\n',
'__aeabi_fdiv': 'void fdiv()\n' \
'{\n' \
'_asm_analysis_.r0.f = _asm_analysis_.r0.f / _asm_analysis_.r1.f;\n' \
'}\n',
'__aeabi_f2d': 'void f2d()\n' \
'{\n' \
'double double_val = (double) _asm_analysis_.r0.f;\n' \
'uint64_t uint64_t_val = *(uint64_t *)&double_val;\n' \
'_asm_analysis_.r1.i = (uint32_t) (uint64_t_val >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) uint64_t_val;\n' \
'}\n',
'__aeabi_d2f': 'void d2f()\n' \
'{\n' \
'uint64_t uint64_t_val = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'double double_val = *(double *)&uint64_t_val;\n' \
'_asm_analysis_.r0.f = (float) double_val;\n' \
'}\n',
'__aeabi_dadd': 'void dadd()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'double result = *(double *)&op1 + *(double *)&op2;\n' \
'uint64_t result_uint64 = *(uint64_t *)&result;\n' \
'_asm_analysis_.r1.i = (uint32_t) (result_uint64 >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) result_uint64;\n' \
'}\n',
'__aeabi_dsub': 'void dsub()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'double result = *(double *)&op1 - *(double *)&op2;\n' \
'uint64_t result_uint64 = *(uint64_t *)&result;\n' \
'_asm_analysis_.r1.i = (uint32_t) (result_uint64 >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) result_uint64;\n' \
'}\n',
'__aeabi_dmul': 'void dmul()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'double result = *(double *)&op1 * *(double *)&op2;\n' \
'uint64_t result_uint64 = *(uint64_t *)&result;\n' \
'_asm_analysis_.r1.i = (uint32_t) (result_uint64 >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) result_uint64;\n' \
'}\n',
'__aeabi_ddiv': 'void ddiv()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'double result = *(double *)&op1 / *(double *)&op2;\n' \
'uint64_t result_uint64 = *(uint64_t *)&result;\n' \
'_asm_analysis_.r1.i = (uint32_t) (result_uint64 >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) result_uint64;\n' \
'}\n',
'__aeabi_dcmplt': 'void dcmplt()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'_asm_analysis_.r0.i = *(double *)&op1 < *(double *)&op2;\n' \
'}\n',
'__aeabi_dcmpeq': 'void dcmpeq()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'_asm_analysis_.r0.i = *(double *)&op1 == *(double *)&op2;\n' \
'}\n',
'__aeabi_dcmple': 'void dcmple()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'_asm_analysis_.r0.i = *(double *)&op1 <= *(double *)&op2;\n' \
'}\n',
'__aeabi_dcmpge': 'void dcmpge()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'_asm_analysis_.r0.i = *(double *)&op1 >= *(double *)&op2;\n' \
'}\n',
'__aeabi_dcmpgt': 'void dcmpgt()\n' \
'{\n' \
'uint64_t op1 = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'uint64_t op2 = ((uint64_t)(uint32_t) _asm_analysis_.r3.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r2.i);\n' \
'_asm_analysis_.r0.i = *(double *)&op1 > *(double *)&op2;\n' \
'}\n',
'__aeabi_d2iz': 'void d2iz()\n' \
'{\n' \
'uint64_t op_int = ((uint64_t)(uint32_t) _asm_analysis_.r1.i) << 32 | ((uint64_t)(uint32_t) _asm_analysis_.r0.i);\n' \
'_asm_analysis_.r0.i = (int32_t) *(double *)&op_int;\n' \
'}\n',
'__aeabi_idivmod': 'void idivmod()\n' \
'{\n' \
'int32_t quot = _asm_analysis_.r0.i / _asm_analysis_.r1.i;\n' \
'int32_t rem = _asm_analysis_.r0.i % _asm_analysis_.r1.i;\n' \
'_asm_analysis_.r0.i = quot;\n' \
'_asm_analysis_.r1.i = rem;\n' \
'}\n',
'__aeabi_idiv': 'void idiv()\n' \
'{\n' \
'_asm_analysis_.r0.i = _asm_analysis_.r0.i / _asm_analysis_.r1.i;\n' \
'}\n',
'__aeabi_i2d': 'void i2d()\n' \
'{\n' \
'double result = (double) _asm_analysis_.r0.i;\n' \
'uint64_t result_uint64 = *(uint64_t *)&result;\n' \
'_asm_analysis_.r1.i = (uint32_t) (result_uint64 >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) result_uint64;\n' \
'}\n',
'__aeabi_ui2d': 'void ui2d()\n' \
'{\n' \
'double result = (double)(uint32_t) _asm_analysis_.r0.i;\n' \
'uint64_t result_uint64 = *(uint64_t *)&result;\n' \
'_asm_analysis_.r1.i = (uint32_t) (result_uint64 >> 32);\n' \
'_asm_analysis_.r0.i = (uint32_t) result_uint64;\n' \
'}\n',
'malloc': 'void malloc_help()\n' \
'{\n' \
'uint8_t* ptr = (uint8_t*) malloc(_asm_analysis_.r0.i);\n' \
'_asm_analysis_.r0.i = (int32_t) (ptr - _asm_analysis_.malloc_0);\n' \
'}\n',
'free': 'void free_help()\n' \
'{\n' \
'free(_asm_analysis_.malloc_0+_asm_analysis_.r0.i);\n' \
'}\n',
'calloc': 'void calloc_help()\n' \
'{\n' \
'uint8_t* ptr = (uint8_t*) calloc(_asm_analysis_.r0.i, _asm_analysis_.r1.i);\n' \
'_asm_analysis_.r0.i = (int32_t) (ptr - _asm_analysis_.malloc_0);\n' \
'}\n',
'memcpy': 'void memcpy_help()\n' \
'{\n' \
'memcpy(_asm_analysis_.malloc_0+_asm_analysis_.r0.i, _asm_analysis_.malloc_0+_asm_analysis_.r1.i, _asm_analysis_.r2.i);\n' \
'}\n',
'memset': 'void memset_help()\n' \
'{\n' \
'memset(_asm_analysis_.malloc_0+_asm_analysis_.r0.i, _asm_analysis_.r1.i, _asm_analysis_.r2.i);\n' \
'}\n',
'strlen': 'void strlen_help()\n' \
'{\n' \
'_asm_analysis_.r0.i = (int32_t) strlen(_asm_analysis_.malloc_0+_asm_analysis_.r0.i);\n' \
'}\n',
'rand': 'void rand_help()\n' \
'{\n' \
'_asm_analysis_.r0.i = rand();\n' \
'}\n',
'srand': 'void srand_help()\n' \
'{\n' \
'srand(_asm_analysis_.r0.i);\n' \
'}\n',
'time': 'void time_help()\n' \
'{\n' \
'_asm_analysis_.r0.i = time(NULL);' \
'}\n',
'clock': 'void clock_help()\n' \
'{\n' \
'_asm_analysis_.r0.i = clock();' \
'}\n',
'puts': '',
'putchar': '',
'putc': '',
'nl': '',
'printf': '',
'__printf_chk': '',
'__assert_fail': 'void assert_help()\n' \
'{\n' \
'__assert_fail(_asm_analysis_.malloc_0+_asm_analysis_.r0.i, _asm_analysis_.malloc_0+_asm_analysis_.r1.i, _asm_analysis_.r2.i, _asm_analysis_.malloc_0+_asm_analysis_.r3.i);\n' \
'}\n',
'__isoc99_scanf': 'void scanf_help()\n' \
'{\n' \
'scanf(_asm_analysis_.malloc_0+_asm_analysis_.r0.i, _asm_analysis_.malloc_0+_asm_analysis_.r1.i);\n' \
'}\n',
'umull': 'void umull(int32_t *dest_lo, int32_t *dest_hi, int32_t *op1, int32_t *op2)\n' \
'{\n' \
'uint64_t res = (uint64_t) ((uint32_t) *op1) * ((uint32_t) *op2);\n' \
'*dest_lo = (uint32_t) res;\n' \
'*dest_hi = (uint32_t) (res >> 32);\n' \
'}\n',
'smull': 'void smull(int32_t *dest_lo, int32_t *dest_hi, int32_t *op1, int32_t *op2)\n' \
'{\n' \
'uint64_t res = (uint64_t) (*op1) * (*op2);\n' \
'*dest_lo = (uint32_t) res;\n' \
'*dest_hi = (uint32_t) (res >> 32);\n' \
'}\n'
}
CALL_DICT = {
'__aeabi_fadd': 'fadd();\n',
'__aeabi_fsub': 'fsub();\n',
'__aeabi_fmul': 'fmul();\n',
'__aeabi_fdiv': 'fdiv();\n',
'__aeabi_f2d': 'f2d();\n',
'__aeabi_d2f': 'd2f();\n',
'__aeabi_dadd': 'dadd();\n',
'__aeabi_dsub': 'dsub();\n',
'__aeabi_dmul': 'dmul();\n',
'__aeabi_ddiv': 'ddiv();\n',
'__aeabi_dcmplt': 'dcmplt();\n',
'__aeabi_dcmpeq': 'dcmpeq();\n',
'__aeabi_dcmple': 'dcmple();\n',
'__aeabi_dcmpge': 'dcmpge();\n',
'__aeabi_dcmpgt': 'dcmpgt();\n',
'__aeabi_d2iz': 'd2iz();\n',
'__aeabi_idivmod': 'idivmod();\n',
'__aeabi_idiv': 'idiv();\n',
'__aeabi_i2d': 'i2d();\n',
'__aeabi_ui2d': 'ui2d();\n',
'malloc': 'malloc_help();\n',
'free': 'free_help();\n',
'calloc': 'calloc_help();\n',
'memcpy': 'memcpy_help();\n',
'memset': 'memset_help();\n',
'strlen': 'strlen_help();\n',
'rand': 'rand_help();\n',
'srand': 'srand_help();\n',
'time': 'time_help();\n',
'clock': 'clock_help();\n',
'puts': 'printf_help("%s\\n", _asm_analysis_.r0.i, _asm_analysis_.r1.i, _asm_analysis_.r2.i);\n',
'putchar': 'printf_help("%c", _asm_analysis_.r0.i, _asm_analysis_.r1.i, _asm_analysis_.r2.i);\n',
'putc': 'printf_help("%c", _asm_analysis_.r0.i, _asm_analysis_.r1.i, _asm_analysis_.r2.i);\n',
'nl': 'printf_help("\\n", _asm_analysis_.r0.i, _asm_analysis_.r1.i, _asm_analysis_.r2.i);\n',
'printf': 'printf_help(_asm_analysis_.malloc_0+_asm_analysis_.r0.i, _asm_analysis_.r1.i, _asm_analysis_.r2.i, _asm_analysis_.r3.i);\n',
'__printf_chk': 'printf_help(_asm_analysis_.malloc_0+_asm_analysis_.r1.i, _asm_analysis_.r2.i, _asm_analysis_.r2.i, _asm_analysis_.r3.i);\n',
'__assert_fail': 'assert_help();\n',
'__isoc99_scanf': 'scanf_help();\n',
'umull': '',
'smull': ''
}
COND_CODES = {
'eq', 'ne', 'ge', 'gt', 'le', 'lt', 'ls', 'cs',
'cc', 'hi', 'mi', 'pl', 'al', 'nv', 'vs', 'vc'
}
[docs]def get_auxiliary_functions(blocks: List[CodeBlock]) -> str:
'''Determines the needed auxiliary functions for the translation.
Parameters
----------
blocks : list[CodeBlock]
The code blocks with all their instructions.
Returns
-------
str
The C code containing all the necessary function definitions.
'''
result = ''
# str4000 is needed in malloc_start
function_calls = set()
# get the necessary auxiliary functions for the translation
for block in blocks:
for instr in block.instructions:
if ((instr[1] == 'bl' or instr[1] == 'b') and
instr[2][0] in CALL_DICT):
function_calls.add(instr[2][0])
if instr[1] in CALL_DICT:
function_calls.add(instr[1])
if re.match('(^ld.*)|(^st.*)|(^push.*)|(^pop.*)|(^clz.*)',
instr[1]):
opcode = instr[1]
if 'clz' in opcode:
function_calls.add('clz')
elif 'push' not in opcode and 'pop' not in opcode:
digit_idx = re.search('\d', opcode).start()
if opcode[digit_idx-2:digit_idx] in COND_CODES:
opcode = opcode[:digit_idx-2]+opcode[digit_idx:]
else:
if opcode[-2:] in COND_CODES:
opcode = opcode[:-2]
function_calls.add(opcode)
added_defs = set()
for call in function_calls:
if FUNC_DICT[call] not in added_defs:
result += FUNC_DICT[call]
added_defs.add(FUNC_DICT[call])
return result