+2003-12-08 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ * src/SDCCopt.c (killDeadCode): change iCode type to DUMMY_READ_VOLATILE
+ instead of deleting the iCode when an operand is volatile
+ * src/z80/gen.c (genDummyRead),
+ * src/mcs51/gen.c (genDummyRead),
+ * src/ds390/gen.c (genDummyRead),
+ * src/hc08/gen.c (genDummyRead): handle operands in IC_LEFT and/or IC_RIGHT,
+ not just IC_RIGHT
+ * src/SDCCicode.c (geniCodeCall): fixed bug #851607
+ * src/SDCC.y: fixed bug #850420
+
+2003-12-05 Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+ Applied z80 i/o port patch from Peter Townson and fixed some operators
+ to better handle operands in A register.
+ * device/include/z180.h
+ * src/SDCC.y
+ * src/SDCCglue.c
+ * src/z80/gen.c
+ * src/z80/gen.h
+ * src/z80/main.c
+ * src/z80/peeph-z80.def
+ * src/z80/peeph.def
+ * src/z80/z80.h
+
2003-12-03 Erik Petrich <epetrich@ivorytower.norman.ok.us>
* src/SDCCsymt.c (addSymChain, compareTypeExact): fixed bug #838241 again
%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
%type <yyint> Interrupt_storage
-%type <sym> identifier declarator declarator2 enumerator_list enumerator
-%type <sym> struct_declarator
+%type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
+%type <sym> struct_declarator function_declarator function_declarator2
%type <sym> struct_declarator_list struct_declaration struct_declaration_list
%type <sym> declaration init_declarator_list init_declarator
%type <sym> declaration_list identifier_list parameter_identifier_list
;
function_definition
- : declarator function_body { /* function type not specified */
+ : function_declarator function_body { /* function type not specified */
/* assume it to be 'int' */
addDecl($1,0,newIntLink());
$$ = createFunction($1,$2);
}
- | declaration_specifiers declarator function_body
+ | declaration_specifiers function_declarator function_body
{
pointerTypes($2->type,copyLinkChain($1));
addDecl($2,0,$1);
| declaration_list compound_statement
{
werror(E_OLD_STYLE,($1 ? $1->name: "")) ;
+ fprintf(stderr, "case 1\n");
exit(1);
}
;
;
declarator
- : declarator2_function_attributes { $$ = $1; }
- | pointer declarator2_function_attributes
+ : declarator3 { $$ = $1 ; }
+ | pointer declarator3
{
addDecl ($2,0,reverseLink($1));
$$ = $2 ;
}
;
-declarator2_function_attributes
- : declarator2 { $$ = $1 ; }
- | declarator2 function_attribute {
- if ((! $1) || (! IS_FUNC($1->etype)))
+declarator3
+ : declarator2_function_attributes { $$ = $1 ; }
+ | declarator2 { $$ = $1 ; }
+ ;
+
+function_declarator
+ : declarator2_function_attributes { $$ = $1; }
+ | pointer declarator2_function_attributes
{
- // function_attribute is only allowed if declarator2 was
- // an actual function
- werror(E_FUNC_ATTR);
- $$=$1;
+ addDecl ($2,0,reverseLink($1));
+ $$ = $2 ;
}
- else
- {
+ ;
+
+declarator2_function_attributes
+ : function_declarator2 { $$ = $1 ; }
+ | function_declarator2 function_attribute {
// copy the functionAttributes (not the args and hasVargs !!)
sym_link *funcType=$1->etype;
struct value *args=FUNC_ARGS(funcType);
sizeof($2->funcAttrs));
addDecl ($1,0,$2);
- }
}
;
declarator2
: identifier
| '(' declarator ')' { $$ = $2; }
- | declarator2 '[' ']'
+ | declarator3 '[' ']'
{
sym_link *p;
DCL_ELEM(p) = 0 ;
addDecl($1,0,p);
}
- | declarator2 '[' constant_expr ']'
+ | declarator3 '[' constant_expr ']'
{
sym_link *p ;
value *tval;
}
addDecl($1,0,p);
}
- | declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
+ ;
+
+function_declarator2
+ : declarator2 '(' ')' { addDecl ($1,FUNCTION,NULL) ; }
| declarator2 '(' { NestLevel++ ; currBlockno++; } parameter_type_list ')'
{
| declarator2 '(' parameter_identifier_list ')'
{
werror(E_OLD_STYLE,$1->name) ;
-
+ fprintf(stderr, "case 2\n");
/* assume it returns an int */
$1->type = $1->etype = newIntLink();
$$ = $1 ;
}
;
-
+
pointer
: unqualified_pointer { $$ = $1 ;}
| unqualified_pointer type_specifier_list
if (!IS_FUNC(OP_SYMBOL(left)->type) &&
!IS_CODEPTR(OP_SYMBOL(left)->type)) {
werror (E_FUNCTION_EXPECTED);
- return NULL;
+ return operandFromValue(valueFromLit(0));
}
/* take care of parameters with side-effecting
ic->op == ENDCRITICAL)
continue;
+ /* Since both IFX & JUMPTABLE (in SKIP_IC) have been tested for */
+ /* it is now safe to assume IC_LEFT, IC_RIGHT, & IC_RESULT are */
+ /* valid. */
+
/* if the result is volatile then continue */
if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
continue;
/* kill this one if required */
if (kill)
{
+ bool volLeft = IS_SYMOP (IC_LEFT (ic))
+ && isOperandVolatile (IC_LEFT (ic), FALSE);
+ bool volRight = IS_SYMOP (IC_RIGHT (ic))
+ && isOperandVolatile (IC_RIGHT (ic), FALSE);
+
change = 1;
gchange++;
- /* eliminate this */
- remiCodeFromeBBlock (ebbs[i], ic);
-
+
/* now delete from defUseSet */
deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
bitVectUnSetBit (ebbs[i]->outDefs, ic->key);
/* and defset of the block */
bitVectUnSetBit (ebbs[i]->defSet, ic->key);
- /* for the left & right remove the usage */
- if (IS_SYMOP (IC_LEFT (ic)))
- bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+ /* delete the result */
+ IC_RESULT (ic) = NULL;
+
+ if (volLeft || volRight)
+ {
+ /* something is volatile, so keep the iCode */
+ /* and change the operator instead */
+ ic->op = DUMMY_READ_VOLATILE;
+
+ /* keep only the volatile operands */
+ if (!volLeft)
+ IC_LEFT (ic) = NULL;
+ if (!volRight)
+ IC_RIGHT (ic) = NULL;
+ }
+ else
+ {
+ /* nothing is volatile, eliminate the iCode */
+ remiCodeFromeBBlock (ebbs[i], ic);
- if (IS_SYMOP (IC_RIGHT (ic)))
- bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+ /* for the left & right remove the usage */
+ if (IS_SYMOP (IC_LEFT (ic)))
+ bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
+
+ if (IS_SYMOP (IC_RIGHT (ic)))
+ bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
+ }
}
} /* end of all instructions */
static void
genDummyRead (iCode * ic)
{
- operand *right;
+ operand *op;
int size, offset;
D(emitcode("; genDummyRead",""));
- right = IC_RIGHT (ic);
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE, FALSE);
- aopOp (right, ic, FALSE, FALSE);
+ /* if the result is a bit */
+ if (AOP_TYPE (op) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+ else
+ {
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
+ while (size--)
+ {
+ MOVA (aopGet (AOP (op), offset, FALSE, FALSE, FALSE));
+ offset++;
+ }
+ }
- /* if the result is a bit */
- if (AOP_TYPE (right) == AOP_CRY)
- {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- goto release;
+ freeAsmop (op, NULL, ic, TRUE);
}
- /* bit variables done */
- /* general case */
- size = AOP_SIZE (right);
- offset = 0;
- while (size--)
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
- offset++;
- }
+ aopOp (op, ic, FALSE, FALSE);
-release:
- freeAsmop (right, NULL, ic, TRUE);
+ /* if the result is a bit */
+ if (AOP_TYPE (op) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+ else
+ {
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
+ while (size--)
+ {
+ MOVA (aopGet (AOP (op), offset, FALSE, FALSE, FALSE));
+ offset++;
+ }
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
+ }
+
}
/*-----------------------------------------------------------------*/
static void
genDummyRead (iCode * ic)
{
- operand *right;
+ operand *op;
int size, offset;
D(emitcode("; genDummyRead",""));
- right = IC_RIGHT (ic);
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
- aopOp (right, ic, FALSE);
+ aopOp (op, ic, FALSE);
- /* bit variables done */
- /* general case */
- size = AOP_SIZE (right);
- offset = 0;
+ size = AOP_SIZE (op);
+ offset = 0;
- while (size--)
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (op), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
+ }
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
{
- loadRegFromAop (hc08_reg_a, AOP (right), offset);
- hc08_freeReg (hc08_reg_a);
- offset++;
- }
- freeAsmop (right, NULL, ic, TRUE);
+ aopOp (op, ic, FALSE);
+
+ size = AOP_SIZE (op);
+ offset = 0;
+
+ while (size--)
+ {
+ loadRegFromAop (hc08_reg_a, AOP (op), offset);
+ hc08_freeReg (hc08_reg_a);
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
+ }
}
/*-----------------------------------------------------------------*/
static void
genDummyRead (iCode * ic)
{
- operand *right;
+ operand *op;
int size, offset;
D(emitcode("; genDummyRead",""));
- right = IC_RIGHT (ic);
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE);
- aopOp (right, ic, FALSE);
+ /* if the result is a bit */
+ if (AOP_TYPE (op) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+ else
+ {
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
+ while (size--)
+ {
+ MOVA (aopGet (AOP (op), offset, FALSE, FALSE));
+ offset++;
+ }
+ }
- /* if the result is a bit */
- if (AOP_TYPE (right) == AOP_CRY)
- {
- emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
- goto release;
+ freeAsmop (op, NULL, ic, TRUE);
}
- /* bit variables done */
- /* general case */
- size = AOP_SIZE (right);
- offset = 0;
- while (size--)
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
{
- MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
- offset++;
- }
+ aopOp (op, ic, FALSE);
-release:
- freeAsmop (right, NULL, ic, TRUE);
+ /* if the result is a bit */
+ if (AOP_TYPE (op) == AOP_CRY)
+ emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+ else
+ {
+ /* bit variables done */
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
+ while (size--)
+ {
+ MOVA (aopGet (AOP (op), offset, FALSE, FALSE));
+ offset++;
+ }
+ }
+
+ freeAsmop (op, NULL, ic, TRUE);
+ }
}
/*-----------------------------------------------------------------*/
static void
genDummyRead (iCode * ic)
{
- operand *right;
+ operand *op;
int size, offset;
- right = IC_RIGHT (ic);
- aopOp (right, ic, FALSE, FALSE);
+ op = IC_RIGHT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE, FALSE);
- /* general case */
- size = AOP_SIZE (right);
- offset = 0;
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
- while (size--)
- {
- _moveA (aopGet (AOP (right), offset, FALSE));
- offset++;
+ while (size--)
+ {
+ _moveA (aopGet (AOP (op), offset, FALSE));
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic);
}
+
+ op = IC_LEFT (ic);
+ if (op && IS_SYMOP (op))
+ {
+ aopOp (op, ic, FALSE, FALSE);
+
+ /* general case */
+ size = AOP_SIZE (op);
+ offset = 0;
- freeAsmop (right, NULL, ic);
+ while (size--)
+ {
+ _moveA (aopGet (AOP (op), offset, FALSE));
+ offset++;
+ }
+
+ freeAsmop (op, NULL, ic);
+ }
}
enum