%token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token <yyint> XOR_ASSIGN OR_ASSIGN
-%token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR AT SBIT
-%token REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL NONBANKED BANKED
-%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID BIT
+%token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR SFR16 SFR32
+%token AT SBIT REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL
+%token NONBANKED BANKED SHADOWREGS WPARAM
+%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE FIXED16X16 CONST VOLATILE VOID BIT
%token STRUCT UNION ENUM ELIPSIS RANGE FAR
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%token NAKED JAVANATIVE OVERLAY
%token <yyinline> INLINEASM
-%token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT
+%token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT GETABIT GETBYTE GETWORD
%token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE
%token RRC RLC
%token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT
-%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP
+%token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE RESTRICT
%type <yyint> Interrupt_storage
%type <sym> identifier declarator declarator2 declarator3 enumerator_list enumerator
%%
file
+ : /* empty */
+ { if (!options.lessPedantic)
+ werror(W_EMPTY_SOURCE_FILE);
+ }
+ | program
+ ;
+
+program
: external_definition
- | file external_definition
+ | program external_definition
;
external_definition
SPEC_EXTR($1->etype) = 1;
}
}
- addSymChain ($1);
+ addSymChain (&$1);
allocVariables ($1) ;
cleanUpLevel (SymbolTab,1);
}
;
function_attributes
- : USING CONSTANT {
+ : USING constant_expr {
$$ = newLink(SPECIFIER) ;
- FUNC_REGBANK($$) = (int) floatFromVal($2);
+ FUNC_REGBANK($$) = (int) floatFromVal(constExprValue($2,TRUE));
}
| REENTRANT { $$ = newLink (SPECIFIER);
FUNC_ISREENT($$)=1;
werror(W_BANKED_WITH_NONBANKED);
}
}
+ | SHADOWREGS {$$ = newLink (SPECIFIER);
+ FUNC_ISSHADOWREGS($$) = 1;
+ }
+ | WPARAM {$$ = newLink (SPECIFIER);
+ FUNC_ISWPARAM($$) = 1;
+ }
| BANKED {$$ = newLink (SPECIFIER);
FUNC_BANKED($$) = 1;
if (FUNC_NONBANKED($$)) {
{
$$ = newNode (CALL,$1,$3) ; $$->left->funcName = 1;
}
- | postfix_expr '.' identifier
+ | postfix_expr '.' { ignoreTypedefType = 1; } identifier
{
- $3 = newSymbol($3->name,NestLevel);
- $3->implicit = 1;
- $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($3)));
-/* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($3))) ; */
+ ignoreTypedefType = 0;
+ $4 = newSymbol($4->name,NestLevel);
+ $4->implicit = 1;
+ $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4)));
+/* $$ = newNode('.',$1,newAst(EX_VALUE,symbolVal($4))) ; */
}
- | postfix_expr PTR_OP identifier
+ | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier
{
- $3 = newSymbol($3->name,NestLevel);
- $3->implicit = 1;
- $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($3)));
+ ignoreTypedefType = 0;
+ $4 = newSymbol($4->name,NestLevel);
+ $4->implicit = 1;
+ $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4)));
}
| postfix_expr INC_OP
{ $$ = newNode(INC_OP,$1,NULL);}
relational_expr
: shift_expr
- | relational_expr '<' shift_expr {
- $$ = (port->lt_nge ?
- newNode('!',newNode(GE_OP,$1,$3),NULL) :
- newNode('<', $1,$3));
- }
- | relational_expr '>' shift_expr {
- $$ = (port->gt_nle ?
- newNode('!',newNode(LE_OP,$1,$3),NULL) :
- newNode('>',$1,$3));
- }
- | relational_expr LE_OP shift_expr {
- $$ = (port->le_ngt ?
- newNode('!', newNode('>', $1 , $3 ), NULL) :
- newNode(LE_OP,$1,$3));
- }
- | relational_expr GE_OP shift_expr {
- $$ = (port->ge_nlt ?
- newNode('!', newNode('<', $1 , $3 ), NULL) :
- newNode(GE_OP,$1,$3));
- }
+ | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);}
+ | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);}
+ | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);}
+ | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);}
;
equality_expr
: relational_expr
- | equality_expr EQ_OP relational_expr {
- $$ = (port->eq_nne ?
- newNode('!',newNode(NE_OP,$1,$3),NULL) :
- newNode(EQ_OP,$1,$3));
- }
- | equality_expr NE_OP relational_expr {
- $$ = (port->ne_neq ?
- newNode('!', newNode(EQ_OP,$1,$3), NULL) :
- newNode(NE_OP,$1,$3));
- }
+ | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);}
+ | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);}
;
and_expr
assignment_expr
: conditional_expr
- | unary_expr assignment_operator assignment_expr
+ | cast_expr assignment_operator assignment_expr
{
switch ($2) {
$$ = newNode($2,$1,$3);
break;
case MUL_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('*',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '*', $3);
break;
case DIV_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('/',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '/', $3);
break;
case MOD_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('%',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '%', $3);
break;
case ADD_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('+',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '+', $3);
break;
case SUB_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('-',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '-', $3);
break;
case LEFT_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode(LEFT_OP,removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, LEFT_OP, $3);
break;
case RIGHT_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode(RIGHT_OP,removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, RIGHT_OP, $3);
break;
case AND_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('&',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '&', $3);
break;
case XOR_ASSIGN:
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('^',removePreIncDecOps(copyAst($1)),$3));
+ $$ = createRMW($1, '^', $3);
break;
case OR_ASSIGN:
- /* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
- $$ = newNode('=',removePostIncDecOps(copyAst($1)),
- newNode('|',removePreIncDecOps(copyAst($1)),$3));
+/* $$ = newNode('=',$1,newNode('|',removeIncDecOps(copyAst($1)),$3)); */
+/* $$ = newNode('=',removePostIncDecOps(copyAst($1)),
+ newNode('|',removePreIncDecOps(copyAst($1)),$3)); */
+ $$ = createRMW($1, '|', $3);
break;
default :
$$ = NULL;
Interrupt_storage
: INTERRUPT { $$ = INTNO_UNSPEC ; }
- | INTERRUPT CONSTANT
- { int intno = (int) floatFromVal($2);
+ | INTERRUPT constant_expr
+ { int intno = (int) floatFromVal(constExprValue($2,TRUE));
if ((intno >= 0) && (intno <= INTNO_MAX))
$$ = intno;
else
/* add this to the storage class specifier */
SPEC_ABSA($1) = 1; /* set the absolute addr flag */
/* now get the abs addr from value */
- SPEC_ADDR($1) = (int) floatFromVal(constExprValue($3,TRUE)) ;
+ SPEC_ADDR($1) = (unsigned) floatFromVal(constExprValue($3,TRUE)) ;
}
;
type_specifier2
- : CHAR {
- $$=newLink(SPECIFIER);
- SPEC_NOUN($$) = V_CHAR ;
- ignoreTypedefType = 1;
- }
- | SHORT {
- $$=newLink(SPECIFIER);
- $$->select.s._short = 1 ;
- ignoreTypedefType = 1;
- }
- | INT {
- $$=newLink(SPECIFIER);
- SPEC_NOUN($$) = V_INT ;
- ignoreTypedefType = 1;
- }
- | LONG {
- $$=newLink(SPECIFIER);
- SPEC_LONG($$) = 1 ;
- ignoreTypedefType = 1;
- }
- | SIGNED {
- $$=newLink(SPECIFIER);
- $$->select.s._signed = 1;
- ignoreTypedefType = 1;
- }
+ : CHAR {
+ $$=newLink(SPECIFIER);
+ SPEC_NOUN($$) = V_CHAR ;
+ ignoreTypedefType = 1;
+ }
+ | SHORT {
+ $$=newLink(SPECIFIER);
+ SPEC_SHORT($$) = 1 ;
+ ignoreTypedefType = 1;
+ }
+ | INT {
+ $$=newLink(SPECIFIER);
+ SPEC_NOUN($$) = V_INT ;
+ ignoreTypedefType = 1;
+ }
+ | LONG {
+ $$=newLink(SPECIFIER);
+ SPEC_LONG($$) = 1 ;
+ ignoreTypedefType = 1;
+ }
+ | SIGNED {
+ $$=newLink(SPECIFIER);
+ $$->select.s.b_signed = 1;
+ ignoreTypedefType = 1;
+ }
| UNSIGNED {
- $$=newLink(SPECIFIER);
- SPEC_USIGN($$) = 1 ;
- ignoreTypedefType = 1;
- }
- | VOID {
- $$=newLink(SPECIFIER);
- SPEC_NOUN($$) = V_VOID ;
- ignoreTypedefType = 1;
- }
- | CONST {
- $$=newLink(SPECIFIER);
- SPEC_CONST($$) = 1;
- }
+ $$=newLink(SPECIFIER);
+ SPEC_USIGN($$) = 1 ;
+ ignoreTypedefType = 1;
+ }
+ | VOID {
+ $$=newLink(SPECIFIER);
+ SPEC_NOUN($$) = V_VOID ;
+ ignoreTypedefType = 1;
+ }
+ | CONST {
+ $$=newLink(SPECIFIER);
+ SPEC_CONST($$) = 1;
+ }
| VOLATILE {
- $$=newLink(SPECIFIER);
- SPEC_VOLATILE($$) = 1 ;
- }
- | FLOAT {
- $$=newLink(SPECIFIER);
- SPEC_NOUN($$) = V_FLOAT;
- ignoreTypedefType = 1;
- }
+ $$=newLink(SPECIFIER);
+ SPEC_VOLATILE($$) = 1 ;
+ }
+ | FLOAT {
+ $$=newLink(SPECIFIER);
+ SPEC_NOUN($$) = V_FLOAT;
+ ignoreTypedefType = 1;
+ }
+ | FIXED16X16 {
+ $$=newLink(SPECIFIER);
+ SPEC_NOUN($$) = V_FIXED16X16;
+ ignoreTypedefType = 1;
+ }
| XDATA {
$$ = newLink (SPECIFIER);
SPEC_SCLS($$) = S_XDATA ;
$$ = newLink (SPECIFIER) ;
SPEC_SCLS($$) = S_CODE ;
}
- | EEPROM {
+ | EEPROM {
$$ = newLink (SPECIFIER) ;
SPEC_SCLS($$) = S_EEPROM ;
}
$$ = newLink (SPECIFIER);
SPEC_SCLS($$) = S_PDATA ;
}
- | BIT {
- $$=newLink(SPECIFIER);
- SPEC_NOUN($$) = V_BIT ;
- SPEC_SCLS($$) = S_BIT ;
- SPEC_BLEN($$) = 1;
- SPEC_BSTR($$) = 0;
- ignoreTypedefType = 1;
- }
+ | BIT {
+ $$=newLink(SPECIFIER);
+ SPEC_NOUN($$) = V_BIT ;
+ SPEC_SCLS($$) = S_BIT ;
+ SPEC_BLEN($$) = 1;
+ SPEC_BSTR($$) = 0;
+ ignoreTypedefType = 1;
+ }
| struct_or_union_specifier {
uselessDecl = FALSE;
$$ = $1 ;
- ignoreTypedefType = 1;
+ ignoreTypedefType = 1;
}
| enum_specifier {
cenum = NULL ;
sym_link *p ;
sym = findSym(TypedefTab,NULL,$1) ;
$$ = p = copyLinkChain(sym->type);
- SPEC_TYPEDEF(getSpec(p)) = 0;
+ SPEC_TYPEDEF(getSpec(p)) = 0;
ignoreTypedefType = 1;
}
| sfr_reg_bit
$$ = newLink(SPECIFIER) ;
SPEC_NOUN($$) = V_SBIT;
SPEC_SCLS($$) = S_SBIT;
- SPEC_BLEN($$) = 1;
- SPEC_BSTR($$) = 0;
- ignoreTypedefType = 1;
+ SPEC_BLEN($$) = 1;
+ SPEC_BSTR($$) = 0;
+ ignoreTypedefType = 1;
}
| sfr_attributes
;
SPEC_NOUN($$) = V_CHAR;
SPEC_SCLS($$) = S_SFR ;
SPEC_USIGN($$) = 1 ;
- ignoreTypedefType = 1;
+ ignoreTypedefType = 1;
}
| SFR BANKED {
$$ = newLink(SPECIFIER) ;
SPEC_NOUN($$) = V_CHAR;
SPEC_SCLS($$) = S_SFR ;
SPEC_USIGN($$) = 1 ;
- ignoreTypedefType = 1;
+ ignoreTypedefType = 1;
+ }
+ ;
+
+sfr_attributes
+ : SFR16 {
+ $$ = newLink(SPECIFIER) ;
+ FUNC_REGBANK($$) = 0;
+ SPEC_NOUN($$) = V_INT;
+ SPEC_SCLS($$) = S_SFR;
+ SPEC_USIGN($$) = 1 ;
+ ignoreTypedefType = 1;
+ }
+ ;
+
+sfr_attributes
+ : SFR32 {
+ $$ = newLink(SPECIFIER) ;
+ FUNC_REGBANK($$) = 0;
+ SPEC_NOUN($$) = V_INT;
+ SPEC_SCLS($$) = S_SFR;
+ SPEC_LONG($$) = 1;
+ SPEC_USIGN($$) = 1;
+ ignoreTypedefType = 1;
}
;
struct_declarator
: declarator
| ':' constant_expr {
- int bitsize;
+ unsigned int bitsize;
$$ = newSymbol (genSymName(NestLevel),NestLevel) ;
- bitsize= (int) floatFromVal(constExprValue($2,TRUE));
+ bitsize= (unsigned int) floatFromVal(constExprValue($2,TRUE));
if (bitsize > (port->s.int_size * 8)) {
bitsize = port->s.int_size * 8;
werror(E_BITFLD_SIZE, bitsize);
}
| declarator ':' constant_expr
{
- int bitsize;
- bitsize= (int) floatFromVal(constExprValue($3,TRUE));
+ unsigned int bitsize;
+ bitsize= (unsigned int) floatFromVal(constExprValue($3,TRUE));
if (bitsize > (port->s.int_size * 8)) {
bitsize = port->s.int_size * 8;
werror(E_BITFLD_SIZE, bitsize);
SPEC_ENUM($1->etype) = 1;
$$ = $1 ;
// do this now, so we can use it for the next enums in the list
- addSymChain($1);
+ addSymChain(&$1);
}
;
pointerTypes($2->type,$1);
addDecl ($2,0,$1);
for (loop=$2;loop;loop->_isparm=1,loop=loop->next);
- addSymChain ($2);
+ addSymChain (&$2);
$$ = symbolVal($2);
ignoreTypedefType = 0;
}
FUNC_HASVARARGS(p) = IS_VARG($4);
FUNC_ARGS(p) = reverseVal($4);
-
+
/* nest level was incremented to take care of the parms */
NestLevel-- ;
currBlockno--;
- p->next = $1;
- $$ = p;
+ if (!$1) {
+ /* ((void (code *) (void)) 0) () */
+ $1=newLink(DECLARATOR);
+ DCL_TYPE($1)=CPOINTER;
+ $$ = $1;
+ }
+ $1->next=p;
// remove the symbol args (if any)
cleanUpLevel(SymbolTab,NestLevel+1);
labeled_statement
// : identifier ':' statement { $$ = createLabel($1,$3); }
- : identifier ':' { $$ = createLabel($1,NULL); }
+ : identifier ':' { $$ = createLabel($1,NULL);
+ $1->isitmp = 0; }
| CASE constant_expr ':'
{
if (STACK_EMPTY(swStk))
: start_block end_block { $$ = createBlock(NULL,NULL); }
| start_block statement_list end_block { $$ = createBlock(NULL,$2) ; }
| start_block
- declaration_list { addSymChain($2); }
+ declaration_list { addSymChain(&$2); }
end_block { $$ = createBlock($2,NULL) ; }
| start_block
- declaration_list { addSymChain ($2); }
+ declaration_list { addSymChain (&$2); }
statement_list
end_block {$$ = createBlock($2,$4) ; }
| error ';' { $$ = NULL ; }