First implementation of bit fields.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4079 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2009-08-29 21:20:13 +00:00
parent 7c6ee79ea9
commit 6b4fe90928
5 changed files with 161 additions and 61 deletions

View File

@@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2002-2006 Ullrich von Bassewitz */
/* R<EFBFBD>merstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* (C) 2002-2009, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@@ -96,7 +96,7 @@ void Assignment (ExprDesc* Expr)
}
if (UseReg) {
PushAddr (Expr);
} else {
} else {
ED_MakeRVal (Expr);
LoadExpr (CF_NONE, Expr);
g_push (CF_PTR | CF_UNSIGNED, 0);
@@ -158,6 +158,46 @@ void Assignment (ExprDesc* Expr)
}
} else if (ED_IsBitField (Expr)) {
unsigned Mask;
unsigned Flags = TypeOf (Expr->Type);
/* Assignment to a bit field. Get the address on stack for the store. */
PushAddr (Expr);
/* Load the value from the location as an unsigned */
Expr->Flags &= ~E_BITFIELD;
LoadExpr (CF_NONE, Expr);
/* Mask unwanted bits */
Mask = (0x0001U << Expr->BitWidth) - 1U;
g_and (Flags | CF_CONST, ~(Mask << Expr->BitOffs));
/* Push it on stack */
g_push (Flags, 0);
/* Read the expression on the right side of the '=' */
hie1 (&Expr2);
/* Do type conversion if necessary */
TypeConversion (&Expr2, ltype);
/* If necessary, load the value into the primary register */
LoadExpr (CF_NONE, &Expr2);
/* Apply the mask */
g_and (Flags | CF_CONST, Mask);
/* Shift it into the right position */
g_asl (Flags | CF_CONST, Expr->BitOffs);
/* Or both values */
g_or (Flags, 0);
/* Generate a store instruction */
Store (Expr, 0);
} else {
/* Get the address on stack if needed */