* sim/ucsim/hc08.src/inst.cc,
[fw/sdcc] / src / hc08 / gen.c
index 29637fae83cd5edb872d0705fbeac5667f4097b4..9c94f3559b73891c3037ce99b0dc5e295720476e 100644 (file)
@@ -1352,7 +1352,7 @@ static asmop *
 aopForRemat (symbol * sym)
 {
   iCode *ic = sym->rematiCode;
-  asmop *aop = newAsmop (AOP_IMMD);
+  asmop *aop = NULL;
   int ptr_type=0;
   int val = 0;
 
@@ -1377,22 +1377,40 @@ aopForRemat (symbol * sym)
       ic = OP_SYMBOL (IC_LEFT (ic))->rematiCode;
     }
 
-  if (val)
-    sprintf (buffer, "(%s %c 0x%04x)",
-            OP_SYMBOL (IC_LEFT (ic))->rname,
-            val >= 0 ? '+' : '-',
-            abs (val) & 0xffff);
-  else
-    strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
+  if (ic->op == ADDRESS_OF)
+    {
+      if (val)
+        sprintf (buffer, "(%s %c 0x%04x)",
+                OP_SYMBOL (IC_LEFT (ic))->rname,
+                val >= 0 ? '+' : '-',
+                abs (val) & 0xffff);
+      else
+        strcpy (buffer, OP_SYMBOL (IC_LEFT (ic))->rname);
 
-  aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
-  strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
-  /* set immd2 field if required */
-  if (aop->aopu.aop_immd.from_cast_remat) {
+      aop = newAsmop (AOP_IMMD);
+      aop->aopu.aop_immd.aop_immd1 = Safe_calloc (1, strlen (buffer) + 1);
+      strcpy (aop->aopu.aop_immd.aop_immd1, buffer);
+      /* set immd2 field if required */
+      if (aop->aopu.aop_immd.from_cast_remat)
+       {
          sprintf(buffer,"#0x%02x",ptr_type);
          aop->aopu.aop_immd.aop_immd2 = Safe_calloc (1, strlen (buffer) + 1);
          strcpy (aop->aopu.aop_immd.aop_immd2, buffer);
-  }
+       }
+    }
+  else if (ic->op == '=')
+    {
+      val += (int) operandLitValue (IC_RIGHT (ic));
+      val &= 0xffff;
+      sprintf (buffer, "0x%04x", val);
+      aop = newAsmop (AOP_LIT);
+      aop->aopu.aop_lit = constVal (buffer);
+    }
+  else
+    werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+           "unexpected rematerialization");
+
+
 
   return aop;
 }
@@ -1902,7 +1920,7 @@ aopAdrStr (asmop * aop, int loffset, bool bit16)
 
     case AOP_LIT:
       if (bit16)
-        return aopLiteralLong (aop->aopu.aop_lit, loffset, 2);
+        return aopLiteralLong (aop->aopu.aop_lit, /*loffset*/ 0, 2);
       else
         return aopLiteral (aop->aopu.aop_lit, loffset);
 
@@ -2080,9 +2098,12 @@ asmopToBool (asmop *aop, bool resultInA)
             emitcode ("", "%05d$:", (tlbl->key + 100));
           }
         else
-          werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
-                  "Bad rIdx in asmToBool");
-          return;
+          {
+            werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+                    "Bad rIdx in asmToBool");
+            return;
+          }
+        break;
       case AOP_EXT:
         if (resultInA)
           needpula = FALSE;
