diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-06-18 19:45:50 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2009-06-18 19:45:50 +0000 |
commit | e77fe99962337e339262ea579487eeb3ff50c4b4 (patch) | |
tree | 703e35e0c65bf44d3c4814f5e75e9587c39c98a3 /misc/buildroot/toolchain/nxflat/arm | |
parent | 050865808bfb56aa3f3dee42157779cf47b16f0e (diff) | |
download | px4-nuttx-e77fe99962337e339262ea579487eeb3ff50c4b4.tar.gz px4-nuttx-e77fe99962337e339262ea579487eeb3ff50c4b4.tar.bz2 px4-nuttx-e77fe99962337e339262ea579487eeb3ff50c4b4.zip |
mknxflat is now in the ballpark
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1904 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'misc/buildroot/toolchain/nxflat/arm')
-rw-r--r-- | misc/buildroot/toolchain/nxflat/arm/arch.h (renamed from misc/buildroot/toolchain/nxflat/arm/arm.h) | 2 | ||||
-rw-r--r-- | misc/buildroot/toolchain/nxflat/arm/disarm.c | 2 | ||||
-rw-r--r-- | misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def | 572 |
3 files changed, 13 insertions, 563 deletions
diff --git a/misc/buildroot/toolchain/nxflat/arm/arm.h b/misc/buildroot/toolchain/nxflat/arm/arch.h index e761dfe68..61ace0dd4 100644 --- a/misc/buildroot/toolchain/nxflat/arm/arm.h +++ b/misc/buildroot/toolchain/nxflat/arm/arch.h @@ -1,5 +1,5 @@ /*********************************************************************** - * xflat/tools/arm/arm.h + * xflat/tools/arm/arch.h * ARM ELF support for BFD. * * Copyright (C) 2009 Gregory Nutt. All rights reserved. diff --git a/misc/buildroot/toolchain/nxflat/arm/disarm.c b/misc/buildroot/toolchain/nxflat/arm/disarm.c index ad430472f..5826df3b4 100644 --- a/misc/buildroot/toolchain/nxflat/arm/disarm.c +++ b/misc/buildroot/toolchain/nxflat/arm/disarm.c @@ -1,5 +1,5 @@ /*********************************************************************** - * toolchain/nxflat/disasm.c + * toolchain/nxflat/arm/disarm.c * ARM Disassembler * * Copyright (C) 2009 Gregory Nutt. All rights reserved. diff --git a/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def b/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def index 29551163b..8f58267bc 100644 --- a/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def +++ b/misc/buildroot/toolchain/nxflat/arm/dyncall_skeleton.def @@ -69,100 +69,9 @@ static const char file_prologue[] = " *******************************************************************/\n\n" "/*******************************************************************\n" " * Definitions\n" - " *******************************************************************/\n\n" - "/* Register definitions */\n\n" - "#define PIC_REG r10\t/* The PIC base register */\n" - "#define RINFO r4\t/* Pointer to dyninfo structure */\n" - "#define MYPIC r5\t/* Saved PIC base register value */\n" - "#define FRAME r6\t/* Current state save frame */\n" - "#define SAVEREG1 r4\t/* First pushed register */\n" - "#define SAVEREG2 r7\t/* Last pushed register */\n" - "#define TMP3 r5\t/* Careful, overlaps MYPIC */\n" - "#define WORK r7\t/* Safe to used */\n" - "#define TMP1 ip\n" - "#define TMP2 lr\n\n" - "/* This is the EXIT software interrupt code. */\n\n" - "#define DFR_EXIT_SWINO 0x900001\n"; - -#ifdef CONFIG_ARCH_DSC25 -static const char dyntrace_enable[] = - "\n/* Conditional Compilation */\n\n" - "#define __DYNTRACE 1\n" - "#define __DYNTRACE_USE_HARDWARE 1\n" - "#define __DYNTRACE_CONFIG_DSC25 1\n"; -#else -static const char dyntrace_enable[] = - "\n/* Conditional Compilation */\n\n" - "#define __DYNTRACE 1\n"; -#endif - -static const char import_prologue[] = - "\n/* This is an assembly language representation of the\n" - " * struct nxflat_import_s structure:\n" - " */\n\n" - "#define RINFO_FCNNAME 0\t/* Offset to the function name */\n" - "#define RINFO_FCNADDR 4\t/* Offset to the function address */\n" - "#define RINFO_PICBASE 8\t/* Offset to the PIC base value */\n\n" - "/* The common dynamic call logic receives the following C stack frame.\n" - " * NOTE: The number of registers should be SAVEREG2-SAVEREG1+2.\n" - " */\n\n" - "#define SP_OFFSET_CREG1 0\n" - "#define SP_OFFSET_CREG2 4\n" - "#define SP_OFFSET_CREG3 8\n" - "#define SP_OFFSET_CREG4 12\n" - "#define SP_OFFSET_CREG5 16\n" - "#define SP_FRAME_SIZE 20\n\n" - "/* The common dynamic call logic will create the following dynamic\n" - " * frame:\n" - " */\n\n" - "#define DFR_OFFSET_ALLOCATED 0\n" - "#define DFR_OFFSET_REFCOUNT 1\n" - "#define DFR_OFFSET_UNUSED1 2\n" - "#define DFR_OFFSET_UNUSED2 3\n" - "#define DFR_OFFSET_CREG1 4\n" - "#define DFR_OFFSET_CREG2 8\n" - "#define DFR_OFFSET_CREG3 12\n" - "#define DFR_OFFSET_CREG4 16\n" - "#define DFR_OFFSET_CREG5 20\n\n" - "#define DFR_FRAME_SIZE_BYTES 24\n" - "#define DFR_FRAME_SIZE_WORDS (DFR_FRAME_SIZE_BYTES >> 2)\n\n" - "/* These definitions determine that memory that will be set aside\n" - " * for frame storage:\n" - " */\n"; + " *******************************************************************/\n"; -static const char import_frame_size[] = - "\n#define DFR_NUM_FRAMES %d\n" - "#define DFR_FRAME_ALLOC_BYTES (DFR_FRAME_SIZE_BYTES*DFR_NUM_FRAMES)\n" - "#define DFR_FRAME_ALLOC_WORDS (DFR_FRAME_ALLOC_BYTES >> 2)\n"; - -static const char dynamic_frames[] = - "\n/*******************************************************************\n" - " * The Dynamic Frame Storage\n" - " *******************************************************************/\n\n" - "/* This defines an array of state save frames the will used by the\n" - " * dynamic call logic to hold information needed to manage a \"thunk.\"\n" - " */\n\n" - "\t.bss\n" - "\t.align\t2\n" - "\t.local\t__dynframes\n" - "\t.type\t__dynframes, object\n" - "__dynframes:\n" - "\t.fill\tDFR_FRAME_ALLOC_WORDS, 4, 0\n" - "\t.size\t__dynframes, .-__dynframes\n"; - -static const char nonreturning_dynamic_frame[] = - "\n/* This defines a special storage location for functions that don't\n" - " * (normally) return. It is kept separate from other frames to prevent\n" - " * overwriting; this storage only exists in case the function does\n" - " * return (which can happen on an error condition).\n" - " */\n\n" - "\t.bss\n" - "\t.align\t2\n" - "\t.local\t__dynnrframe\n" - "\t.type\t__dynnrframe, object\n" - "__dynnrframe:\n" - "\t.fill\tDFR_FRAME_SIZE_WORDS, 4, 0\n" - "\t.size\t__dynnrframe, .-__dynnrframe\n"; +static const char import_prologue[] = ""; /******************************************************************* * Import Function Name String Table @@ -189,7 +98,7 @@ static const char import_name_strtab_format[] = "\t.size\t__dynimport%04d, .-__dynimport%04d\n"; /******************************************************************* - * Per Import Dyanamic Call Information + * Dyanamic Call Information *******************************************************************/ static const char dynimport_decl_prologue[] = @@ -222,7 +131,6 @@ static const char dynimport_array_format[] = "__dyninfo%04d:\t\t\t/* Dynamic info for imported symbol %s */\n" "\t.word\t__dynimport%04d\t/* Offset to name of imported function */\n" "\t.word\t0\t\t/* Resolved address of imported function */\n" - "\t.word\t0\t\t/* Data segment address for imported func */\n" "\t.size\t__dyninfo%04d, .-__dyninfo%04d\n"; static const char dynimport_array_epilogue[] = @@ -231,7 +139,7 @@ static const char dynimport_array_epilogue[] = static const char dyncall_decl_prologue[] = "\n/*******************************************************************\n" - " * Per Import Dynamic Call Logic\n" + " * Dynamic Call Logic\n" " *******************************************************************/\n\n" "\t.text\n" "\t.align\t2\n"; @@ -243,17 +151,10 @@ static const char dyncall_format[] = "\t.global\t%s\n" "\t.type\t%s, function\n\n" "%s:\n" - "\tldr\tTMP1, =__dyninfo%04d\n" - "\tb\t__dyncall1\n" - "\t.size\t%s, .-%s\n"; - -static const char dyncall_format2[] = - "\n/* Dynamic call logic for special imported symbol %s */\n\n" - "\t.global\t%s\n" - "\t.type\t%s, function\n\n" - "%s:\n" - "\tldr\tTMP1, =__dyninfo%04d\n" - "\tb\t__dyncall2\n" + "\tstmdb\tsp!,{r4, lr}\n" + "\tldr\tr4, =__dyninfo%04d\n" + "\tbl\t[r4]\n" + "\tldmia\tsp!,{r4, pc}\n" "\t.size\t%s, .-%s\n"; static const char nonreturning_dyncall_format[] = @@ -261,465 +162,14 @@ static const char nonreturning_dyncall_format[] = "\t.global\t%s\n" "\t.type\t%s, function\n\n" "%s:\n" - "\tldr\tTMP1, =__dyninfo%04d\n" - "\tb\t__dynnoreturn\n" + "\tldr\tr4, =__dyninfo%04d\n" + "\tb\t[r4]\n" "\t.size\t%s, .-%s\n"; /******************************************************************* - * Dynamic Call Trace Logic - *******************************************************************/ - -static const char dyntrace_function[] = - "\n/* This is constant data used to by the __dyntrace function */\n\n" - "#ifdef __DYNTRACE\n\n" - "\t.section\t.rodata\n\n" - "# ifdef __DYNTRACE_USE_HARDWARE\n" - "# define __DYNTRACE_LBRACE_SIZE 3\n" - "# define __DYNTRACE_RBRACE_SIZE 3\n\n" - "\t.local\t.LC_lbrace\n" - "\t.type\t.LC_lbrace, object\n" - "\t.size\t.LC_lbrace, __DYNTRACE_LBRACE_SIZE\n" - ".LC_lbrace:\n" - "\t.ascii\t\"\\r\\n[\"\n\n" - "\t.local\t.LC_rbrace\n" - "\t.type\t.LC_rbrace, object\n" - "\t.size\t.LC_rbrace, __DYNTRACE_RBRACE_SIZE\n" - ".LC_rbrace:\n" - "\t.ascii\t\"]\\r\\n\"\n\n" - "# else\n\n" - "# define __DYNTRACE_LBRACE_SIZE 2\n" - "# define __DYNTRACE_RBRACE_SIZE 2\n\n" - "\t.local\t.LC_lbrace\n" - "\t.type\t.LC_lbrace, object\n" - "\t.size\t.LC_lbrace, __DYNTRACE_LBRACE_SIZE\n" - ".LC_lbrace:\n" - "\t.ascii\t\"\\n[\"\n\n" - "\t.local\t.LC_rbrace\n" - "\t.type\t.LC_rbrace, object\n" - "\t.size\t.LC_rbrace, __DYNTRACE_RBRACE_SIZE\n" - ".LC_rbrace:\n" - "\t.ascii\t\"]\\n\"\n\n" - "#endif /* __DYNTRACE_USE_HARDWARE */\n\n" - "#define __DYNTRACE_EXITTING_SIZE 8\n" - "\t.local\t.LC_exitting\n" - "\t.type\t.LC_exitting, object\n" - "\t.size\t.LC_exitting, __DYNTRACE_EXITTING_SIZE\n" - ".LC_exitting:\n" - "\t.ascii\t\"ABORTING\"\n\n" - "/* Macros to write trace information to the console/stderr\n" - " *\n" - " * r1 = write buffer address\n" - " * r2 = write buffer size\n" - " *\n" - " * Will use all registers normally altered on a C subroutine call:\n" - " * r0-r3, ip (r12), and lr (r14).\n" - " */\n\n" - "#ifdef __DYNTRACE_USE_HARDWARE\n" - "\t/* These are the same macros that can be found in\n" - "\t * linux/arch/armnommu/kernel/debug-armv.S for the 2.4 kernel\n" - "\t */\n\n" - "#ifdef __DYNTRACE_CONFIG_DSC25\n" - "\t.macro\taddruart,rx\n" - "\tldr\t\\rx, =0x00030300\t@ UART0 base\n" - "\t.endm\n\n" - "\t.macro\tsenduart,rd,rx\n" - "\tstrh\t\\rd, [\\rx, #0x00]\t@ UARTx_DTRR Offset\n" - "\t.endm\n\n" - "\t.macro\twaituart,rd,rx\n" - "1001:\tldrh\t\\rd, [\\rx, #0x0c]\t@ UARTx_SR Offset\n" - "\ttst\t\\rd, #0x0400\t\t@ Check TX fifo ind.\n" - "\tbeq\t1001b\t\t\t@ loop til 1=room in TX fifo\n" - "\t.endm\n\n" - "\t.macro\tbusyuart,rd,rx\n" - "1002:\tldrh\t\\rd, [\\rx, #0x0c]\t@ UARTx_SR Offset\n" - "\ttst\t\\rd, #0x0001\t\t@ Check TX empty bit\n" - "\tbne\t1002b\t\t\t@ loop til 0=TX fifo empty\n" - "\t.endm\n" - "#else\n" - "# error Unsupported architecture\n" - "#endif\n" - "\t.macro __dyntrace_write\n" - "\tbl\t__dynwrite\n" - "\t.endm\n\n" - "/* Write directly to the uart hardware:\n" - " * r1 = addr, r2 = number of bytes.\n" - " */\n\n" - "\t.text\n" - "\t.align\t2\n" - "\t.local\t__dynwrite\n" - "\t.type\t__dynwrite, function\n" - "__dynwrite:\n\n" - "\taddruart r3\t\t\t@ Get the UART address\n" - "1:\twaituart r0, r3\t\t\t@ Wait for UART available\n" - "\tldrb\tr0, [r1], #1\t\t@ Fetch the next byte\n" - "\tsenduart r0, r3\t\t\t@ Send the byte\n" - "\tbusyuart r0, r3\t\t\t@ Wait for the byte to go\n" - "\tsubs\tr2, r2, #1\t\t@ Decr # bytes sent\n" - "\tbne\t1b\t\t\t@ Done?\n" - "\tmov\tpc, lr\t\t\t@ Yes, Return\n" - "#else\n" - "/* This macro uses the write syscall to output trace information: */\n\n" - "\t.macro __dyntrace_write\n" - "\tmov\tr0, #1\n" - "\tswi\t0x900004\n" - "\t.endm\n" - "#endif\n\n" - "/* If enabled, the __dyntrace function will be called just before\n" - " * each call into a shared library is performed. The __dyntrace\n" - " * function will print the name of the called function on stderr\n" - " * in the follow format: \\n[name]\\n. WARNING: This function uses\n" - " * the write syscall directly!\n" - " *\n" - " * The following register state is assume on entry:\n" - " * o WORK is available for use\n" - " * o [PIC_REG] points to our data segment\n" - " * o [RINFO] holds the offset to the info structure\n" - " * [RINFO]+RINFO_FCNAME points to the symbol name.\n" - " */\n\n" - "\t.text\n" - "\t.align\t2\n" - "\t.local\t__dyntrace\n" - "\t.type\t__dyntrace, function\n" - "__dyntrace:\n\n" - "\t/* Save all registers normally altered on a C subroutine call:\n" - "\t * r0-r3, ip (r12), and lr (r14).\n" - "\t */\n\n" - "\tstmfd\tsp!, {r0-r3, ip, lr}\n\n" - "\t/* Write the leading \"\\n[\" */\n\n" - "\tldr\tr1, .Llbrace_addr\n" - "\tadd\tr1, PIC_REG, r1\n" - "\tmov\tr2, #__DYNTRACE_LBRACE_SIZE\n" - "\t__dyntrace_write\n\n" - "\t/* Determine the length of the name string */\n\n" - "\tadd\tr3, PIC_REG, RINFO\n" - "\tldr\tr1, [r3, #RINFO_FCNNAME]\n" - "\tmov\tr2, #0\n" - ".Lstrlen_loop:\n" - "\tldrb\tr0, [r1], #1\n" - "\tcmp\tr0, #0\n" - "\taddne\tr2, r2, #1\n" - "\tbne\t.Lstrlen_loop\n\n" - "\t/* Then write the name string */\n\n" - "\tldr\tr1, [r3, #RINFO_FCNNAME]\n" - "\t__dyntrace_write\n\n" - "\t/* Write the trailing \"\\n[\" */\n\n" - "\tldr\tr1, .Lrbrace_addr\n" - "\tadd\tr1, PIC_REG, r1\n" - "\tmov\tr2, #__DYNTRACE_LBRACE_SIZE\n" - "\t__dyntrace_write\n\n" - "\tldmfd\tsp!, {r0-r3, ip, pc}\n\n" - "\t.align\t2\n" - ".Llbrace_addr:\n" - "\t.word\t.LC_lbrace\n" - ".Lrbrace_addr:\n" - "\t.word\t.LC_rbrace\n" - "\t.size\t __dyntrace, .-__dyntrace\n" - "#endif /* __DYNTRACE */\n"; - -/******************************************************************* - * Common Dyanamic Call Information + * File Epilogue *******************************************************************/ -static const char frame_macros[] = - "\n/*******************************************************************\n" - " * Frame Management Macros\n" - " *******************************************************************/\n\n" - "\t.macro\tget_frame, frame, refcount, tmp1, tmp2\n\n" - "\t/* Get frame = first frame in the __dynframes list, and\n" - "\t * tmp2 = the first address past the __dynframe list.\n" - "\t */\n\n" - "\tldr\t\\tmp2, =DFR_FRAME_ALLOC_BYTES\n" - "\tldr\t\\tmp1, =__dynframes\n" - "\tadd\t\\frame, PIC_REG, \\tmp1\n" - "\tadd\t\\tmp2, \\tmp2, \\frame\n\n" - "\t/* Loop until an unsused frame is found our until the\n" - "\t * end of the __dynframes list is encountered. Normally,\n" - "\t * this will be very fast -- because the first frame should\n" - "\t * be available.\n" - "\t */\n\n" - "1:\n" - "\tmov\t\\tmp1, #1\n" - "\tswpb\t\\tmp1, \\tmp1, [\\frame]\n" - "\tcmp\t\\tmp1, #0\n" - "\tbeq\t2f\n\n" - "\t/* Increment to the next frame in the list and check if this\n" - "\t * next frame lies beyond the __dynframes list.\n" - "\t */\n\n" - "\tadd\t\\frame, \\frame, #DFR_FRAME_SIZE_BYTES\n" - "\tcmp\t\\frame, \\tmp2\n" - "\tbcc\t1b\n\n" - "\t/* Failure! The list is full! We don't have many options\n" - "\t * here so we will just exit with error number = 1.\n" - "\t */\n\n" - "#ifdef __DYNTRACE\n" - "\tldr\tr1, =.LC_exitting\n" - "\tmov\tr2, #__DYNTRACE_EXITTING_SIZE\n" - "\t__dyntrace_write\n" - "#endif\n\n" - "\tmov\tr0, #1\n" - "\tswi\tDFR_EXIT_SWINO\n\n" - "\t/* Set the reference count on the frame and continue with\n" - "\t * frame = the available frame */\n" - "2:\n" - "\tstrb\t\\refcount, [\\frame, #DFR_OFFSET_REFCOUNT]\n" - "\t.endm\n\n" - "\t.macro release_frame, frame, tmp1\n" - "\tldrb\t\\tmp1, [\\frame, #DFR_OFFSET_REFCOUNT]\n" - "\tcmp\t\\tmp1, #0\n" - "\tsub\t\\tmp1, \\tmp1, #1\n" - "\tble\t3f\n" - "\tcmp\t\\tmp1, #0\n" - "\tstrb\t\\tmp1, [\\frame, #DFR_OFFSET_REFCOUNT]\n" - "\tstreqb\t\\tmp1, [\\frame, #DFR_OFFSET_ALLOCATED]\n" - "3:\n" - "\t.endm\n"; - -static const char nonreturning_frame_macros[] = - "\t.macro\tget_nrframe, frame, refcount, tmp1, tmp2\n\n" - "\tldr\t\\frame, =__dynnrframe\n" - "\tadd\t\\frame, PIC_REG, \\frame\n" - "\t.endm\n\n" - "\t.macro release_nrframe, frame, tmp1\n" - "\t.endm\n"; - -static const char dyncall_prologue[] = - "\n/*******************************************************************\n" - " *\n" - " * This the dynamic call logic.\n" - " *\n" - " *\t1. SAVEREG1-SAVEREG2, and lr stored on the C stack\n" - " *\t2. [PIC_REG] = Points to our data segment\n" - " *\t3. [RINFO] = Offset to info structure in data segment\n" - " *\t4. [WORK] = Reference count to be applied to the frame\n" - " *\t5. TMP1, TMP2 and TMP3 are available for use.\n" - " *******************************************************************/\n\n" - "\t.text\n" - "\t.align\t2\n" - "\t.local\t__dyncall\n" - "\t.type\t__dyncall, function\n" - "\t.local\t__dyncall1\n" - "\t.type\t__dyncall1, function\n" - "\t.local\t__dyncall2\n" - "\t.type\t__dyncall2, function\n\n" - "__dyncall1:\n" - "\tstmdb\tsp!, {SAVEREG1-SAVEREG2, lr}\n" - "\tmov\tRINFO, TMP1\n" - "\tmov\tWORK, #1\n" - "\tb\t__dyncall\n" - "\t.size\t__dyncall1, .-__dyncall1\n\n" - "__dyncall2:\n" - "\tstmdb\tsp!, {SAVEREG1-SAVEREG2, lr}\n" - "\tmov\tRINFO, TMP1\n" - "\tmov\tWORK, #2\n" - "\t.size\t__dyncall2, .-__dyncall2\n\n" - "__dyncall:\n"; - -static const char dyntrace_call[] = - "\n#ifdef __DYNTRACE\n" - "\tbl\t__dyntrace\n" - "#endif /* __DYNTRACE */\n"; - -static const char dyncall_epilogue[] = - "\n\t/***********************************************************\n" - "\t * Transfer all of the information saved on the C stack to\n" - "\t * a dynamic frame.\n" - "\t ***********************************************************/\n\n" - "\t/* Get FRAME = the dynamic frame. */\n\n" - "\tget_frame\tFRAME, WORK, TMP1, TMP2\n\n" - "\t/* Copy the current C stack frame in the dynamic frame */\n\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG1]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG1]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG2]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG2]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG3]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG3]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG4]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG4]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG5]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG5]\n\n" - "\t/***********************************************************\n" - "\t * And release the C stack frame.\n" - "\t * At this point, the entire call stack should be pristine.\n" - "\t ***********************************************************/\n\n" - "\tadd\tsp, sp, #SP_FRAME_SIZE\n\n" - "\t/***********************************************************\n" - "\t * Get the dyncall information.\n" - "\t * Before the following section:\n" - "\t *\t[PIC_REG] = Points to our PIC base\n" - "\t *\t[FRAME] = Reference to dynamic frame\n" - "\t *\t[RINFO] = Offset to info structure in data segment\n" - "\t *\tRWORK, TMP1-3 are available\n" - "\t *\n" - "\t * After the following:\n" - "\t *\t[RINFO] = Dyncall info pointer\n" - "\t *\t[MYPIC] = Points to our PIC base\n" - "\t *\t[FRAME] = Reference to dynamic frame\n" - "\t *\t[PIC_REG] = Holds the new PIC base for the target\n" - "\t *\t[WORK] = Target function entry point\n" - "\t *\tTMP1-3 are still available\n" - "\t ***********************************************************/\n\n" - "\tadd\tRINFO, PIC_REG, RINFO\n" - "\tmov\tMYPIC, PIC_REG\n" - "\tldr\tPIC_REG, [RINFO, #RINFO_PICBASE]\n" - "\tldr\tWORK, [RINFO, #RINFO_FCNADDR]\n\n" - "\t/***********************************************************\n" - "\t * Call the function entry point.\n" - "\t *\n" - "\t * This logic performs a 32-bit, register version of the\n" - "\t * the bl instruction. \n" - "\t ***********************************************************/\n\n" - "\tmov\tlr, pc\n" - "\tmov\tpc, WORK\n\n" - "\t/***********************************************************\n" - "\t * Return from the thunked function\n" - "\t *\n" - "\t * At this point:\n" - "\t *\t1. We should have our PIC base in MYPIC.\n" - "\t *\t2. We should have the reference to the dynamic frame in FRAME\n" - "\t *\t3. We are free to use: r0-r3, RINFO, PIC_REG, FRAME-2, TMP1-2\n" - "\t *\n" - "\t ***********************************************************/\n\n" - "\t/* First, recover our PIC base into from a register that will\n" - "\t * have been restored.\n" - "\t */\n\n" - "\tmov\tPIC_REG, MYPIC\n\n" - "\t/***********************************************************\n" - "\t * Restore the C stack frame and release the dynamic frame\n" - "\t ***********************************************************/\n\n" - "\t/* Re-allocate the stack frame */\n\n" - "\tsub\tsp, sp, #SP_FRAME_SIZE\n\n" - "\t/* Then transfer the information into the C stack frame\n" - "\t * that was saved in the dynamic frame\n" - "\t */\n\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG1]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG1]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG2]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG2]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG3]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG3]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG4]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG4]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG5]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG5]\n\n" - "\t/* Release the dynamic frame */\n\n" - "\trelease_frame\tFRAME, TMP1\n\n" - "\t/***********************************************************\n" - "\t * And return to the caller\n" - "\t ***********************************************************/\n\n" - "\tldmia\tsp!, {SAVEREG1-SAVEREG2, pc}\n" - "\t.size\t__dyncall, .-__dyncall\n"; - -static const char nonreturning_dyncall_prologue[] = - "\n/*******************************************************************\n" - " *\n" - " * This is special dynamic call logic for functions that do not\n" - " * (normally) return.\n" - " *\n" - " *\t1. SAVEREG1-SAVEREG2, and lr stored on the C stack\n" - " *\t2. [PIC_REG] = Points to our data segment\n" - " *\t3. [RINFO] = Offset to info structure in data segment\n" - " *\t3. [WORK] = Reference count to be applied to the frame\n" - " *\t4. TMP1 and TMP2 are available for use.\n" - " *******************************************************************/\n\n" - "\t.text\n" - "\t.align\t2\n" - "\t.local\t__dynnoreturn\n" - "\t.type\t__dynnoreturn, function\n\n" - "__dynnoreturn:\n" - "\tstmdb\tsp!, {SAVEREG1-SAVEREG2, lr}\n" - "\tmov\tRINFO, TMP1\n" - "\tmov\tWORK, #0\n"; - -static const char nonreturning_dyncall_epilogue[] = - "\n\t/***********************************************************\n" - "\t * Transfer all of the information saved on the C stack to\n" - "\t * a dynamic frame.\n" - "\t ***********************************************************/\n\n" - "\t/* Get FRAME = the dynamic frame. */\n\n" - "\tget_nrframe\tFRAME, WORK, TMP1, TMP2\n\n" - "\t/* Copy the current C stack frame in the dynamic frame */\n\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG1]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG1]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG2]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG2]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG3]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG3]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG4]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG4]\n" - "\tldr\tTMP2, [sp, #SP_OFFSET_CREG5]\n" - "\tstr\tTMP2, [FRAME, #DFR_OFFSET_CREG5]\n\n" - "\t/***********************************************************\n" - "\t * And release the C stack frame.\n" - "\t * At this point, the entire call stack should be pristine.\n" - "\t ***********************************************************/\n\n" - "\tadd\tsp, sp, #SP_FRAME_SIZE\n\n" - "\t/***********************************************************\n" - "\t * Get the dyncall information.\n" - "\t * Before the following section:\n" - "\t *\t[PIC_REG] = Points to our PIC base\n" - "\t *\t[FRAME] = Reference to dynamic frame\n" - "\t *\t[RINFO] = Offset to info structure in data segment\n" - "\t *\tRWORK, TMP1-3 are available\n" - "\t *\n" - "\t * After the following:\n" - "\t *\t[RINFO] = Dyncall info pointer\n" - "\t *\t[MYPIC] = Points to our PIC base\n" - "\t *\t[FRAME] = Reference to dynamic frame\n" - "\t *\t[PIC_REG] = Holds the new PIC base for the target\n" - "\t *\t[WORK] = Target function entry point\n" - "\t *\tTMP1-3 are still available\n" - "\t ***********************************************************/\n\n" - "\tadd\tRINFO, PIC_REG, RINFO\n" - "\tmov\tMYPIC, PIC_REG\n" - "\tldr\tPIC_REG, [RINFO, #RINFO_PICBASE]\n" - "\tldr\tWORK, [RINFO, #RINFO_FCNADDR]\n\n" - "\t/***********************************************************\n" - "\t * Call the function entry point.\n" - "\t *\n" - "\t * This logic performs a 32-bit, register version of the\n" - "\t * the bl instruction. \n" - "\t ***********************************************************/\n\n" - "\tmov\tlr, pc\n" - "\tmov\tpc, WORK\n\n" - "\t/***********************************************************\n" - "\t * Return from the thunked function\n" - "\t *\n" - "\t * At this point:\n" - "\t *\t1. We should have our PIC base in MYPIC.\n" - "\t *\t2. We should have a reference to the dynamic frame in FRAME\n" - "\t *\t3. We are free to use: r0-r3, RINFO, PIC_REG, FRAME-2, TMP1-2\n" - "\t *\n" - "\t ***********************************************************/\n\n" - "\t/* First, recover our PIC base from a register the will have\n" - "\t * been restored.\n" - "\t */\n\n" - "\tmov\tPIC_REG, MYPIC\n\n" - "\t/***********************************************************\n" - "\t * Restore the C stack frame\n" - "\t ***********************************************************/\n\n" - "\t/* Re-allocate the stack frame */\n\n" - "\tsub\tsp, sp, #SP_FRAME_SIZE\n\n" - "\t/* Then transfer the information into the C stack frame\n" - "\t * that was saved in the dynamic frame.\n" - "\t */\n\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG1]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG1]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG2]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG2]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG3]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG3]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG4]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG4]\n" - "\tldr\tTMP2, [FRAME, #DFR_OFFSET_CREG5]\n" - "\tstr\tTMP2, [sp, #SP_OFFSET_CREG5]\n\n" - "\t/* Release the dynamic frame */\n\n" - "\trelease_nrframe\tFRAME, TMP1\n\n" - "\t/***********************************************************\n" - "\t * And return to the caller\n" - "\t ***********************************************************/\n\n" - "\tldmia\tsp!, {SAVEREG1-SAVEREG2, pc}\n" - "\t.size\t__dynnoreturn, .-__dynnoreturn\n"; - static const char file_epilogue[] = "\t.end\n"; |