+
+ /* port from pic14 to cope with generic pointers */
+ if (IS_PTR(restype))
+ {
+ operand *result = IC_RESULT(ic);
+ //operand *left = IC_LEFT(ic);
+ operand *right = IC_RIGHT(ic);
+ int tag = 0xff;
+
+ /* copy common part */
+ int max, size = AOP_SIZE(result);
+ if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
+ DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
+ /* warn if we discard generic opinter tag */
+ if (!IS_GENPTR(restype) && IS_GENPTR(rtype) && (AOP_SIZE(result) < AOP_SIZE(right)))
+ {
+ //fprintf (stderr, "%s:%u: discarding generic pointer type tag\n", __FUNCTION__, __LINE__);
+ } // if
+
+ max = size;
+ while (size--)
+ {
+ pic16_mov2w (AOP(right), size);
+ pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
+ } // while
+ pic16_addSign(result, max, 0);
+
+ /* upcast into generic pointer type? */
+ if (IS_GENPTR(restype) && !IS_GENPTR(rtype))
+ {
+ //fprintf (stderr, "%s:%u: must determine pointer type (IS_PTR: %d, DCL_TYPE: %d)\n", __FUNCTION__, __LINE__, IS_PTR(rtype), IS_PTR(rtype) ? DCL_TYPE(rtype) : 0);
+ if (IS_PTR(rtype))
+ {
+ switch (DCL_TYPE(rtype))
+ {
+ case POINTER: /* __data */
+ case FPOINTER: /* __data */
+ assert (AOP_SIZE(right) == 2);
+ tag = 0x80;
+ break;
+
+ case CPOINTER: /* __code */
+ assert (AOP_SIZE(right) == 2);
+ tag = 0x00;
+ break;
+
+ case GPOINTER: /* unknown destination, __data or __code */
+ assert (AOP_SIZE(right) == 3);
+ /* tag taken from right operand */
+ break;
+
+ default:
+ assert (!"unhandled pointer type");
+ } // switch
+ } else {
+ /* convert other values into pointers to __data space */
+ fprintf (stderr, "%s:%u(%s): creating generic pointer from non-pointer type -- assuming __data space\n", __FILE__, __LINE__, __FUNCTION__);
+ tag = 0x80;
+ }
+
+ assert (AOP_SIZE(result) == 3);
+ if (tag == 0) {
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 2));
+ } else {
+ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(tag));
+ pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), 2));
+ }
+ } // if
+ goto release;
+ }