@@ -3325,6 +3346,8 @@ genMinus (iCode * ic)
 {
   char *sub;
   int size, offset = 0;
+  
+  asmop *leftOp, *rightOp;
 
   D(emitcode (";     genMinus",""));
 
@@ -3340,7 +3363,6 @@ genMinus (iCode * ic)
 
   size = getDataSize (IC_RESULT (ic));
 
-  asmop *leftOp, *rightOp;
 
   leftOp = AOP(IC_LEFT(ic));
   rightOp = AOP(IC_RIGHT(ic));
@@ -4964,11 +4986,59 @@ genGetHbit (iCode * ic)
   emitcode ("rola", "");
   hc08_dirtyReg (hc08_reg_a, FALSE);
   storeRegToFullAop (hc08_reg_a, AOP (result), FALSE);
+  hc08_freeReg (hc08_reg_a);
   
   freeAsmop (left, NULL, ic, TRUE);
   freeAsmop (result, NULL, ic, TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genSwap - generates code to swap nibbles or bytes               */
+/*-----------------------------------------------------------------*/
+static void
+genSwap (iCode * ic)
+{
+  operand *left, *result;
+
+  D(emitcode (";     genSwap",""));
+
+  left = IC_LEFT (ic);
+  result = IC_RESULT (ic);
+  aopOp (left, ic, FALSE);
+  aopOp (result, ic, FALSE);
+  
+  switch (AOP_SIZE (left))
+    {
+    case 1: /* swap nibbles in byte */
+      loadRegFromAop (hc08_reg_a, AOP (left), 0);
+      emitcode ("nsa", "");
+      hc08_dirtyReg (hc08_reg_a, FALSE);
+      storeRegToAop (hc08_reg_a, AOP (result), 0);
+      hc08_freeReg (hc08_reg_a);
+      break;
+    case 2: /* swap bytes in a word */
+      if (operandsEqu (left, result))
+        {
+          loadRegFromAop (hc08_reg_a, AOP (left), 0);
+          hc08_useReg (hc08_reg_a);
+          transferAopAop (AOP (left), 1, AOP (result), 0);
+          storeRegToAop (hc08_reg_a, AOP (result), 1);
+          hc08_freeReg (hc08_reg_a);
+        }
+      else
+        {
+          transferAopAop (AOP (left), 0, AOP (result), 1);
+          transferAopAop (AOP (left), 1, AOP (result), 0);
+        }
+      break;
+    default:
+      wassertl(FALSE, "unsupported SWAP operand size");
+    }
+    
+  freeAsmop (left, NULL, ic, TRUE);
+  freeAsmop (result, NULL, ic, TRUE);
+}
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* AccRol - rotate left accumulator by known count                 */
@@ -5276,7 +5346,7 @@ XAccRsh (int shCount, bool sign)
       return;
     }
   
-  shCount &= 0x000f;           // shCount : 0..7
+  shCount &= 0x000f;           // shCount : 0..f
 
   /* if we can beat 2n cycles or bytes for some special case, do it here */
   switch (shCount)
@@ -5304,7 +5374,7 @@ XAccRsh (int shCount, bool sign)
       **   rola       1  1        bcde fgh0  0000 000a   0
       **   lslx       1  1        cdef gh00  0000 000a   b
       **   rola       1  1        cdef gh00  0000 00ab   0
-      **   clrx       1  1        0000 0000  0000 000a   0
+      **   clrx       1  1        0000 0000  0000 00ab   0
       ** total: 6 cycles, 6 bytes
       */
       loadRegFromConst (hc08_reg_x, zero);
@@ -5360,12 +5430,12 @@ XAccRsh (int shCount, bool sign)
       ;
     }
 
-  /* lslx/rola is only 2 cycles and bytes, so an unrolled loop is often  */
+  /* lsrx/rora is only 2 cycles and bytes, so an unrolled loop is often  */
   /* the fastest and shortest.                                           */
   for (i=0;i<shCount;i++)
     {
-      rmwWithReg ("lsl", hc08_reg_x);
-      rmwWithReg ("rol", hc08_reg_a);
+      rmwWithReg ("lsr", hc08_reg_x);
+      rmwWithReg ("ror", hc08_reg_a);
     }
 
 }
@@ -5414,87 +5484,6 @@ movLeft2Result (operand * left, int offl,
 }
 
 
