This allows adding support for signed operations and preserving negative integers in yaml and dts output. Signed-off-by: Andrei Ziureaev <andrei.ziureaev@xxxxxxx> --- dtc-lexer.l | 10 ++-- dtc-parser.y | 127 +++++++++++++++++++++++++++++++++++++-------------- dtc.h | 3 ++ 3 files changed, 102 insertions(+), 38 deletions(-) diff --git a/dtc-lexer.l b/dtc-lexer.l index b3b7270..037a2ab 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -156,7 +156,9 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...); DPRINT("Integer Literal: '%s'\n", yytext); errno = 0; - yylval.integer = strtoull(yytext, &e, 0); + yylval.integer = (struct integer){ + strtoull(yytext, &e, 0) + }; if (*e && e[strspn(e, "UL")]) { lexical_error("Bad integer literal '%s'", @@ -180,9 +182,11 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...); d = data_copy_escape_string(yytext+1, yyleng-2); if (d.len == 1) { lexical_error("Empty character literal"); - yylval.integer = 0; + yylval.integer = (struct integer){ 0 }; } else { - yylval.integer = (unsigned char)d.val[0]; + yylval.integer = (struct integer){ + (unsigned char)d.val[0] + }; if (d.len > 2) lexical_error("Character literal has %d" diff --git a/dtc-parser.y b/dtc-parser.y index c8c1875..3bc1aca 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -41,7 +41,7 @@ extern bool treesource_error; struct node *node; struct node *nodelist; struct reserve_info *re; - uint64_t integer; + struct integer integer; unsigned int flags; } @@ -140,7 +140,7 @@ memreserves: memreserve: DT_MEMRESERVE integer_prim integer_prim ';' { - $$ = build_reserve_entry($2, $3); + $$ = build_reserve_entry($2.ull, $3.ull); } | DT_LABEL memreserve { @@ -310,13 +310,13 @@ propdata: FILE *f = srcfile_relative_open($4.val, NULL); struct data d; - if ($6 != 0) - if (fseek(f, $6, SEEK_SET) != 0) + if ($6.ull != 0) + if (fseek(f, $6.ull, SEEK_SET) != 0) die("Couldn't seek to offset %llu in \"%s\": %s", - (unsigned long long)$6, $4.val, + (unsigned long long)$6.ull, $4.val, strerror(errno)); - d = data_copy_file(f, $8); + d = data_copy_file(f, $8.ull); $$ = data_merge($1, d); fclose(f); @@ -358,7 +358,7 @@ arrayprefix: unsigned long long bits; enum markertype type = TYPE_UINT32; - bits = $2; + bits = $2.ull; switch (bits) { case 8: type = TYPE_UINT8; break; @@ -391,12 +391,12 @@ arrayprefix: * within the mask to one (i.e. | in the * mask), all bits are one. */ - if (($2 > mask) && (($2 | mask) != -1ULL)) + if (($2.ull > mask) && (($2.ull | mask) != -1ULL)) ERROR(&@2, "Value out of range for" " %d-bit array element", $1.bits); } - $$.data = data_append_integer($1.data, $2, $1.bits); + $$.data = data_append_integer($1.data, $2.ull, $1.bits); } | arrayprefix dt_ref { @@ -433,78 +433,126 @@ integer_expr: integer_trinary: integer_or - | integer_or '?' integer_expr ':' integer_trinary { $$ = $1 ? $3 : $5; } + | integer_or '?' integer_expr ':' integer_trinary { $$ = $1.ull ? $3 : $5; } ; integer_or: integer_and - | integer_or DT_OR integer_and { $$ = $1 || $3; } + | integer_or DT_OR integer_and + { + $$ = (struct integer){ $1.ull || $3.ull }; + } ; integer_and: integer_bitor - | integer_and DT_AND integer_bitor { $$ = $1 && $3; } + | integer_and DT_AND integer_bitor + { + $$ = (struct integer){ $1.ull && $3.ull }; + } ; integer_bitor: integer_bitxor - | integer_bitor '|' integer_bitxor { $$ = $1 | $3; } + | integer_bitor '|' integer_bitxor + { + $$ = (struct integer){ $1.ull | $3.ull }; + } ; integer_bitxor: integer_bitand - | integer_bitxor '^' integer_bitand { $$ = $1 ^ $3; } + | integer_bitxor '^' integer_bitand + { + $$ = (struct integer){ $1.ull ^ $3.ull }; + } ; integer_bitand: integer_eq - | integer_bitand '&' integer_eq { $$ = $1 & $3; } + | integer_bitand '&' integer_eq + { + $$ = (struct integer){ $1.ull & $3.ull }; + } ; integer_eq: integer_rela - | integer_eq DT_EQ integer_rela { $$ = $1 == $3; } - | integer_eq DT_NE integer_rela { $$ = $1 != $3; } + | integer_eq DT_EQ integer_rela + { + $$ = (struct integer){ $1.ull == $3.ull }; + } + | integer_eq DT_NE integer_rela + { + $$ = (struct integer){ $1.ull != $3.ull }; + } ; integer_rela: integer_shift - | integer_rela '<' integer_shift { $$ = $1 < $3; } - | integer_rela '>' integer_shift { $$ = $1 > $3; } - | integer_rela DT_LE integer_shift { $$ = $1 <= $3; } - | integer_rela DT_GE integer_shift { $$ = $1 >= $3; } + | integer_rela '<' integer_shift + { + $$ = (struct integer){ $1.ull < $3.ull }; + } + | integer_rela '>' integer_shift + { + $$ = (struct integer){ $1.ull > $3.ull }; + } + | integer_rela DT_LE integer_shift + { + $$ = (struct integer){ $1.ull <= $3.ull }; + } + | integer_rela DT_GE integer_shift + { + $$ = (struct integer){ $1.ull >= $3.ull }; + } ; integer_shift: - integer_shift DT_LSHIFT integer_add { $$ = ($3 < 64) ? ($1 << $3) : 0; } - | integer_shift DT_RSHIFT integer_add { $$ = ($3 < 64) ? ($1 >> $3) : 0; } + integer_shift DT_LSHIFT integer_add + { + $$ = (struct integer){ ($3.ull < 64) ? ($1.ull << $3.ull) : 0 }; + } + | integer_shift DT_RSHIFT integer_add + { + $$ = (struct integer){ ($3.ull < 64) ? ($1.ull >> $3.ull) : 0 }; + } | integer_add ; integer_add: - integer_add '+' integer_mul { $$ = $1 + $3; } - | integer_add '-' integer_mul { $$ = $1 - $3; } + integer_add '+' integer_mul + { + $$ = (struct integer){ $1.ull + $3.ull }; + } + | integer_add '-' integer_mul + { + $$ = (struct integer){ $1.ull - $3.ull }; + } | integer_mul ; integer_mul: - integer_mul '*' integer_unary { $$ = $1 * $3; } + integer_mul '*' integer_unary + { + $$ = (struct integer){ $1.ull * $3.ull }; + } | integer_mul '/' integer_unary { - if ($3 != 0) { - $$ = $1 / $3; + if ($3.ull != 0) { + $$ = (struct integer){ $1.ull / $3.ull }; } else { ERROR(&@$, "Division by zero"); - $$ = 0; + $$ = (struct integer){ 0 }; } } | integer_mul '%' integer_unary { - if ($3 != 0) { - $$ = $1 % $3; + if ($3.ull != 0) { + $$ = (struct integer){ $1.ull % $3.ull }; } else { ERROR(&@$, "Division by zero"); - $$ = 0; + $$ = (struct integer){ 0 }; } } | integer_unary @@ -512,9 +560,18 @@ integer_mul: integer_unary: integer_prim - | '-' integer_unary { $$ = -$2; } - | '~' integer_unary { $$ = ~$2; } - | '!' integer_unary { $$ = !$2; } + | '-' integer_unary + { + $$ = (struct integer){ -$2.ull }; + } + | '~' integer_unary + { + $$ = (struct integer){ ~$2.ull }; + } + | '!' integer_unary + { + $$ = (struct integer){ !$2.ull }; + } ; bytestring: diff --git a/dtc.h b/dtc.h index e3225ab..ccfe689 100644 --- a/dtc.h +++ b/dtc.h @@ -117,6 +117,9 @@ struct data { struct marker *markers; }; +struct integer { + uint64_t ull; +}; #define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ }) -- 2.17.1