/* rl78-parse.y Renesas RL78 parser
- Copyright 2011
- Free Software Foundation, Inc.
+ Copyright (C) 2011-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
static int rl78_last_token = 0;
static char * rl78_init_start;
static char * rl78_last_exp_start = 0;
+static int rl78_bit_insn = 0;
#define YYDEBUG 1
#define YYERROR_VERBOSE 1
#define NOT_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFF1F")
#define SA(e) if (!expr_is_saddr (e)) NOT_SADDR;
+#define SET_SA(e) e.X_md = BFD_RELOC_RL78_SADDR
+
#define NOT_SFR rl78_error ("Expression not 0xFFF00 to 0xFFFFF")
#define SFR(e) if (!expr_is_sfr (e)) NOT_SFR;
#define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned");
+#define ISA_G10(s) if (!rl78_isa_g10()) rl78_error (s " is only supported on the G10")
+#define ISA_G13(s) if (!rl78_isa_g13()) rl78_error (s " is only supported on the G13")
+#define ISA_G14(s) if (!rl78_isa_g14()) rl78_error (s " is only supported on the G14")
+
static void check_expr_is_bit_index (expressionS);
#define Bit(e) check_expr_is_bit_index (e);
%token HALT
%token INC INCW
%token MACH MACHU MOV MOV1 MOVS MOVW MULH MULHU MULU
-%token NOP
+%token NOP NOT1
%token ONEB ONEW OR OR1
%token POP PUSH
%token RET RETI RETB ROL ROLC ROLWC ROR RORC
{ B1 (0x0c|$1); O1 ($5); }
| addsub EXPR {SA($2)} ',' '#' EXPR
- { B1 (0x0a|$1); O1 ($2); O1 ($6); }
+ { B1 (0x0a|$1); SET_SA ($2); O1 ($2); O1 ($6); }
| addsub A ',' A
{ B2 (0x61, 0x01|$1); }
{ B2 (0x61, 0x00|$1); F ($2, 13, 3); }
| addsub A ',' EXPR {SA($4)}
- { B1 (0x0b|$1); O1 ($4); }
+ { B1 (0x0b|$1); SET_SA ($4); O1 ($4); }
| addsub A ',' opt_es '!' EXPR
- { B1 (0x0f|$1); O2 ($6); }
+ { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); }
| addsub A ',' opt_es '[' HL ']'
{ B1 (0x0d|$1); }
| addsub A ',' opt_es '[' HL '+' C ']'
{ B2 (0x61, 0x82|$1); }
-
-
| addsub opt_es '!' EXPR ',' '#' EXPR
{ if ($1 != 0x40)
{ rl78_error ("Only CMP takes these operands"); }
else
- { B1 (0x00|$1); O2 ($4); O1 ($7); }
+ { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); }
}
/* ---------------------------------------------------------------------- */
{ B1 (0x01|$1); F ($4, 5, 2); }
| addsubw AX ',' EXPR {SA($4)}
- { B1 (0x06|$1); O1 ($4); }
+ { B1 (0x06|$1); SET_SA ($4); O1 ($4); }
| addsubw AX ',' opt_es '!' EXPR
- { B1 (0x02|$1); O2 ($6); }
+ { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); }
| addsubw AX ',' opt_es '[' HL '+' EXPR ']'
{ B2 (0x61, 0x09|$1); O1 ($8); }
| addsubw AX ',' opt_es '[' HL ']'
- { B4 (0x61, 0x09|$1, 0, 0); }
+ { B3 (0x61, 0x09|$1, 0); }
| addsubw SP ',' '#' EXPR
{ B1 ($1 ? 0x20 : 0x10); O1 ($5);
{ if (expr_is_sfr ($4))
{ B2 (0x71, 0x08|$1); FE ($6, 9, 3); O1 ($4); }
else if (expr_is_saddr ($4))
- { B2 (0x71, 0x00|$1); FE ($6, 9, 3); O1 ($4); }
+ { B2 (0x71, 0x00|$1); FE ($6, 9, 3); SET_SA ($4); O1 ($4); }
else
NOT_SFR_OR_SADDR;
}
/* ---------------------------------------------------------------------- */
| BC '$' EXPR
- { B1 (0xdc); PC1 ($3); }
+ { B1 (0xdc); PC1 ($3); rl78_linkrelax_branch (); }
| BNC '$' EXPR
- { B1 (0xde); PC1 ($3); }
+ { B1 (0xde); PC1 ($3); rl78_linkrelax_branch (); }
| BZ '$' EXPR
- { B1 (0xdd); PC1 ($3); }
+ { B1 (0xdd); PC1 ($3); rl78_linkrelax_branch (); }
| BNZ '$' EXPR
- { B1 (0xdf); PC1 ($3); }
+ { B1 (0xdf); PC1 ($3); rl78_linkrelax_branch (); }
| BH '$' EXPR
- { B2 (0x61, 0xc3); PC1 ($3); }
+ { B2 (0x61, 0xc3); PC1 ($3); rl78_linkrelax_branch (); }
| BNH '$' EXPR
- { B2 (0x61, 0xd3); PC1 ($3); }
+ { B2 (0x61, 0xd3); PC1 ($3); rl78_linkrelax_branch (); }
/* ---------------------------------------------------------------------- */
{ if (expr_is_sfr ($2))
{ B2 (0x31, 0x80|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
else if (expr_is_saddr ($2))
- { B2 (0x31, 0x00|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); }
+ { B2 (0x31, 0x00|$1); FE ($4, 9, 3); SET_SA ($2); O1 ($2); PC1 ($7); }
else
NOT_SFR_OR_SADDR;
}
{ B2 (0x61, 0xcb); }
| BR '$' EXPR
- { B1 (0xef); PC1 ($3); }
+ { B1 (0xef); PC1 ($3); rl78_linkrelax_branch (); }
| BR '$' '!' EXPR
- { B1 (0xee); PC2 ($4); }
+ { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); }
| BR '!' EXPR
- { B1 (0xed); O2 ($3); }
+ { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); }
| BR '!' '!' EXPR
- { B1 (0xec); O3 ($4); }
+ { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); }
/* ---------------------------------------------------------------------- */
{ B1 (0xfd); O2 ($3); }
| CALL '!' '!' EXPR
- { B1 (0xfc); O3 ($4); }
+ { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); }
| CALLT '[' EXPR ']'
{ if ($3.X_op != O_constant)
{ if (expr_is_sfr ($2))
{ B2 (0x71, 0x0a|$1); FE ($4, 9, 3); O1 ($2); }
else if (expr_is_saddr ($2))
- { B2 (0x71, 0x02|$1); FE ($4, 9, 3); O1 ($2); }
+ { B2 (0x71, 0x02|$1); FE ($4, 9, 3); SET_SA ($2); O1 ($2); }
else
NOT_SFR_OR_SADDR;
}
{ B2 (0x71, 0x8a|$1); FE ($4, 9, 3); }
| setclr1 opt_es '!' EXPR '.' EXPR
- { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); }
+ { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); }
| setclr1 opt_es '[' HL ']' '.' EXPR
{ B2 (0x71, 0x82|$1); FE ($7, 9, 3); }
{ B1 (0xe2|$1); }
| oneclrb EXPR {SA($2)}
- { B1 (0xe4|$1); O1 ($2); }
+ { B1 (0xe4|$1); SET_SA ($2); O1 ($2); }
| oneclrb opt_es '!' EXPR
- { B1 (0xe5|$1); O2 ($4); }
+ { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); }
/* ---------------------------------------------------------------------- */
{ B1 (0xd2); }
| CMP0 EXPR {SA($2)}
- { B1 (0xd4); O1 ($2); }
+ { B1 (0xd4); SET_SA ($2); O1 ($2); }
| CMP0 opt_es '!' EXPR
- { B1 (0xd5); O2 ($4); }
+ { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); }
/* ---------------------------------------------------------------------- */
{ B1 (0x80|$1); F ($2, 5, 3); }
| incdec EXPR {SA($2)}
- { B1 (0xa4|$1); O1 ($2); }
+ { B1 (0xa4|$1); SET_SA ($2); O1 ($2); }
| incdec '!' EXPR
- { B1 (0xa0|$1); O2 ($3); }
+ { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); }
| incdec ES ':' '!' EXPR
{ B2 (0x11, 0xa0|$1); O2 ($5); }
| incdec '[' HL '+' EXPR ']'
{ B1 (0xa1|$1); F ($2, 5, 2); }
| incdecw EXPR {SA($2)}
- { B1 (0xa6|$1); O1 ($2); }
+ { B1 (0xa6|$1); SET_SA ($2); O1 ($2); }
| incdecw opt_es '!' EXPR
- { B1 (0xa2|$1); O2 ($4); }
+ { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); }
| incdecw opt_es '[' HL '+' EXPR ']'
{ B2 (0x61, 0x79+$1); O1 ($6); }
/* ---------------------------------------------------------------------- */
- | MULHU
+ | MULHU { ISA_G14 ("MULHU"); }
{ B3 (0xce, 0xfb, 0x01); }
- | MULH
+ | MULH { ISA_G14 ("MULH"); }
{ B3 (0xce, 0xfb, 0x02); }
| MULU X
{ B1 (0xd6); }
- | DIVHU
+ | DIVHU { ISA_G14 ("DIVHU"); }
{ B3 (0xce, 0xfb, 0x03); }
- | DIVWU
- { B3 (0xce, 0xfb, 0x04); }
+/* Note that the DIVWU encoding was changed from [0xce,0xfb,0x04] to
+ [0xce,0xfb,0x0b]. Different versions of the Software Manual exist
+ with the same version number, but varying encodings. The version
+ here matches the hardware. */
- | MACHU
+ | DIVWU { ISA_G14 ("DIVWU"); }
+ { B3 (0xce, 0xfb, 0x0b); }
+
+ | MACHU { ISA_G14 ("MACHU"); }
{ B3 (0xce, 0xfb, 0x05); }
- | MACH
+ | MACH { ISA_G14 ("MACH"); }
{ B3 (0xce, 0xfb, 0x06); }
/* ---------------------------------------------------------------------- */
{ if (expr_is_sfr ($3))
{ B1 (0xce); O1 ($3); O1 ($6); }
else if (expr_is_saddr ($3))
- { B1 (0xcd); O1 ($3); O1 ($6); }
+ { B1 (0xcd); SET_SA ($3); O1 ($3); O1 ($6); }
else
NOT_SFR_OR_SADDR;
}
| MOV '!' EXPR ',' '#' EXPR
- { B1 (0xcf); O2 ($3); O1 ($6); }
+ { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); }
| MOV ES ':' '!' EXPR ',' '#' EXPR
{ B2 (0x11, 0xcf); O2 ($5); O1 ($8); }
{ if (expr_is_sfr ($3))
{ B1 (0x9e); O1 ($3); }
else if (expr_is_saddr ($3))
- { B1 (0x9d); O1 ($3); }
+ { B1 (0x9d); SET_SA ($3); O1 ($3); }
else
NOT_SFR_OR_SADDR;
}
| MOV A ',' opt_es '!' EXPR
- { B1 (0x8f); O2 ($6); }
+ { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); }
| MOV '!' EXPR ',' A
- { B1 (0x9f); O2 ($3); }
+ { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); }
| MOV ES ':' '!' EXPR ',' A
{ B2 (0x11, 0x9f); O2 ($5); }
| MOV regb_na ',' opt_es '!' EXPR
- { B1 (0xc9|reg_xbc($2)); O2 ($6); }
+ { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); }
| MOV A ',' opt_es EXPR {NOT_ES}
{ if (expr_is_saddr ($5))
- { B1 (0x8d); O1 ($5); }
+ { B1 (0x8d); SET_SA ($5); O1 ($5); }
else if (expr_is_sfr ($5))
{ B1 (0x8e); O1 ($5); }
else
}
| MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES}
- { B1 (0xc8|reg_xbc($2)); O1 ($5); }
+ { B1 (0xc8|reg_xbc($2)); SET_SA ($5); O1 ($5); }
| MOV A ',' sfr
{ B2 (0x8e, $4); }
{ if ($2 != 0xfd)
rl78_error ("Only ES allowed here");
else
- { B2 (0x61, 0xb8); O1 ($5); }
+ { B2 (0x61, 0xb8); SET_SA ($5); O1 ($5); }
}
| MOV A ',' opt_es '[' DE ']'
/* ---------------------------------------------------------------------- */
- | MOV1 CY ',' EXPR '.' EXPR
+ | mov1 CY ',' EXPR '.' EXPR
{ if (expr_is_saddr ($4))
- { B2 (0x71, 0x04); FE ($6, 9, 3); O1 ($4); }
+ { B2 (0x71, 0x04); FE ($6, 9, 3); SET_SA ($4); O1 ($4); }
else if (expr_is_sfr ($4))
{ B2 (0x71, 0x0c); FE ($6, 9, 3); O1 ($4); }
else
NOT_SFR_OR_SADDR;
}
- | MOV1 CY ',' A '.' EXPR
+ | mov1 CY ',' A '.' EXPR
{ B2 (0x71, 0x8c); FE ($6, 9, 3); }
- | MOV1 CY ',' sfr '.' EXPR
+ | mov1 CY ',' sfr '.' EXPR
{ B3 (0x71, 0x0c, $4); FE ($6, 9, 3); }
- | MOV1 CY ',' opt_es '[' HL ']' '.' EXPR
+ | mov1 CY ',' opt_es '[' HL ']' '.' EXPR
{ B2 (0x71, 0x84); FE ($9, 9, 3); }
- | MOV1 EXPR '.' EXPR ',' CY
+ | mov1 EXPR '.' EXPR ',' CY
{ if (expr_is_saddr ($2))
- { B2 (0x71, 0x01); FE ($4, 9, 3); O1 ($2); }
+ { B2 (0x71, 0x01); FE ($4, 9, 3); SET_SA ($2); O1 ($2); }
else if (expr_is_sfr ($2))
{ B2 (0x71, 0x09); FE ($4, 9, 3); O1 ($2); }
else
NOT_SFR_OR_SADDR;
}
- | MOV1 A '.' EXPR ',' CY
+ | mov1 A '.' EXPR ',' CY
{ B2 (0x71, 0x89); FE ($4, 9, 3); }
- | MOV1 sfr '.' EXPR ',' CY
+ | mov1 sfr '.' EXPR ',' CY
{ B3 (0x71, 0x09, $2); FE ($4, 9, 3); }
- | MOV1 opt_es '[' HL ']' '.' EXPR ',' CY
+ | mov1 opt_es '[' HL ']' '.' EXPR ',' CY
{ B2 (0x71, 0x81); FE ($7, 9, 3); }
/* ---------------------------------------------------------------------- */
| MOVW opt_es EXPR ',' '#' EXPR {NOT_ES}
{ if (expr_is_saddr ($3))
- { B1 (0xc9); O1 ($3); O2 ($6); }
+ { B1 (0xc9); SET_SA ($3); O1 ($3); O2 ($6); }
else if (expr_is_sfr ($3))
{ B1 (0xcb); O1 ($3); O2 ($6); }
else
| MOVW AX ',' opt_es EXPR {NOT_ES}
{ if (expr_is_saddr ($5))
- { B1 (0xad); O1 ($5); WA($5); }
+ { B1 (0xad); SET_SA ($5); O1 ($5); WA($5); }
else if (expr_is_sfr ($5))
{ B1 (0xae); O1 ($5); WA($5); }
else
| MOVW opt_es EXPR ',' AX {NOT_ES}
{ if (expr_is_saddr ($3))
- { B1 (0xbd); O1 ($3); WA($3); }
+ { B1 (0xbd); SET_SA ($3); O1 ($3); WA($3); }
else if (expr_is_sfr ($3))
{ B1 (0xbe); O1 ($3); WA($3); }
else
{ B1 (0x10); F ($2, 5, 2); }
| MOVW AX ',' opt_es '!' EXPR
- { B1 (0xaf); O2 ($6); WA($6); }
+ { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
| MOVW opt_es '!' EXPR ',' AX
- { B1 (0xbf); O2 ($4); WA($4); }
+ { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); }
| MOVW AX ',' opt_es '[' DE ']'
{ B1 (0xa9); }
{ B2 (0xb8, 0); }
| MOVW regw_na ',' EXPR {SA($4)}
- { B1 (0xca); F ($2, 2, 2); O1 ($4); WA($4); }
+ { B1 (0xca); F ($2, 2, 2); SET_SA ($4); O1 ($4); WA($4); }
| MOVW regw_na ',' opt_es '!' EXPR
- { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); }
+ { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); }
| MOVW SP ',' '#' EXPR
{ B2 (0xcb, 0xf8); O2 ($5); }
| NOP
{ B1 (0x00); }
+/* ---------------------------------------------------------------------- */
+
+ | NOT1 CY
+ { B2 (0x71, 0xc0); }
+
/* ---------------------------------------------------------------------- */
| POP regw
/* ---------------------------------------------------------------------- */
| SKC
- { B2 (0x61, 0xc8); }
+ { B2 (0x61, 0xc8); rl78_relax (RL78_RELAX_BRANCH, 0); }
| SKH
- { B2 (0x61, 0xe3); }
+ { B2 (0x61, 0xe3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| SKNC
- { B2 (0x61, 0xd8); }
+ { B2 (0x61, 0xd8); rl78_relax (RL78_RELAX_BRANCH, 0); }
| SKNH
- { B2 (0x61, 0xf3); }
+ { B2 (0x61, 0xf3); rl78_relax (RL78_RELAX_BRANCH, 0); }
| SKNZ
- { B2 (0x61, 0xf8); }
+ { B2 (0x61, 0xf8); rl78_relax (RL78_RELAX_BRANCH, 0); }
| SKZ
- { B2 (0x61, 0xe8); }
+ { B2 (0x61, 0xe8); rl78_relax (RL78_RELAX_BRANCH, 0); }
/* ---------------------------------------------------------------------- */
}
| XCH A ',' opt_es '!' EXPR
- { B2 (0x61, 0xaa); O2 ($6); }
+ { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); }
| XCH A ',' opt_es '[' DE ']'
{ B2 (0x61, 0xae); }
{ if (expr_is_sfr ($4))
{ B2 (0x61, 0xab); O1 ($4); }
else if (expr_is_saddr ($4))
- { B2 (0x61, 0xa8); O1 ($4); }
+ { B2 (0x61, 0xa8); SET_SA ($4); O1 ($4); }
else
NOT_SFR_OR_SADDR;
}
| CMPW { $$ = 0x40; }
;
-andor1 : AND1 { $$ = 0x05; }
- | OR1 { $$ = 0x06; }
- | XOR1 { $$ = 0x07; }
+andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; }
+ | OR1 { $$ = 0x06; rl78_bit_insn = 1; }
+ | XOR1 { $$ = 0x07; rl78_bit_insn = 1; }
;
-bt_bf : BT { $$ = 0x02; }
- | BF { $$ = 0x04; }
- | BTCLR { $$ = 0x00; }
+bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1; rl78_linkrelax_branch (); }
+ | BF { $$ = 0x04; rl78_bit_insn = 1; rl78_linkrelax_branch (); }
+ | BTCLR { $$ = 0x00; rl78_bit_insn = 1; }
;
-setclr1 : SET1 { $$ = 0; }
- | CLR1 { $$ = 1; }
+setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; }
+ | CLR1 { $$ = 1; rl78_bit_insn = 1; }
;
oneclrb : ONEB { $$ = 0x00; }
| DECW { $$ = 0x10; }
;
+mov1 : MOV1 { rl78_bit_insn = 1; }
+ ;
+
%%
/* ====================================================================== */
OPC(MULHU),
OPC(MULU),
OPC(NOP),
+ OPC(NOT1),
OPC(ONEB),
OPC(ONEW),
OPC(OR),
rl78_in_brackets = 0;
rl78_last_token = 0;
+ rl78_bit_insn = 0;
+
setbuf (stdout, 0);
}
+/* Return a pointer to the '.' in a bit index expression (like
+ foo.5), or NULL if none is found. */
+static char *
+find_bit_index (char *tok)
+{
+ char *last_dot = NULL;
+ char *last_digit = NULL;
+ while (*tok && *tok != ',')
+ {
+ if (*tok == '.')
+ {
+ last_dot = tok;
+ last_digit = NULL;
+ }
+ else if (*tok >= '0' && *tok <= '7'
+ && last_dot != NULL
+ && last_digit == NULL)
+ {
+ last_digit = tok;
+ }
+ else if (ISSPACE (*tok))
+ {
+ /* skip */
+ }
+ else
+ {
+ last_dot = NULL;
+ last_digit = NULL;
+ }
+ tok ++;
+ }
+ if (last_dot != NULL
+ && last_digit != NULL)
+ return last_dot;
+ return NULL;
+}
+
static int
rl78_lex (void)
{
/*unsigned int ci;*/
char * save_input_pointer;
+ char * bit = NULL;
while (ISSPACE (*rl78_lex_start)
&& rl78_lex_start != rl78_lex_end)
bitfields. We check for it specially so we can allow labels
with '.' in them. */
- if (*rl78_lex_start == '.'
- && ISDIGIT (rl78_lex_start[1])
- && (rl78_last_token == ']'
- || rl78_last_token == A
- || rl78_last_token == PSW
- || rl78_last_token == EXPR))
+ if (rl78_bit_insn
+ && *rl78_lex_start == '.'
+ && find_bit_index (rl78_lex_start) == rl78_lex_start)
{
rl78_last_token = *rl78_lex_start;
return *rl78_lex_start ++;
return *rl78_lex_start ++;
}
+ /* Again, '.' is funny. Look for '.<digit>' at the end of the line
+ or before a comma, which is a bitfield, not an expression. */
+
+ if (rl78_bit_insn)
+ {
+ bit = find_bit_index (rl78_lex_start);
+ if (bit)
+ *bit = 0;
+ else
+ bit = NULL;
+ }
+
save_input_pointer = input_line_pointer;
input_line_pointer = rl78_lex_start;
rl78_lval.exp.X_md = 0;
expression (&rl78_lval.exp);
+ if (bit)
+ *bit = '.';
+
rl78_lex_start = input_line_pointer;
input_line_pointer = save_input_pointer;
rl78_last_token = EXPR;
}
int
-rl78_error (char * str)
+rl78_error (const char * str)
{
int len;
unsigned long v;
if (exp.X_op != O_constant)
- return 0;
+ return 1;
v = exp.X_add_number;
if (0xFFE20 <= v && v <= 0xFFF1F)
if (v & 1)
return 0;
return 1;
-
+
}
static void
}
return 1;
}
-
-