+ aopOp (left, ic, FALSE, FALSE);
+ aopOp (result, ic, FALSE, FALSE);
+
+ size = AOP_SIZE (result);
+
+ if (isPair (AOP (left)) && size == 1 && !IS_BITVAR (retype))
+ {
+ /* Just do it */
+ if (isPtrPair (AOP (left)))
+ {
+ tsprintf (buffer, sizeof(buffer),
+ "!*pair", getPairName (AOP (left)));
+ aopPut (AOP (result), buffer, 0);
+ }
+ else
+ {
+ emit2 ("ld a,!*pair", getPairName (AOP (left)));
+ aopPut (AOP (result), "a", 0);
+ }
+ freeAsmop (left, NULL, ic);
+ goto release;
+ }
+
+ if (getPairId (AOP (left)) == PAIR_IY && !IS_BITVAR (retype))
+ {
+ /* Just do it */
+ offset = 0;
+ while (size--)
+ {
+ char at[20];
+ tsprintf (at, sizeof(at), "!*iyx", offset);
+ aopPut (AOP (result), at, offset);
+ offset++;
+ }
+
+ freeAsmop (left, NULL, ic);
+ goto release;
+ }
+
+ /* For now we always load into IY */
+ /* if this is remateriazable */
+ fetchPair (pair, AOP (left));
+
+ /* if bit then unpack */
+ if (IS_BITVAR (retype))
+ {
+ genUnpackBits (result, pair);
+ freeAsmop (left, NULL, ic);
+ goto release;
+ //wassert (0);
+ }
+ else if (getPairId (AOP (result)) == PAIR_HL)
+ {
+ wassertl (size == 2, "HL must be of size 2");
+ emit2 ("ld a,!*hl");
+ emit2 ("inc hl");
+ emit2 ("ld h,!*hl");
+ emit2 ("ld l,a");
+ spillPair (PAIR_HL);
+ }
+ else if (getPairId (AOP (left)) == PAIR_HL && !isLastUse (ic, left))
+ {
+ size = AOP_SIZE (result);
+ offset = 0;
+
+ while (size--)
+ {
+ /* PENDING: make this better */
+ if (!IS_GB && AOP_TYPE (result) == AOP_REG)
+ {
+ aopPut (AOP (result), "!*hl", offset++);
+ }
+ else
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ aopPut (AOP (result), "a", offset++);
+ }
+ if (size)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
+ /* Fixup HL back down */
+ for (size = AOP_SIZE (result)-1; size; size--)
+ {
+ emit2 ("dec %s", _pairs[pair].name);
+ }
+ }
+ else
+ {
+ size = AOP_SIZE (result);
+ offset = 0;
+
+ while (size--)
+ {
+ /* PENDING: make this better */
+ if (!IS_GB &&
+ (AOP_TYPE (result) == AOP_REG || AOP_TYPE (result) == AOP_HLREG))
+ {
+ aopPut (AOP (result), "!*hl", offset++);
+ }
+ else
+ {
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ aopPut (AOP (result), "a", offset++);
+ }
+ if (size)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
+ }
+
+ freeAsmop (left, NULL, ic);
+
+release:
+ freeAsmop (result, NULL, ic);
+}
+
+/*-----------------------------------------------------------------*/
+/* genPointerGet - generate code for pointer get */
+/*-----------------------------------------------------------------*/
+static void
+genPointerGet (iCode * ic)
+{
+ operand *left, *result;
+ sym_link *type, *etype;
+
+ left = IC_LEFT (ic);
+ result = IC_RESULT (ic);
+
+ /* depending on the type of pointer we need to
+ move it to the correct pointer register */
+ type = operandType (left);
+ etype = getSpec (type);
+
+ genGenPointerGet (left, result, ic);
+}
+
+bool
+isRegOrLit (asmop * aop)
+{
+ if (aop->type == AOP_REG || aop->type == AOP_LIT || aop->type == AOP_IMMD || aop->type == AOP_HLREG)
+ return TRUE;
+ return FALSE;
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage */
+/*-----------------------------------------------------------------*/
+static void
+genPackBits (sym_link * etype,
+ operand * right,
+ int pair,
+ iCode *ic)
+{
+ int offset = 0; /* source byte offset */
+ int rlen = 0; /* remaining bitfield length */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ int litval; /* source literal value (if AOP_LIT) */
+ unsigned char mask; /* bitmask within current byte */
+ int extraPair; /* a tempory register */
+ bool needPopExtra=0; /* need to restore original value of temp reg */
+
+ emitDebug ("; genPackBits","");
+
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ mask = ((unsigned char) (0xFF << (blen + bstr)) |
+ (unsigned char) (0xFF >> (8 - bstr)));
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with a bitfield length <8 and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval <<= bstr;
+ litval &= (~mask) & 0xff;
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ if ((mask|litval)!=0xff)
+ emit2 ("and a,!immedbyte", mask);
+ if (litval)
+ emit2 ("or a,!immedbyte", litval);
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ return;
+ }
+ else
+ {
+ /* Case with a bitfield length <8 and arbitrary source
+ */
+ _moveA (aopGet (AOP (right), 0, FALSE));
+ /* shift and mask source value */
+ AccLsh (bstr);
+ emit2 ("and a,!immedbyte", (~mask) & 0xff);
+
+ extraPair = getFreePairId(ic);
+ if (extraPair == PAIR_INVALID)
+ {
+ extraPair = PAIR_BC;
+ if (getPairId (AOP (right)) != PAIR_BC
+ || !isLastUse (ic, right))
+ {
+ _push (extraPair);
+ needPopExtra = 1;
+ }
+ }
+ emit2 ("ld %s,a", _pairs[extraPair].l);
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+
+ emit2 ("and a,!immedbyte", mask);
+ emit2 ("or a,%s", _pairs[extraPair].l);
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ if (needPopExtra)
+ _pop (extraPair);
+ return;
+ }
+ }
+
+ /* Bit length is greater than 7 bits. In this case, copy */
+ /* all except the partial byte at the end */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ emit2 ("ld a,%s", aopGet (AOP (right), offset++, FALSE) );
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ if (rlen>8)
+ {
+ emit2 ("inc %s", _pairs[pair].name);
+ _G.pairs[pair].offset++;
+ }
+ }
+
+ /* If there was a partial byte at the end */
+ if (rlen)
+ {
+ mask = (((unsigned char) -1 << rlen) & 0xff);
+
+ if (AOP_TYPE (right) == AOP_LIT)
+ {
+ /* Case with partial byte and literal source
+ */
+ litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+ litval >>= (blen-rlen);
+ litval &= (~mask) & 0xff;
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+ if ((mask|litval)!=0xff)
+ emit2 ("and a,!immedbyte", mask);
+ if (litval)
+ emit2 ("or a,!immedbyte", litval);
+ }
+ else
+ {
+ /* Case with partial byte and arbitrary source
+ */
+ _moveA (aopGet (AOP (right), offset++, FALSE));
+ emit2 ("and a,!immedbyte", (~mask) & 0xff);
+
+ extraPair = getFreePairId(ic);
+ if (extraPair == PAIR_INVALID)
+ {
+ extraPair = getPairId (AOP (right));
+ if (!isLastUse (ic, right) || (extraPair == PAIR_INVALID))
+ extraPair = PAIR_BC;
+
+ if (getPairId (AOP (right)) != PAIR_BC
+ || !isLastUse (ic, right))
+ {
+ _push (extraPair);
+ needPopExtra = 1;
+ }
+ }
+ emit2 ("ld %s,a", _pairs[extraPair].l);
+ emit2 ("ld a,!*pair", _pairs[pair].name);
+
+ emit2 ("and a,!immedbyte", mask);
+ emit2 ("or a,%s", _pairs[extraPair].l);
+ if (needPopExtra)
+ _pop (extraPair);
+
+ }
+ emit2 ("ld !*pair,a", _pairs[pair].name);
+ }
+}