* Added support for doing shifts by helper functions
[fw/sdcc] / src / SDCCsymt.c
index 6f20b9825bf13e93646e0b470868de4cb5017ea3..2037ea608b518dac9a7f88430ef4d48ed9a1e3b3 100644 (file)
@@ -30,7 +30,7 @@ char *nounName(sym_link *sl) {
     {
     case V_INT: {
       if (SPEC_LONG(sl)) return "long";
-      if (SPEC_SHORT(sl)) return "short";
+      if (sl->select.s._short) return "short";
       return "int";
     }
     case V_FLOAT: return "float";
@@ -98,16 +98,19 @@ addSym (bucket ** stab,
        void *sym,
        char *sname,
        int level,
-       int block)
+       int block,
+       int checkType)
 {
   int i;                       /* index into the hash Table */
   bucket *bp;                  /* temp bucket    *         */
 
-  if (getenv("DEBUG_SANITY")) {
-    fprintf (stderr, "addSym: %s\n", sname);
+  if (checkType) {
+    if (getenv("DEBUG_SANITY")) {
+      fprintf (stderr, "addSym: %s ", sname);
+    }
+    /* make sure the type is complete and sane */
+    checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
   }
-  /* Make sure sym is a symbol and not a structdef */
-  if (StructTab!=stab) checkTypeSanity(((symbol *)sym)->etype, sname);
 
   /* the symbols are always added at the head of the list  */
   i = hashKey (sname);
@@ -409,7 +412,7 @@ addDecl (symbol * sym, int type, sym_link * p)
     {
       if (IS_SPEC (sym->etype) && IS_SPEC (head) && head == tail)
        {
-         sym->etype = mergeSpec (sym->etype, head);
+         sym->etype = mergeSpec (sym->etype, head, sym->name);
        }
       else
        {
@@ -455,49 +458,63 @@ addDecl (symbol * sym, int type, sym_link * p)
   checkTypeSanity: prevent the user from doing e.g.:
   unsigned float uf;
   ------------------------------------------------------------------*/
-void checkTypeSanity(sym_link *dest, char *name) {
+void checkTypeSanity(sym_link *etype, char *name) {
   char *noun;
 
-  if (!dest) {
+  if (!etype) {
+    if (getenv("DEBUG_SANITY")) {
+      fprintf (stderr, "sanity check skipped for %s (etype==0)\n", name);
+    }
+    return;
+  }
+
+  if (!IS_SPEC(etype)) {
     if (getenv("DEBUG_SANITY")) {
-      printf ("sanity check skipped for %s\n", name);
+      fprintf (stderr, "sanity check skipped for %s (!IS_SPEC)\n", name);
     }
     return;
   }
 
-  noun=nounName(dest);
+  noun=nounName(etype);
 
   if (getenv("DEBUG_SANITY")) {
-    printf ("checking sanity for %s\n", name);
+    fprintf (stderr, "checking sanity for %s %x\n", name, (int)etype);
   }
 
-  if ((SPEC_NOUN(dest)==V_CHAR || 
-       SPEC_NOUN(dest)==V_FLOAT || 
-       SPEC_NOUN(dest)==V_DOUBLE || 
-       SPEC_NOUN(dest)==V_VOID) &&
-      (SPEC_SHORT(dest) || SPEC_LONG(dest))) {
+  if ((SPEC_NOUN(etype)==V_CHAR || 
+       SPEC_NOUN(etype)==V_FLOAT || 
+       SPEC_NOUN(etype)==V_DOUBLE || 
+       SPEC_NOUN(etype)==V_VOID) &&
+      (etype->select.s._short || SPEC_LONG(etype))) {
     // long or short for char float double or void
     werror (E_LONG_OR_SHORT_INVALID, noun, name);
   }
-  if ((SPEC_NOUN(dest)==V_FLOAT || 
-       SPEC_NOUN(dest)==V_DOUBLE || 
-       SPEC_NOUN(dest)==V_VOID) && 
-      (SPEC_SIGNED(dest) || SPEC_USIGN(dest))) {
+  if ((SPEC_NOUN(etype)==V_FLOAT || 
+       SPEC_NOUN(etype)==V_DOUBLE || 
+       SPEC_NOUN(etype)==V_VOID) && 
+      (etype->select.s._signed || SPEC_USIGN(etype))) {
     // signed or unsigned for float double or void
     werror (E_SIGNED_OR_UNSIGNED_INVALID, noun, name);
   }
 
-  if (!SPEC_NOUN(dest)) {
-    if (SPEC_SIGNED(dest) || SPEC_USIGN(dest)) {
-      SPEC_NOUN(dest)=V_INT;
-    }
+  // special case for "short"
+  if (etype->select.s._short) {
+    SPEC_NOUN(etype) = options.shortis8bits ? V_CHAR : V_INT;
+    etype->select.s._short = 0;
+  }
+
+  /* if no noun e.g. 
+     "const a;" or "data b;" or "signed s" or "long l"
+     assume an int */
+  if (!SPEC_NOUN(etype)) {
+    SPEC_NOUN(etype)=V_INT;
   }
 
-  if (SPEC_SIGNED(dest) && SPEC_USIGN(dest)) {
+  if (etype->select.s._signed && SPEC_USIGN(etype)) {
     // signed AND unsigned 
     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
   }
-  if (SPEC_SHORT(dest) && SPEC_LONG(dest)) {
+  if (etype->select.s._short && SPEC_LONG(etype)) {
     // short AND long
     werror (E_LONG_AND_SHORT_INVALID, noun, name);
   }
@@ -507,34 +524,77 @@ void checkTypeSanity(sym_link *dest, char *name) {
 /*------------------------------------------------------------------*/
 /* mergeSpec - merges two specifiers and returns the new one        */
 /*------------------------------------------------------------------*/
+#define LAST_MINUTE_2_3_0_FIX
 sym_link *
-mergeSpec (sym_link * dest, sym_link * src)
+mergeSpec (sym_link * dest, sym_link * src, char *name)
 {
 
-  /* we shouldn't redeclare the type */
-  if ((SPEC_NOUN (dest) && SPEC_NOUN (src)) && 
-      (SPEC_NOUN(dest) != SPEC_NOUN(src))) {
-    if (getenv("DEBUG_SANITY")) {
-      fprintf (stderr, "mergeSpec: ");
+#ifdef LAST_MINUTE_2_3_0_FIX
+  sym_link *symlink;
+
+  if (!IS_SPEC(dest)) {
+    // This should not happen
+    fprintf (stderr, "*** internal error: can't merge declarators\n");
+  }
+  if (!IS_SPEC(src)) {
+    // here we have a declarator as source, reverse them
+    symlink=src;
+    src=dest;
+    dest=symlink;
+    while (!IS_SPEC(dest)) {
+      // and find the specifier
+      dest=dest->next;
     }
-    werror(E_TWO_OR_MORE_DATA_TYPES, yylval.yychar);
+  } else {
+    symlink=dest;
   }
+#endif
 
-  /* if noun different then src overrides */
-  if (SPEC_NOUN (dest) != SPEC_NOUN (src) && !SPEC_NOUN (dest))
-    SPEC_NOUN (dest) = SPEC_NOUN (src);
+  if (getenv("DEBUG_mergeSpec")) {
+    fprintf (stderr, "mergeSpec: \"%s\"\n", name);
+  }
+
+  if (SPEC_NOUN(src)) {
+    if (!SPEC_NOUN(dest)) {
+      SPEC_NOUN(dest)=SPEC_NOUN(src);
+    } else {
+      /* we shouldn't redeclare the type */
+      if (getenv("DEBUG_SANITY")) {
+       fprintf (stderr, "mergeSpec: ");
+      }
+      werror(E_TWO_OR_MORE_DATA_TYPES, name);
+    }
+  }
+  
+  if (SPEC_SCLS(src)) {
+    /* if destination has no storage class */
+    if (!SPEC_SCLS (dest) || SPEC_SCLS(dest)==S_REGISTER) {
+      SPEC_SCLS (dest) = SPEC_SCLS (src);
+    } else {
+      if (getenv("DEBUG_SANITY")) {
+       fprintf (stderr, "mergeSpec: ");
+      }
+      werror(E_TWO_OR_MORE_STORAGE_CLASSES, name);
+    }
+  }
 
-  /* if destination has no storage class */
-  if (!SPEC_SCLS (dest) || 
-      ((SPEC_SCLS(dest) == S_CONSTANT || SPEC_SCLS(dest) == S_REGISTER) && 
-       SPEC_SCLS (src)))
-    SPEC_SCLS (dest) = SPEC_SCLS (src);
-  /* special case for const */
   /* copy all the specifications  */
+
+  // we really should do: 
+#if 0
+  if (SPEC_what(src)) {
+    if (SPEC_what(dest)) {
+      werror(W_DUPLICATE_SPEC, "what");
+    }
+    SPEC_what(dst)|=SPEC_what(src);
+  }
+#endif
+  // but there are more important thing right now
+
   SPEC_LONG (dest) |= SPEC_LONG (src);
-  SPEC_SHORT (dest) |= SPEC_SHORT (src);
+  dest->select.s._short|=src->select.s._short;
   SPEC_USIGN (dest) |= SPEC_USIGN (src);
-  SPEC_SIGNED (dest) |= SPEC_SIGNED (src);
+  dest->select.s._signed|=src->select.s._signed;
   SPEC_STAT (dest) |= SPEC_STAT (src);
   SPEC_EXTR (dest) |= SPEC_EXTR (src);
   SPEC_ABSA (dest) |= SPEC_ABSA (src);
@@ -554,7 +614,11 @@ mergeSpec (sym_link * dest, sym_link * src)
   if (IS_STRUCT (dest) && SPEC_STRUCT (dest) == NULL)
     SPEC_STRUCT (dest) = SPEC_STRUCT (src);
 
+#ifdef LAST_MINUTE_2_3_0_FIX
+  return symlink;
+#else
   return dest;
+#endif
 }
 
 /*------------------------------------------------------------------*/
@@ -677,7 +741,7 @@ getSize (sym_link * p)
       switch (SPEC_NOUN (p))
        {                       /* depending on the specifier type */
        case V_INT:
-         return (IS_LONG (p) ? LONGSIZE : (IS_SHORT (p) ? SHORTSIZE : INTSIZE));
+         return (IS_LONG (p) ? LONGSIZE : INTSIZE);
        case V_FLOAT:
          return FLOATSIZE;
        case V_CHAR:
@@ -736,7 +800,7 @@ bitsForType (sym_link * p)
       switch (SPEC_NOUN (p))
        {                       /* depending on the specifier type */
        case V_INT:
-         return (IS_LONG (p) ? LONGSIZE * 8 : (IS_SHORT (p) ? SHORTSIZE * 8 : INTSIZE * 8));
+         return (IS_LONG (p) ? LONGSIZE * 8 : INTSIZE * 8);
        case V_FLOAT:
          return FLOATSIZE * 8;
        case V_CHAR:
@@ -894,17 +958,17 @@ addSymChain (symbol * symHead)
        {
 
          /* previous definition extern ? */
-         if (1 || IS_EXTERN (csym->etype))
+         if (IS_EXTERN (csym->etype))
            {
              /* do types match ? */
-             if (checkType (csym->type, sym->type) != 1)
+             if (compareType (csym->type, sym->type) != 1)
                /* no then error */
                werror (E_DUPLICATE, csym->name);
 
              /* delete current entry */
              deleteSym (SymbolTab, csym, csym->name);
              /* add new entry */
-             addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
+             addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
            }
          else                  /* not extern */
            werror (E_DUPLICATE, sym->name);
@@ -918,11 +982,11 @@ addSymChain (symbol * symHead)
          /* then check the type with the current one         */
          if (IS_EXTERN (csym->etype))
            {
-             if (checkType (csym->type, sym->type) <= 0)
+             if (compareType (csym->type, sym->type) <= 0)
                werror (W_EXTERN_MISMATCH, csym->name);
            }
        }
-      addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
+      addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
     }
 }
 
@@ -1074,11 +1138,18 @@ compStructSize (int su, structdef * sdef)
 static void 
 checkSClass (symbol * sym)
 {
+  if (getenv("DEBUG_SANITY")) {
+    fprintf (stderr, "checkSClass: %s \n", sym->name);
+  }
+  if (strcmp(sym->name, "_testsGlobal")==0) {
+    printf ("oach\n");
+  }
+  
   /* type is literal can happen foe enums change
      to auto */
   if (SPEC_SCLS (sym->etype) == S_LITERAL && !SPEC_ENUM (sym->etype))
     SPEC_SCLS (sym->etype) = S_AUTO;
-
+  
   /* if sfr or sbit then must also be */
   /* volatile the initial value will be xlated */
   /* to an absolute address */
@@ -1095,26 +1166,24 @@ checkSClass (symbol * sym)
          sym->ival = NULL;
        }
     }
-
+  
   /* if absolute address given then it mark it as
      volatile */
   if (IS_ABSOLUTE (sym->etype))
     SPEC_VOLATILE (sym->etype) = 1;
-
+  
   /* global variables declared const put into code */
   if (sym->level == 0 &&
-      SPEC_SCLS (sym->etype) == S_CONSTANT)
-    {
-      SPEC_SCLS (sym->etype) = S_CODE;
-      SPEC_CONST (sym->etype) = 1;
-    }
-
+      SPEC_CONST (sym->etype)) {
+    SPEC_SCLS (sym->etype) = S_CODE;
+  }
+  
   /* global variable in code space is a constant */
   if (sym->level == 0 &&
       SPEC_SCLS (sym->etype) == S_CODE &&
       port->mem.code_ro)
     SPEC_CONST (sym->etype) = 1;
-
+  
 
   /* if bit variable then no storage class can be */
   /* specified since bit is already a storage */
@@ -1135,6 +1204,7 @@ checkSClass (symbol * sym)
       sym->ival = NULL;
     }
 
+#if 0
   /* if this is an automatic symbol then */
   /* storage class will be ignored and   */
   /* symbol will be allocated on stack/  */
@@ -1145,13 +1215,29 @@ checkSClass (symbol * sym)
        SPEC_SCLS (sym->etype) != S_FIXED &&
        SPEC_SCLS (sym->etype) != S_REGISTER &&
        SPEC_SCLS (sym->etype) != S_STACK &&
-       SPEC_SCLS (sym->etype) != S_XSTACK &&
-       SPEC_SCLS (sym->etype) != S_CONSTANT))
+       SPEC_SCLS (sym->etype) != S_XSTACK))
     {
       werror (E_AUTO_ASSUMED, sym->name);
       SPEC_SCLS (sym->etype) = S_AUTO;
     }
-
+#else
+  /* if this is an atomatic symbol */
+  if (sym->level && (options.stackAuto || reentrant)) {
+    if ((SPEC_SCLS (sym->etype) == S_AUTO ||
+        SPEC_SCLS (sym->etype) == S_FIXED ||
+        SPEC_SCLS (sym->etype) == S_REGISTER ||
+        SPEC_SCLS (sym->etype) == S_STACK ||
+        SPEC_SCLS (sym->etype) == S_XSTACK)) {
+      SPEC_SCLS (sym->etype) = S_AUTO;
+    } else {
+      /* storage class may only be specified for statics */
+      if (!IS_STATIC(sym->etype)) {
+       werror (E_AUTO_ASSUMED, sym->name);
+      }
+    }
+  }
+#endif
+  
   /* automatic symbols cannot be given   */
   /* an absolute address ignore it      */
   if (sym->level &&
@@ -1368,10 +1454,10 @@ computeType (sym_link * type1, sym_link * type2)
 }
 
 /*------------------------------------------------------------------*/
-/* checkType - will do type check return 1 if match                 */
+/* compareType - will do type check return 1 if match                 */
 /*------------------------------------------------------------------*/
 int 
-checkType (sym_link * dest, sym_link * src)
+compareType (sym_link * dest, sym_link * src)
 {
   if (!dest && !src)
     return 1;
@@ -1388,13 +1474,13 @@ checkType (sym_link * dest, sym_link * src)
       if (IS_DECL (src))
        {
          if (DCL_TYPE (src) == DCL_TYPE (dest))
-           return checkType (dest->next, src->next);
+           return compareType (dest->next, src->next);
          else if (IS_PTR (src) && IS_PTR (dest))
            return -1;
          else if (IS_PTR (dest) && IS_ARRAY (src))
            return -1;
          else if (IS_PTR (dest) && IS_FUNC (dest->next) && IS_FUNC (src))
-           return -1 * checkType (dest->next, src);
+           return -1 * compareType (dest->next, src);
          else
            return 0;
        }
@@ -1418,17 +1504,6 @@ checkType (sym_link * dest, sym_link * src)
       SPEC_NOUN (src) == V_VOID)
     return -1;
 
-  /* char === to short */
-  if (SPEC_NOUN (dest) == V_CHAR &&
-      SPEC_NOUN (src) == V_INT &&
-      SPEC_SHORT (src))
-    return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
-
-  if (SPEC_NOUN (src) == V_CHAR &&
-      SPEC_NOUN (dest) == V_INT &&
-      SPEC_SHORT (dest))
-    return (SPEC_USIGN (src) == SPEC_USIGN (dest) ? 1 : -2);
-
   /* if they are both bitfields then if the lengths
      and starts don't match */
   if (IS_BITFIELD (dest) && IS_BITFIELD (src) &&
@@ -1458,9 +1533,6 @@ checkType (sym_link * dest, sym_link * src)
   if (SPEC_LONG (dest) != SPEC_LONG (src))
     return -1;
 
-  if (SPEC_SHORT (dest) != SPEC_SHORT (src))
-    return -1;
-
   if (SPEC_USIGN (dest) != SPEC_USIGN (src))
     return -2;
 
@@ -1468,7 +1540,7 @@ checkType (sym_link * dest, sym_link * src)
 }
 
 /*------------------------------------------------------------------*/
-/* inCalleeSaveList - return 1 if found in calle save list          */
+/* inCalleeSaveList - return 1 if found in callee save list          */
 /*------------------------------------------------------------------*/
 bool 
 inCalleeSaveList (char *s)
@@ -1559,8 +1631,16 @@ checkFunction (symbol * sym)
 {
   symbol *csym;
   value *exargs, *acargs;
+  value *checkValue;
   int argCnt = 0;
 
+  if (getenv("DEBUG_SANITY")) {
+    fprintf (stderr, "checkFunction: %s ", sym->name);
+  }
+
+  /* make sure the type is complete and sane */
+  checkTypeSanity(((symbol *)sym)->etype, ((symbol *)sym)->name);
+
   /* if not type then some kind of error */
   if (!sym->type)
     return 0;
@@ -1606,7 +1686,7 @@ checkFunction (symbol * sym)
     }
 
   /* check the return value type   */
-  if (checkType (csym->type, sym->type) <= 0)
+  if (compareType (csym->type, sym->type) <= 0)
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "type");
       werror (E_CONTINUE, "previous definition type ");
@@ -1621,13 +1701,16 @@ checkFunction (symbol * sym)
   if (SPEC_INTRTN (csym->etype) != SPEC_INTRTN (sym->etype))
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "interrupt");
-      return 0;
     }
 
   if (SPEC_BANK (csym->etype) != SPEC_BANK (sym->etype))
     {
       werror (E_PREV_DEF_CONFLICT, csym->name, "using");
-      return 0;
+    }
+
+  if (SPEC_NAKED (csym->etype) != SPEC_NAKED (sym->etype))
+    {
+      werror (E_PREV_DEF_CONFLICT, csym->name, "_naked");
     }
 
   /* compare expected agrs with actual args */
@@ -1639,7 +1722,12 @@ checkFunction (symbol * sym)
        exargs && acargs;
        exargs = exargs->next, acargs = acargs->next, argCnt++)
     {
-      value *checkValue;
+      if (getenv("DEBUG_SANITY")) {
+       fprintf (stderr, "checkFunction: %s ", exargs->name);
+      }
+      /* make sure the type is complete and sane */
+      checkTypeSanity(exargs->etype, exargs->name);
+
       /* If the actual argument is an array, any prototype
        * will have modified it to a pointer. Duplicate that
        * change here.
@@ -1654,7 +1742,7 @@ checkFunction (symbol * sym)
          checkValue = acargs;
        }
 
-      if (checkType (exargs->type, checkValue->type) <= 0)
+      if (compareType (exargs->type, checkValue->type) <= 0)
        {
          werror (E_ARG_TYPE, argCnt);
          return 0;
@@ -1669,7 +1757,7 @@ checkFunction (symbol * sym)
   /* replace with this defition */
   sym->cdef = csym->cdef;
   deleteSym (SymbolTab, csym, csym->name);
-  addSym (SymbolTab, sym, sym->name, sym->level, sym->block);
+  addSym (SymbolTab, sym, sym->name, sym->level, sym->block, 1);
   if (IS_EXTERN (csym->etype) && !
       IS_EXTERN (sym->etype))
     {
@@ -1891,8 +1979,6 @@ printTypeChain (sym_link * type, FILE * of)
            case V_INT:
              if (IS_LONG (type))
                fprintf (of, "long ");
-             if (IS_SHORT (type))
-               fprintf (of, "short ");
              fprintf (of, "int ");
              break;
 
@@ -1986,8 +2072,6 @@ cdbTypeInfo (sym_link * type, FILE * of)
            case V_INT:
              if (IS_LONG (type))
                fprintf (of, "SL");
-             else if (IS_SHORT (type))
-               fprintf (of, "SS");
              else
                fprintf (of, "SI");
              break;
@@ -2177,22 +2261,21 @@ symbol *__muldiv[3][3][2];
 sym_link *__multypes[3][2];
 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
 symbol *__conv[2][3][2];
+/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
+symbol *__rlrr[2][3][2];
 
 sym_link *floatType;
 
-static void 
-_makeRegParam (symbol * sym)
+static char *
+_mangleFunctionName(char *in)
 {
-  value *val;
-
-  val = sym->args;             /* loop thru all the arguments   */
-
-  /* reset regparm for the port */
-  (*port->reset_regparms) ();
-  while (val)
+  if (port->getMangledFunctionName) 
     {
-      SPEC_REGPARM (val->etype) = 1;
-      val = val->next;
+      return port->getMangledFunctionName(in);
+    }
+  else
+    {
+      return in;
     }
 }
 
@@ -2214,8 +2297,12 @@ initCSupport ()
   {
     "s", "u"
   };
+  const char *srlrr[] =
+  {
+    "rl", "rr"
+  };
 
-  int bwd, su, muldivmod, tofrom;
+  int bwd, su, muldivmod, tofrom, rlrr;
 
   floatType = newFloatLink ();
 
@@ -2261,12 +2348,12 @@ initCSupport ()
              if (tofrom)
                {
                  sprintf (buffer, "__fs2%s%s", ssu[su], sbwd[bwd]);
-                 __conv[tofrom][bwd][su] = funcOfType (buffer, __multypes[bwd][su], floatType, 1, options.float_rent);
+                 __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], floatType, 1, options.float_rent);
                }
              else
                {
                  sprintf (buffer, "__%s%s2fs", ssu[su], sbwd[bwd]);
-                 __conv[tofrom][bwd][su] = funcOfType (buffer, floatType, __multypes[bwd][su], 1, options.float_rent);
+                 __conv[tofrom][bwd][su] = funcOfType (_mangleFunctionName(buffer), floatType, __multypes[bwd][su], 1, options.float_rent);
                }
            }
        }
@@ -2282,10 +2369,24 @@ initCSupport ()
                       smuldivmod[muldivmod],
                       ssu[su],
                       sbwd[bwd]);
-              __muldiv[muldivmod][bwd][su] = funcOfType (buffer, __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
+              __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
              SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
-             if (bwd < port->muldiv.force_reg_param_below)
-               _makeRegParam (__muldiv[muldivmod][bwd][su]);
+           }
+       }
+    }
+
+  for (rlrr = 0; rlrr < 2; rlrr++)
+    {
+      for (bwd = 0; bwd < 3; bwd++)
+       {
+         for (su = 0; su < 2; su++)
+           {
+             sprintf (buffer, "_%s%s%s",
+                      srlrr[rlrr],
+                      ssu[su],
+                      sbwd[bwd]);
+              __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
+             SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1;
            }
        }
     }