-/*-----------------------------------------------------------------*/
-/* AccAXRsh1 - right shift 0->a:x->c by 1                         */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRsh1 (char *x)
-{
-  emitcode ("lsra", "");
-  emitcode ("ror", "%s", x);
-}
-
-
-/*-----------------------------------------------------------------*/
-/* AccAXRshS1 - signed right shift s->a:x->c by 1                         */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRshS1 (char *x)
-{
-  emitcode ("asra", "");
-  emitcode ("ror", "%s", x);
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
-/*-----------------------------------------------------------------*/
-static void
-AccAXLrl1 (char *x)
-{
-  emitcode ("rol", "%s", x);
-  emitcode ("rola", "");
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLsh1 - left shift a:x<-0 by 1                              */
-/*-----------------------------------------------------------------*/
-static void
-AccAXLsh1 (char *x)
-{
-  emitcode ("lsl", "%s", x);
-  emitcode ("rola", "");
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXLsh - left shift a:x by known count (0..7)                 */
-/*-----------------------------------------------------------------*/
-static void
-AccAXLsh (char *x, int shCount)
-{
-  int i;
-
-  for (i=0;i<shCount;i++) {
-    AccAXLsh1 (x);
-  }
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXRsh - right shift a:x known count (0..7)                   */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRsh (char *x, int shCount)
-{
-  int i;
-
-  for (i=0;i<shCount;i++) {
-    AccAXRsh1 (x);
-  }
-  
-}
-
-/*-----------------------------------------------------------------*/
-/* AccAXRshS - right shift signed a:x known count (0..7)           */
-/*-----------------------------------------------------------------*/
-static void
-AccAXRshS (char *x, int shCount)
-{
-  int i;
-
-  for (i=0;i<shCount;i++) {
-    AccAXRshS1 (x);
-  }
-}
-
 /*-----------------------------------------------------------------*/
 /* shiftL2Left2Result - shift left two bytes from left to result   */
 /*-----------------------------------------------------------------*/
@@ -5624,6 +5613,7 @@ genlshTwo (operand * result, operand * left, int shCount)
 
   D(emitcode (";     genlshTwo",""));
 
+  
   size = getDataSize (result);
 
   /* if shCount >= 8 */
@@ -5633,10 +5623,9 @@ genlshTwo (operand * result, operand * left, int shCount)
 
       if (size > 1)
        {
-         if (shCount)
-           shiftL1Left2Result (left, LSB, result, MSB16, shCount);
-         else
-           movLeft2Result (left, LSB, result, MSB16, 0);
+          loadRegFromAop (hc08_reg_a, AOP (left), 0);
+          AccLsh (shCount);
+         storeRegToAop (hc08_reg_a, AOP (result), 1);
        }
       storeConstToAop(zero, AOP (result), LSB);
     }
@@ -5644,10 +5633,9 @@ genlshTwo (operand * result, operand * left, int shCount)
   /*  1 <= shCount <= 7 */
   else
     {
-      if (size == 1)
-       shiftL1Left2Result (left, LSB, result, LSB, shCount);
-      else
-       shiftL2Left2Result (left, LSB, result, LSB, shCount);
+      loadRegFromAop (hc08_reg_xa, AOP (left), 0);
+      XAccLsh (shCount);
+      storeRegToFullAop (hc08_reg_xa, AOP (result), 0);
     }
 }
 
@@ -6342,6 +6330,7 @@ genDataPointerGet (operand * left,
   freeAsmop (result, NULL, ic, TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genNearPointerGet - emitcode for near pointer fetch             */
 /*-----------------------------------------------------------------*/
@@ -6414,9 +6403,8 @@ genNearPointerGet (operand * left,
   }
 
   hc08_freeReg (hc08_reg_hx);
-  
 }
-
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genFarPointerGet - get value from far space                     */
@@ -6521,7 +6509,7 @@ genPointerGet (iCode * ic, iCode *pi)
     }
 
   /* special case when cast remat */
-  if (p_type == GPOINTER && OP_SYMBOL(left)->remat &&
+  if (p_type == GPOINTER && IS_SYMOP(left) && OP_SYMBOL(left)->remat &&
       IS_CAST_ICODE(OP_SYMBOL(left)->rematiCode)) {
          left = IC_RIGHT(OP_SYMBOL(left)->rematiCode);
          type = operandType (left);
@@ -6663,6 +6651,7 @@ genPackBits (sym_link * etype,
       emitcode ("and", "#0x%02x", mask);
       emitcode ("ora", "1,s");
       emitcode ("sta", ",x");
+      pullReg (hc08_reg_a);
     }
 
   hc08_freeReg (hc08_reg_a);
@@ -6698,6 +6687,7 @@ genDataPointerSet (operand * right,
   freeAsmop (NULL, derefaop, ic, TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genNearPointerSet - emitcode for near pointer put                */
 /*-----------------------------------------------------------------*/
@@ -6769,7 +6759,7 @@ genNearPointerSet (operand * right,
   hc08_freeReg (hc08_reg_hx);
   
 }
-
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genFarPointerSet - set value from far space                     */
@@ -7249,6 +7239,10 @@ genDjnz (iCode * ic, iCode * ifx)
   if (operandLitValue (IC_RIGHT (ic)) != 1)
     return 0;
 
+  /* dbnz doesn't support extended mode */
+  if (isOperandInFarSpace (IC_RESULT (ic)))
+    return 0;
+
   /* if the size of this greater than one then no
      saving */
 //  if (getSize (operandType (IC_RESULT (ic))) > 1)
@@ -7305,6 +7299,85 @@ genReceive (iCode * ic)
   freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  operand *right;
+  int size, offset;
+
+  D(emitcode(";     genDummyRead",""));
+
+  right = IC_RIGHT (ic);
+
+  aopOp (right, ic, FALSE);
+
+  /* bit variables done */
+  /* general case */
+  size = AOP_SIZE (right);
+  offset = 0;
+
+  while (size--)
+    {
+      loadRegFromAop (hc08_reg_a, AOP (right), offset);
+      hc08_freeReg (hc08_reg_a);
+      offset++;
+    }
+
+  freeAsmop (right, NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genCritical - generate code for start of a critical sequence    */
+/*-----------------------------------------------------------------*/
+static void
+genCritical (iCode *ic)
+{
+  D(emitcode(";     genCritical",""));
+  
+  if (IC_RESULT (ic))
+    aopOp (IC_RESULT (ic), ic, TRUE);
+
+  emitcode ("tpa", "");
+  hc08_dirtyReg (hc08_reg_a, FALSE);
+  emitcode ("sei", "");
+
+  if (IC_RESULT (ic))
+    storeRegToAop (hc08_reg_a, AOP (IC_RESULT (ic)), 0);
+  else
+    pushReg (hc08_reg_a, FALSE);
+
+  hc08_freeReg (hc08_reg_a);
+  if (IC_RESULT (ic))
+    freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndCritical - generate code for end of a critical sequence   */
+/*-----------------------------------------------------------------*/
+static void
+genEndCritical (iCode *ic)
+{
+  D(emitcode(";     genEndCritical",""));
+  
+  if (IC_RIGHT (ic))
+    {
+      aopOp (IC_RIGHT (ic), ic, FALSE);
+      loadRegFromAop (hc08_reg_a, AOP (IC_RIGHT (ic)), 0);
+      emitcode ("tap", "");
+      hc08_freeReg (hc08_reg_a);
+      freeAsmop (IC_RIGHT (ic), NULL, ic, TRUE);
+    }
+  else
+    {
+      pullReg (hc08_reg_a);
+      emitcode ("tap", "");
+    }
+}
+
+
 /*-----------------------------------------------------------------*/
 /* genhc08Code - generate code for HC08 based controllers          */
 /*-----------------------------------------------------------------*/
@@ -7616,6 +7689,22 @@ genhc08Code (iCode * lic)
          addSet (&_G.sendSet, ic);
          break;
 
+       case DUMMY_READ_VOLATILE:
+         genDummyRead (ic);
+         break;
+
+       case CRITICAL:
+         genCritical (ic);
+         break;
+
+       case ENDCRITICAL:
+         genEndCritical (ic);
+         break;
+       
+        case SWAP:
+         genSwap (ic);
+          break;
+
        default:
          ic = ic;
        }