+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(rlen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << rlen));
+ emitLabel (tlbl);
+ }
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
+
+finish:
+ if (offset < rsize)
+ {
+ rsize -= offset;
+ if (SPEC_USIGN (etype))
+ {
+ while (rsize--)
+ storeConstToAop (zero, AOP (result), offset++);
+ }
+ else
+ {
+ /* signed bitfield: sign extension with 0x00 or 0xff */
+ emitcode ("rola", "");
+ emitcode ("clra", "");
+ emitcode ("sbc", zero);
+
+ while (rsize--)
+ storeRegToAop (hc08_reg_a, AOP (result), offset++);
+ }
+ }
+}
+
+
+/*-----------------------------------------------------------------*/
+/* genUnpackBitsImmed - generates code for unpacking bits */
+/*-----------------------------------------------------------------*/
+static void
+genUnpackBitsImmed (operand * left,
+ operand * result,
+ iCode *ic,
+ iCode *ifx)
+{
+ int size;
+ int offset = 0; /* result byte offset */
+ int rsize; /* result size */
+ int rlen = 0; /* remaining bitfield length */
+ sym_link *etype; /* bitfield type information */
+ int blen; /* bitfield length */
+ int bstr; /* bitfield starting bit within byte */
+ asmop *derefaop;
+
+ D(emitcode ("; genUnpackBitsImmed",""));
+
+ aopOp (result, ic, TRUE);
+ size = AOP_SIZE (result);
+
+ derefaop = aopDerefAop (AOP (left));
+ freeAsmop (left, NULL, ic, TRUE);
+ derefaop->size = size;
+
+ etype = getSpec (operandType (result));
+ rsize = getSize (operandType (result));
+ blen = SPEC_BLEN (etype);
+ bstr = SPEC_BSTR (etype);
+
+ /* if the bitfield is a single bit in the direct page */
+ if (blen == 1 && derefaop->type == AOP_DIR)
+ {
+ if (!ifx && bstr)
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+
+ loadRegFromConst (hc08_reg_a, zero);
+ emitcode ("brclr", "#%d,%s,%05d$",
+ bstr, aopAdrStr (derefaop, 0, FALSE),
+ (tlbl->key + 100));
+ if (SPEC_USIGN (etype))
+ rmwWithReg ("inc", hc08_reg_a);
+ else
+ rmwWithReg ("dec", hc08_reg_a);
+ emitLabel (tlbl);
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ goto finish;
+ }
+ else if (ifx)
+ {
+ symbol *tlbl = newiTempLabel (NULL);
+ symbol *jlbl;
+ char * inst;
+
+ if (IC_TRUE (ifx))
+ {
+ jlbl = IC_TRUE (ifx);
+ inst = "brclr";
+ }
+ else
+ {
+ jlbl = IC_FALSE (ifx);
+ inst = "brset";
+ }
+ emitcode (inst, "#%d,%s,%05d$",
+ bstr, aopAdrStr (derefaop, 0, FALSE),
+ (tlbl->key + 100));
+ emitBranch ("jmp", jlbl);
+ emitLabel (tlbl);
+ ifx->generated = 1;
+ offset++;
+ goto finish;
+ }
+ }
+
+ /* If the bitfield length is less than a byte */
+ if (blen < 8)
+ {
+ loadRegFromAop (hc08_reg_a, derefaop, 0);
+ if (!ifx)
+ {
+ AccRsh (bstr, FALSE);
+ emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8 - blen));
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(blen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << blen));
+ emitLabel (tlbl);
+ }
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ }
+ else
+ {
+ emitcode ("and", "#0x%02x",
+ (((unsigned char) -1) >> (8 - blen)) << bstr);
+ hc08_dirtyReg (hc08_reg_a, FALSE);
+ }
+ offset++;
+ goto finish;
+ }
+
+ /* Bit field did not fit in a byte. Copy all
+ but the partial byte at the end. */
+ for (rlen=blen;rlen>=8;rlen-=8)
+ {
+ loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
+ if (!ifx)
+ storeRegToAop (hc08_reg_a, AOP (result), offset);
+ else
+ emitcode ("tsta", "");
+ offset++;
+ }
+
+ /* Handle the partial byte at the end */
+ if (rlen)
+ {
+ loadRegFromAop (hc08_reg_a, derefaop, size-offset-1);
+ emitcode ("and", "#0x%02x", ((unsigned char) -1) >> (8-rlen));
+ if (!SPEC_USIGN (etype))
+ {
+ /* signed bitfield */
+ symbol *tlbl = newiTempLabel (NULL);
+
+ emitcode ("bit", "#0x%02x", 1<<(rlen - 1));
+ emitcode ("beq", "%05d$", tlbl->key + 100);
+ emitcode ("ora", "#0x%02x", (unsigned char) (0xff << rlen));
+ emitLabel (tlbl);
+ }