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.c541
1 files changed, 541 insertions, 0 deletions
diff --git a/misc/pascal/insn32/regm/regm_registers2.c b/misc/pascal/insn32/regm/regm_registers2.c
new file mode 100644
index 000000000..2973dc7c3
--- /dev/null
+++ b/misc/pascal/insn32/regm/regm_registers2.c
@@ -0,0 +1,541 @@
+/**********************************************************************
+ * 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;
+}
+
+/***********************************************************************/