summaryrefslogtreecommitdiff
path: root/misc/pascal/insn32/regm/regm_registers2.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/pascal/insn32/regm/regm_registers2.c')
-rw-r--r--misc/pascal/insn32/regm/regm_registers2.c1083
1 files changed, 542 insertions, 541 deletions
diff --git a/misc/pascal/insn32/regm/regm_registers2.c b/misc/pascal/insn32/regm/regm_registers2.c
index 2973dc7c3..25aaddfaf 100644
--- a/misc/pascal/insn32/regm/regm_registers2.c
+++ b/misc/pascal/insn32/regm/regm_registers2.c
@@ -1,541 +1,542 @@
-/**********************************************************************
- * regm_registers.c
- * Pass 2 register management functions
- *
- * Copyright (C) 2008 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * 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 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 NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * 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 OWNER 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.
- *
- **********************************************************************/
-
-/**********************************************************************
- * Included Files
- **********************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "keywords.h"
-#include "pofflib.h"
-#include "pedefs.h"
-#include "perr.h"
-
-#include "rinsn32.h"
-
-#include "regm.h"
-#include "regm_pass2.h"
-#include "regm_registers2.h"
-
-/**********************************************************************
- * Definitions
- **********************************************************************/
-
-#define INITIAL_RCODE2_ALLOC 150
-#define RCODE2_REALLOC 50
-
-/**********************************************************************
- * Private Function Prototypes
- **********************************************************************/
-
-/**********************************************************************
- * Public Variables
- **********************************************************************/
-
-struct regm_rcode2_s *g_pRCode2 = NULL;
-uint32 g_nRCode2 = 0;
-
-/**********************************************************************
- * Private Variables
- **********************************************************************/
-
-static uint32 g_nRCode2Alloc = 0;
-
-static const char * const g_prgReg2Names[NREGISTER_TYPES] =
- { "Z", "X", "CC", "A", "R", "V", "V", "S" };
-
-static const char * const g_prgSpecialReg2Names[NSPECIAL_REGISTERS2] =
- { "SPB", "SP", "BRG", "LSP", "CSB", "CSP", "PC", "DC", "LR", "CC"};
-
-/**********************************************************************
- * Private Functions
- **********************************************************************/
-
-/***********************************************************************/
-
-static void regm_CheckRCode2Alloc(void)
-{
- /* If the RCode buffer has never been allocated, allocate it now. */
-
- if (!g_pRCode2)
- {
- /* Allocate an inital buffer to hold the instructions */
-
- g_pRCode2 = (struct regm_rcode2_s*)
- malloc(INITIAL_RCODE2_ALLOC*sizeof(struct regm_rcode2_s));
- if (!g_pRCode2)
- {
- fatal(eNOMEMORY);
- }
-
- g_nRCode2Alloc = INITIAL_RCODE2_ALLOC;
- }
-
- /* The buffer has already been allocated, is there space for one
- * more RCode?
- */
-
- else if (g_nRCode2 >= g_nRCode2Alloc)
- {
- /* If not, then reallocate the array */
-
- g_pRCode2 = (struct regm_rcode2_s*)
- realloc(g_pRCode2, g_nRCode2Alloc*sizeof(struct regm_rcode2_s));
- if (!g_pRCode2)
- {
- fatal(eNOMEMORY);
- }
-
- g_nRCode2Alloc += RCODE2_REALLOC;
- }
-}
-
-/***********************************************************************/
-
-struct regm_rcode2_s *regm_AllocateRCode2(void)
-{
- struct regm_rcode2_s *pRetSlot;
-
- /* Make sure we have memory allocated in the array for another
- * RCode.
- */
-
- regm_CheckRCode2Alloc();
-
- /* Return the reference to the next RCode slot */
-
- pRetSlot = &g_pRCode2[g_nRCode2];
- g_nRCode2++;
- return pRetSlot;
-}
-
-static void regm_PrintSpecialReg2(FILE *pStream, uint32 dwRegister)
-{
- int wRegNo = regm_GetRegNo(dwRegister);
- if (wRegNo >= NSPECIAL_REGISTERS2)
- fputc('?', pStream);
- else
- fputs(g_prgSpecialRegNames[wRegNo], pStream);
-}
-
-static void regm_PrintReg2(FILE *pStream, uint32 dwRegister)
-{
- int wKind = regm_GetKind(dwRegister);
- int wRegNo = regm_GetRegNo(dwRegister)
- if (wKind >= REGISTERS_TYPES)
- fprintf(pStream, "?%d", wRegNo);
- else if (wKind == SPECIAL_REG)
- regm_PrintSpecialReg(fg, dwRegister);
- else
- fprintf(pStream, "%s%d", g_prgRegNames[wKind], wRegNo);
-}
-
-static void regm_PrintDebugReg(const char *string, uint32 dwRegister)
-{
- if (vRegmDebug)
- {
- fputs(string, DEBUG_FILE);
- regm_PrintReg2(DEBUG_FILE, dwRegister);
- fputc('\n', DEBUG_FILE);
- }
-}
-
-/***********************************************************************/
-
-static void regm_MarkRegisterUsed(struct regm_rcode2_s *pReg,
- uint32 dwRegister)
-{
- regm_PrintDebugReg("Register used: ", dwRegister);
-
- switch (regm_GetKind(dwRegister))
- {
- case SPECIAL_REG : /* Special "global" registers */
- break; /* (ignored) */
-
- case CC_REG : /* Condition code register instance (fake) */
- break;
-
- case INARG_REG : /* Volatile register for input arguments */
- /* and output values from/to callee */
- break;
-
- case OUTARG_REG : /* Volatile register for output arguments */
- /* and input values to/from called */
- /* function (fake) */
- break;
-
- case SCRATCH_REG : /* Volatile register for general usage */
- break;
-
- case VOLATILE_REG : /* Volatile registers in general */
- case STATIC_REG : /* Static register */
- default:
- fatal(ePOFFCONFUSION);
- break;
- }
-#warning "Not Implemeted"
-}
-
-/***********************************************************************/
-
-static void regm_MarkRegisterModified(struct regm_rcode2_s *pReg,
- uint32 dwRegister)
-{
- regm_PrintDebugReg("Register modified: ", dwRegister);
-
- switch (regm_GetKind(dwRegister))
- {
- case SPECIAL_REG : /* Special "global" registers */
- break; /* (ignored) */
-
- case CC_REG : /* Condition code register instance (fake) */
- break;
-
- case INARG_REG : /* Volatile register for input arguments */
- /* and output values from/to callee */
- break;
-
- case OUTARG_REG : /* Volatile register for output arguments */
- /* and input values to/from called */
- /* function (fake) */
- break;
-
- case SCRATCH_REG : /* Volatile register for general usage */
- break;
-
- case VOLATILE_REG : /* Volatile registers in general */
- case STATIC_REG : /* Static register */
- default:
- fatal(ePOFFCONFUSION);
- break;
- }
-#warning "Not Implemeted"
-}
-
-/**********************************************************************
- * Public Functions
- **********************************************************************/
-
-/***********************************************************************/
-/* Generate function prologue: Save return address, create stack frame
- * for local variables, and save static registers that till be used.
- */
-
-void regm_GeneratePrologue(uint32 dwFrameSize)
-{
-#warning "Not implemented"
-}
-
-/***********************************************************************/
-/* Restore static registers, release stack frame and return */
-
-void regm_GenerateEpilogue(uint32 dwFrameSize)
-{
-#warning "Not implemented"
-}
-
-/***********************************************************************/
-/* Register-to-register comparisons (e.g., cmp r1, r2)
- *
- * FORM 1R: <op> <roperand1>, <roperand2>
- */
-
-void regm_GenerateForm1RCc(ubyte chOp, uint32 dwROperand1,
- uint32 dwROperand2, uint32 dwRCc)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_1RCc;
- pReg->chOp = chOp;
- pReg->u.f1rcc.dwROperand1 = dwROperand1;
- pReg->u.f1rcc.dwROperand2 = dwROperand2;
- pReg->u.f1rcc.dwRCc = dwRCc;
-
- regm_MarkRegisterUsed(pReg, dwROperand1);
- regm_MarkRegisterUsed(pReg, dwROperand2);
- regm_MarkRegisterModified(pReg, dwRCc);
-}
-
-/***********************************************************************/
-/* Register-to-immediate comparisons (e.g., cmpi r1, 1)
- *
- * FORM 1I: <op> <roperand1>, <immediate>
- */
-
-void regm_GenerateForm1ICc(ubyte chOp, uint32 dwROperand1,
- uint32 dwImmediate, uint32 dwRCc)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_1ICc;
- pReg->chOp = chOp;
- pReg->u.f1icc.dwROperand1 = dwROperand1;
- pReg->u.f1icc.dwImmediate = dwImmediate;
- pReg->u.f1icc.dwRCc = dwRCc;
-
- regm_MarkRegisterUsed(pReg, dwROperand1);
- regm_MarkRegisterModified(pReg, dwRCc);
-}
-
-/***********************************************************************/
-/* Register-to-register mov instructions (e.g, mov r1, r2)
- *
- * FORM 2R: <op> <rdest>, <roperand2>
- */
-
-void regm_GenerateForm2R(ubyte chOp, uint32 dwRDest,
- uint32 dwROperand2)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_2R;
- pReg->chOp = chOp;
- pReg->u.f2r.dwRDest = dwRDest;
- pReg->u.f2r.dwROperand2 = dwROperand2;
-
- regm_MarkRegisterModified(pReg, dwRDest);
- regm_MarkRegisterUsed(pReg, dwROperand2);
-}
-
-/***********************************************************************/
-/* Immediate-to-register mov instructions (e.g, movi r1, 1)
- *
-/* FORM 2I: <op> <rdest>, <immediate>
-*/
-
-void regm_GenerateForm2I(ubyte chOp, uint32 dwRDest,
- uint32 dwImmediate)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_2I;
- pReg->chOp = chOp;
- pReg->u.f2i.dwRDest = dwRDest;
- pReg->u.f2i.dwImmediate = dwImmediate;
-
- regm_MarkRegisterModified(pReg, dwRDest);
-}
-
-/***********************************************************************/
-/* Binary operations (e.g., add r0, r1, r2)
- * Load operations (e.g., ld r0, [r1, r2])
- * Store operations (e.g., st r0, [r1, r2])
- *
- * FORM 3R: <op> <rdest>, <roperand1>, <roperand2>
- * <rsrc>, <roperand1>, <roperand2>
- */
-
-void regm_GenerateForm3R(ubyte chOp, uint32 dwRSrcDest,
- uint32 dwROperand1, uint32 dwROperand2)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_3R;
- pReg->chOp = chOp;
- pReg->u.f3r.dwRSrcDest = dwRSrcDest;
- pReg->u.f3r.dwROperand1 = dwROperand1;
- pReg->u.f3r.dwROperand2 = dwROperand2;
-
- switch (chOp)
- {
- /* FORM 3: Arithmetic and logical operations */
- /* FORM 3: Loads */
-
- case rADD :
- case rSUB :
- case rRSB :
- case rMUL :
- case rDIV :
- case rMOD :
- case rSLL :
- case rSRL :
- case rSRA :
- case rOR :
- case rAND :
- case rXOR :
- case rANDN :
- case rLD :
- case rLDH :
- case rLDB :
- regm_MarkRegisterModified(pReg, dwRSrcDest);
- break;
-
- /* FORM 3: Loads multiple */
- case rLDM :
- {
- uint32 dwRDest = dwRSrcDest;
- int i;
- for (i = 0; i < g_dwRegisterCount; i++)
- {
- regm_MarkRegisterModified(pReg, dwRDest);
- dwRDest++;
- }
- }
- break;
-
- /* FORM 3: Stores */
- case rST :
- case rSTH :
- case rSTB :
- regm_MarkRegisterUsed(pReg, dwRSrcDest);
- break;
-
- /* FORM 3: Store multipole */
- case rSTM :
- {
- uint32 dwRSrc = dwRSrcDest;
- int i;
- for (i = 0; i < g_dwRegisterCount; i++)
- {
- regm_MarkRegisterUsed(pReg, dwRSrc);
- dwRSrc++;
- }
- }
- break;
-
- default:
- fatal(ePOFFCONFUSION);
- }
-
- regm_MarkRegisterUsed(pReg, dwROperand1);
- regm_MarkRegisterUsed(pReg, dwROperand2);
-}
-
-/***********************************************************************/
-/* Binary operations (e.g., addi r0, r1, 1)
- * Load operations (e.g., ldi r0, [r1, 4])
- * Store operations (e.g., sti r0, [r1, 4])
- *
- * FORM 3I: <op> <rdest>, <roperand1>, <immediate>
- * <rsrc>, <roperand1>, <immediate>
- */
-
-void regm_GenerateForm3I(ubyte chOp, uint32 dwRSrcDest,
- uint32 dwROperand1, uint32 dwImmediate)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_3I;
- pReg->chOp = chOp;
- pReg->u.f3i.dwRSrcDest = dwRSrcDest;
- pReg->u.f3i.dwROperand1 = dwROperand1;
- pReg->u.f3i.dwImmediate = dwImmediate;
-
- switch (chOp)
- {
- /* FORM 3: Arithmetic and logical operations */
- /* FORM 3: Loads */
-
- case rADDI :
- case rSUBI :
- case rRSBI :
- case rMULI :
- case rDIVI :
- case rMODI :
- case rSLLI :
- case rSRLI :
- case rSRAI :
- case rORI :
- case rANDI :
- case rXORI :
- case rANDNI :
- case rLDI :
- case rLDIH :
- case rLDIB :
- regm_MarkRegisterModified(pReg, dwRSrcDest);
- break;
-
- /* FORM 3: Stores */
- case rSTI :
- case rSTIH :
- case rSTIB :
- regm_MarkRegisterUsed(pReg, dwRSrcDest);
- break;
-
- default:
- fatal(ePOFFCONFUSION);
- }
-
- regm_MarkRegisterUsed(pReg, dwROperand1);
-}
-
-/***********************************************************************/
-/* Unconditional branch operations (b offset, bl offset)
- *
- * FORM 4I: <op> <pc-offset>
- */
-
-void regm_GenerateForm4I(ubyte chOp, uint32 dwOffset)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_4I;
- pReg->chOp = chOp;
- pReg->u.f4i.dwOffset = dwOffset;
-}
-
-/***********************************************************************/
-/* Conditional branch operations (e.g., beq offset)
- *
- * FORM 4I: <op> <pc-offset>
- */
-
-void regm_GenerateForm4ICc(ubyte chOp, uint32 dwOffset,
- uint32 dwRCc)
-{
- struct regm_rcode2_s *pReg = regm_AllocateRCode2();
- pReg->eForm = eFORM_4ICc;
- pReg->chOp = chOp;
- pReg->u.f4icc.dwOffset = dwOffset;
- pReg->u.f4icc.dwRCc = dwRCc;
-
- regm_MarkRegisterUsed(pReg, dwRCc);
-}
-
-/***********************************************************************/
-
-int regm_ForEachRCode2(regm_rcode2_node_t pNode, void *arg)
-{
- int ret;
- int i;
- for (i = 0; i < g_nRCode2; i++)
- {
- ret = pNode(&g_pRCode2[i], arg);
- if (ret != 0)
- {
- return ret;
- }
- }
- return 0;
-}
-
-/***********************************************************************/
+/**********************************************************************
+ * regm_registers.c
+ * Pass 2 register management functions
+ *
+ * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 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 NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * 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 OWNER 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.
+ *
+ **********************************************************************/
+
+/**********************************************************************
+ * Included Files
+ **********************************************************************/
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "keywords.h"
+#include "pofflib.h"
+#include "pedefs.h"
+#include "perr.h"
+
+#include "rinsn32.h"
+
+#include "regm.h"
+#include "regm_pass2.h"
+#include "regm_registers2.h"
+
+/**********************************************************************
+ * Definitions
+ **********************************************************************/
+
+#define INITIAL_RCODE2_ALLOC 150
+#define RCODE2_REALLOC 50
+
+/**********************************************************************
+ * Private Function Prototypes
+ **********************************************************************/
+
+/**********************************************************************
+ * Public Variables
+ **********************************************************************/
+
+struct regm_rcode2_s *g_pRCode2 = NULL;
+uint32_t g_nRCode2 = 0;
+
+/**********************************************************************
+ * Private Variables
+ **********************************************************************/
+
+static uint32_t g_nRCode2Alloc = 0;
+
+static const char * const g_prgReg2Names[NREGISTER_TYPES] =
+ { "Z", "X", "CC", "A", "R", "V", "V", "S" };
+
+static const char * const g_prgSpecialReg2Names[NSPECIAL_REGISTERS2] =
+ { "SPB", "SP", "BRG", "LSP", "CSB", "CSP", "PC", "DC", "LR", "CC"};
+
+/**********************************************************************
+ * Private Functions
+ **********************************************************************/
+
+/***********************************************************************/
+
+static void regm_CheckRCode2Alloc(void)
+{
+ /* If the RCode buffer has never been allocated, allocate it now. */
+
+ if (!g_pRCode2)
+ {
+ /* Allocate an inital buffer to hold the instructions */
+
+ g_pRCode2 = (struct regm_rcode2_s*)
+ malloc(INITIAL_RCODE2_ALLOC*sizeof(struct regm_rcode2_s));
+ if (!g_pRCode2)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ g_nRCode2Alloc = INITIAL_RCODE2_ALLOC;
+ }
+
+ /* The buffer has already been allocated, is there space for one
+ * more RCode?
+ */
+
+ else if (g_nRCode2 >= g_nRCode2Alloc)
+ {
+ /* If not, then reallocate the array */
+
+ g_pRCode2 = (struct regm_rcode2_s*)
+ realloc(g_pRCode2, g_nRCode2Alloc*sizeof(struct regm_rcode2_s));
+ if (!g_pRCode2)
+ {
+ fatal(eNOMEMORY);
+ }
+
+ g_nRCode2Alloc += RCODE2_REALLOC;
+ }
+}
+
+/***********************************************************************/
+
+struct regm_rcode2_s *regm_AllocateRCode2(void)
+{
+ struct regm_rcode2_s *pRetSlot;
+
+ /* Make sure we have memory allocated in the array for another
+ * RCode.
+ */
+
+ regm_CheckRCode2Alloc();
+
+ /* Return the reference to the next RCode slot */
+
+ pRetSlot = &g_pRCode2[g_nRCode2];
+ g_nRCode2++;
+ return pRetSlot;
+}
+
+static void regm_PrintSpecialReg2(FILE *pStream, uint32_t dwRegister)
+{
+ int wRegNo = regm_GetRegNo(dwRegister);
+ if (wRegNo >= NSPECIAL_REGISTERS2)
+ fputc('?', pStream);
+ else
+ fputs(g_prgSpecialRegNames[wRegNo], pStream);
+}
+
+static void regm_PrintReg2(FILE *pStream, uint32_t dwRegister)
+{
+ int wKind = regm_GetKind(dwRegister);
+ int wRegNo = regm_GetRegNo(dwRegister)
+ if (wKind >= REGISTERS_TYPES)
+ fprintf(pStream, "?%d", wRegNo);
+ else if (wKind == SPECIAL_REG)
+ regm_PrintSpecialReg(fg, dwRegister);
+ else
+ fprintf(pStream, "%s%d", g_prgRegNames[wKind], wRegNo);
+}
+
+static void regm_PrintDebugReg(const char *string, uint32_t dwRegister)
+{
+ if (vRegmDebug)
+ {
+ fputs(string, DEBUG_FILE);
+ regm_PrintReg2(DEBUG_FILE, dwRegister);
+ fputc('\n', DEBUG_FILE);
+ }
+}
+
+/***********************************************************************/
+
+static void regm_MarkRegisterUsed(struct regm_rcode2_s *pReg,
+ uint32_t dwRegister)
+{
+ regm_PrintDebugReg("Register used: ", dwRegister);
+
+ switch (regm_GetKind(dwRegister))
+ {
+ case SPECIAL_REG : /* Special "global" registers */
+ break; /* (ignored) */
+
+ case CC_REG : /* Condition code register instance (fake) */
+ break;
+
+ case INARG_REG : /* Volatile register for input arguments */
+ /* and output values from/to callee */
+ break;
+
+ case OUTARG_REG : /* Volatile register for output arguments */
+ /* and input values to/from called */
+ /* function (fake) */
+ break;
+
+ case SCRATCH_REG : /* Volatile register for general usage */
+ break;
+
+ case VOLATILE_REG : /* Volatile registers in general */
+ case STATIC_REG : /* Static register */
+ default:
+ fatal(ePOFFCONFUSION);
+ break;
+ }
+#warning "Not Implemeted"
+}
+
+/***********************************************************************/
+
+static void regm_MarkRegisterModified(struct regm_rcode2_s *pReg,
+ uint32_t dwRegister)
+{
+ regm_PrintDebugReg("Register modified: ", dwRegister);
+
+ switch (regm_GetKind(dwRegister))
+ {
+ case SPECIAL_REG : /* Special "global" registers */
+ break; /* (ignored) */
+
+ case CC_REG : /* Condition code register instance (fake) */
+ break;
+
+ case INARG_REG : /* Volatile register for input arguments */
+ /* and output values from/to callee */
+ break;
+
+ case OUTARG_REG : /* Volatile register for output arguments */
+ /* and input values to/from called */
+ /* function (fake) */
+ break;
+
+ case SCRATCH_REG : /* Volatile register for general usage */
+ break;
+
+ case VOLATILE_REG : /* Volatile registers in general */
+ case STATIC_REG : /* Static register */
+ default:
+ fatal(ePOFFCONFUSION);
+ break;
+ }
+#warning "Not Implemeted"
+}
+
+/**********************************************************************
+ * Public Functions
+ **********************************************************************/
+
+/***********************************************************************/
+/* Generate function prologue: Save return address, create stack frame
+ * for local variables, and save static registers that till be used.
+ */
+
+void regm_GeneratePrologue(uint32_t dwFrameSize)
+{
+#warning "Not implemented"
+}
+
+/***********************************************************************/
+/* Restore static registers, release stack frame and return */
+
+void regm_GenerateEpilogue(uint32_t dwFrameSize)
+{
+#warning "Not implemented"
+}
+
+/***********************************************************************/
+/* Register-to-register comparisons (e.g., cmp r1, r2)
+ *
+ * FORM 1R: <op> <roperand1>, <roperand2>
+ */
+
+void regm_GenerateForm1RCc(uint8_t chOp, uint32_t dwROperand1,
+ uint32_t dwROperand2, uint32_t dwRCc)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_1RCc;
+ pReg->chOp = chOp;
+ pReg->u.f1rcc.dwROperand1 = dwROperand1;
+ pReg->u.f1rcc.dwROperand2 = dwROperand2;
+ pReg->u.f1rcc.dwRCc = dwRCc;
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+ regm_MarkRegisterUsed(pReg, dwROperand2);
+ regm_MarkRegisterModified(pReg, dwRCc);
+}
+
+/***********************************************************************/
+/* Register-to-immediate comparisons (e.g., cmpi r1, 1)
+ *
+ * FORM 1I: <op> <roperand1>, <immediate>
+ */
+
+void regm_GenerateForm1ICc(uint8_t chOp, uint32_t dwROperand1,
+ uint32_t dwImmediate, uint32_t dwRCc)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_1ICc;
+ pReg->chOp = chOp;
+ pReg->u.f1icc.dwROperand1 = dwROperand1;
+ pReg->u.f1icc.dwImmediate = dwImmediate;
+ pReg->u.f1icc.dwRCc = dwRCc;
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+ regm_MarkRegisterModified(pReg, dwRCc);
+}
+
+/***********************************************************************/
+/* Register-to-register mov instructions (e.g, mov r1, r2)
+ *
+ * FORM 2R: <op> <rdest>, <roperand2>
+ */
+
+void regm_GenerateForm2R(uint8_t chOp, uint32_t dwRDest,
+ uint32_t dwROperand2)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_2R;
+ pReg->chOp = chOp;
+ pReg->u.f2r.dwRDest = dwRDest;
+ pReg->u.f2r.dwROperand2 = dwROperand2;
+
+ regm_MarkRegisterModified(pReg, dwRDest);
+ regm_MarkRegisterUsed(pReg, dwROperand2);
+}
+
+/***********************************************************************/
+/* Immediate-to-register mov instructions (e.g, movi r1, 1)
+ *
+/* FORM 2I: <op> <rdest>, <immediate>
+*/
+
+void regm_GenerateForm2I(uint8_t chOp, uint32_t dwRDest,
+ uint32_t dwImmediate)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_2I;
+ pReg->chOp = chOp;
+ pReg->u.f2i.dwRDest = dwRDest;
+ pReg->u.f2i.dwImmediate = dwImmediate;
+
+ regm_MarkRegisterModified(pReg, dwRDest);
+}
+
+/***********************************************************************/
+/* Binary operations (e.g., add r0, r1, r2)
+ * Load operations (e.g., ld r0, [r1, r2])
+ * Store operations (e.g., st r0, [r1, r2])
+ *
+ * FORM 3R: <op> <rdest>, <roperand1>, <roperand2>
+ * <rsrc>, <roperand1>, <roperand2>
+ */
+
+void regm_GenerateForm3R(uint8_t chOp, uint32_t dwRSrcDest,
+ uint32_t dwROperand1, uint32_t dwROperand2)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_3R;
+ pReg->chOp = chOp;
+ pReg->u.f3r.dwRSrcDest = dwRSrcDest;
+ pReg->u.f3r.dwROperand1 = dwROperand1;
+ pReg->u.f3r.dwROperand2 = dwROperand2;
+
+ switch (chOp)
+ {
+ /* FORM 3: Arithmetic and logical operations */
+ /* FORM 3: Loads */
+
+ case rADD :
+ case rSUB :
+ case rRSB :
+ case rMUL :
+ case rDIV :
+ case rMOD :
+ case rSLL :
+ case rSRL :
+ case rSRA :
+ case rOR :
+ case rAND :
+ case rXOR :
+ case rANDN :
+ case rLD :
+ case rLDH :
+ case rLDB :
+ regm_MarkRegisterModified(pReg, dwRSrcDest);
+ break;
+
+ /* FORM 3: Loads multiple */
+ case rLDM :
+ {
+ uint32_t dwRDest = dwRSrcDest;
+ int i;
+ for (i = 0; i < g_dwRegisterCount; i++)
+ {
+ regm_MarkRegisterModified(pReg, dwRDest);
+ dwRDest++;
+ }
+ }
+ break;
+
+ /* FORM 3: Stores */
+ case rST :
+ case rSTH :
+ case rSTB :
+ regm_MarkRegisterUsed(pReg, dwRSrcDest);
+ break;
+
+ /* FORM 3: Store multipole */
+ case rSTM :
+ {
+ uint32_t dwRSrc = dwRSrcDest;
+ int i;
+ for (i = 0; i < g_dwRegisterCount; i++)
+ {
+ regm_MarkRegisterUsed(pReg, dwRSrc);
+ dwRSrc++;
+ }
+ }
+ break;
+
+ default:
+ fatal(ePOFFCONFUSION);
+ }
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+ regm_MarkRegisterUsed(pReg, dwROperand2);
+}
+
+/***********************************************************************/
+/* Binary operations (e.g., addi r0, r1, 1)
+ * Load operations (e.g., ldi r0, [r1, 4])
+ * Store operations (e.g., sti r0, [r1, 4])
+ *
+ * FORM 3I: <op> <rdest>, <roperand1>, <immediate>
+ * <rsrc>, <roperand1>, <immediate>
+ */
+
+void regm_GenerateForm3I(uint8_t chOp, uint32_t dwRSrcDest,
+ uint32_t dwROperand1, uint32_t dwImmediate)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_3I;
+ pReg->chOp = chOp;
+ pReg->u.f3i.dwRSrcDest = dwRSrcDest;
+ pReg->u.f3i.dwROperand1 = dwROperand1;
+ pReg->u.f3i.dwImmediate = dwImmediate;
+
+ switch (chOp)
+ {
+ /* FORM 3: Arithmetic and logical operations */
+ /* FORM 3: Loads */
+
+ case rADDI :
+ case rSUBI :
+ case rRSBI :
+ case rMULI :
+ case rDIVI :
+ case rMODI :
+ case rSLLI :
+ case rSRLI :
+ case rSRAI :
+ case rORI :
+ case rANDI :
+ case rXORI :
+ case rANDNI :
+ case rLDI :
+ case rLDIH :
+ case rLDIB :
+ regm_MarkRegisterModified(pReg, dwRSrcDest);
+ break;
+
+ /* FORM 3: Stores */
+ case rSTI :
+ case rSTIH :
+ case rSTIB :
+ regm_MarkRegisterUsed(pReg, dwRSrcDest);
+ break;
+
+ default:
+ fatal(ePOFFCONFUSION);
+ }
+
+ regm_MarkRegisterUsed(pReg, dwROperand1);
+}
+
+/***********************************************************************/
+/* Unconditional branch operations (b offset, bl offset)
+ *
+ * FORM 4I: <op> <pc-offset>
+ */
+
+void regm_GenerateForm4I(uint8_t chOp, uint32_t dwOffset)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_4I;
+ pReg->chOp = chOp;
+ pReg->u.f4i.dwOffset = dwOffset;
+}
+
+/***********************************************************************/
+/* Conditional branch operations (e.g., beq offset)
+ *
+ * FORM 4I: <op> <pc-offset>
+ */
+
+void regm_GenerateForm4ICc(uint8_t chOp, uint32_t dwOffset,
+ uint32_t dwRCc)
+{
+ struct regm_rcode2_s *pReg = regm_AllocateRCode2();
+ pReg->eForm = eFORM_4ICc;
+ pReg->chOp = chOp;
+ pReg->u.f4icc.dwOffset = dwOffset;
+ pReg->u.f4icc.dwRCc = dwRCc;
+
+ regm_MarkRegisterUsed(pReg, dwRCc);
+}
+
+/***********************************************************************/
+
+int regm_ForEachRCode2(regm_rcode2_node_t pNode, void *arg)
+{
+ int ret;
+ int i;
+ for (i = 0; i < g_nRCode2; i++)
+ {
+ ret = pNode(&g_pRCode2[i], arg);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ }
+ return 0;
+}
+
+/***********************************************************************/