scripts/dtc: Add support for floating-point literals

Signed-off-by: Asahi Lina <lina@asahilina.net>
This commit is contained in:
Mark Kettenis 2023-04-14 13:14:41 +02:00 committed by Janne Grunau
parent fc674bc74d
commit ae70c3fc84
4 changed files with 66 additions and 0 deletions

View file

@ -197,6 +197,33 @@ struct data data_append_integer(struct data d, uint64_t value, int bits)
}
}
struct data data_append_float(struct data d, double value, int bits)
{
float f32;
uint32_t u32;
double f64;
uint64_t u64;
fdt32_t value_32;
fdt64_t value_64;
switch (bits) {
case 32:
f32 = value;
memcpy(&u32, &f32, sizeof(u32));
value_32 = cpu_to_fdt32(u32);
return data_append_data(d, &value_32, 4);
case 64:
f64 = value;
memcpy(&u64, &f64, sizeof(u64));
value_64 = cpu_to_fdt64(u64);
return data_append_data(d, &value_64, 8);
default:
die("Invalid literal size (%d)\n", bits);
}
}
struct data data_append_re(struct data d, uint64_t address, uint64_t size)
{
struct fdt_reserve_entry re;

View file

@ -166,6 +166,28 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
return DT_LABEL;
}
<V1>[-+]?(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))(e[-+]?[0-9]+)?f? {
char *e;
DPRINT("Floating-point Literal: '%s'\n", yytext);
errno = 0;
yylval.floating = strtod(yytext, &e);
if (*e && (*e != 'f' || e[1])) {
lexical_error("Bad floating-point literal '%s'",
yytext);
}
if (errno == ERANGE)
lexical_error("Floating-point literal '%s' out of range",
yytext);
else
/* ERANGE is the only strtod error triggerable
* by strings matching the pattern */
assert(errno == 0);
return DT_FP_LITERAL;
}
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
char *e;
DPRINT("Integer Literal: '%s'\n", yytext);

View file

@ -53,6 +53,7 @@ extern bool treesource_error;
struct node *nodelist;
struct reserve_info *re;
uint64_t integer;
double floating;
unsigned int flags;
}
@ -66,6 +67,7 @@ extern bool treesource_error;
%token DT_OMIT_NO_REF
%token <propnodename> DT_PROPNODENAME
%token <integer> DT_LITERAL
%token <floating> DT_FP_LITERAL
%token <integer> DT_CHAR_LITERAL
%token <byte> DT_BYTE
%token <data> DT_STRING
@ -89,6 +91,7 @@ extern bool treesource_error;
%type <node> subnode
%type <nodelist> subnodes
%type <floating> floating_prim
%type <integer> integer_prim
%type <integer> integer_unary
%type <integer> integer_mul
@ -358,6 +361,15 @@ arrayprefix:
$$.data = empty_data;
$$.bits = 32;
}
| arrayprefix floating_prim
{
if ($1.bits < 32) {
ERROR(&@2, "Floating-point values must be"
" 32-bit or 64-bit");
}
$$.data = data_append_float($1.data, $2, $1.bits);
}
| arrayprefix integer_prim
{
if ($1.bits < 64) {
@ -397,6 +409,10 @@ arrayprefix:
}
;
floating_prim:
DT_FP_LITERAL
;
integer_prim:
DT_LITERAL
| DT_CHAR_LITERAL

View file

@ -115,6 +115,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
struct data data_merge(struct data d1, struct data d2);
struct data data_append_cell(struct data d, cell_t word);
struct data data_append_integer(struct data d, uint64_t word, int bits);
struct data data_append_float(struct data d, double value, int bits);
struct data data_append_re(struct data d, uint64_t address, uint64_t size);
struct data data_append_addr(struct data d, uint64_t addr);
struct data data_append_byte(struct data d, uint8_t byte);