Commit b5450704 authored by Lev Walkin's avatar Lev Walkin

generate float instead of double if constraints suggest this

parent 026e21ab
......@@ -122,6 +122,21 @@ static int compar_enumMap_byValue(const void *ap, const void *bp) {
return 1;
}
static int
REAL_fits_float32(arg_t *arg, asn1p_expr_t *expr) {
asn1p_expr_type_e etype = expr_get_type(arg, arg->expr);
if(etype == ASN_BASIC_REAL) {
asn1cnst_range_t *range = asn1constraint_compute_OER_range(
expr->Identifier, etype, expr->combined_constraints, ACT_EL_RANGE,
0, 0, 0);
int fits = range->narrowing == NARROW_FLOAT32;
asn1constraint_range_free(range);
return fits;
} else {
return 0;
}
}
int
asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
......@@ -1298,6 +1313,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
&& expr_elements_count(arg, expr))
|| (expr->expr_type == ASN_BASIC_INTEGER
&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
|| REAL_fits_float32(arg, expr)
)
etd_spec = ETD_HAS_SPECIFICS;
else
......@@ -1339,6 +1355,16 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
REDIR(OT_STAT_DEFS);
if(REAL_fits_float32(arg, expr)) {
if(!(expr->_type_referenced)) OUT("static ");
OUT("const asn_NativeReal_specifics_t asn_SPC_%s_specs_%d = {\n",
MKID(expr), expr->_type_unique_index);
INDENT(+1);
OUT("4\t/* Use 'float' type. */\n");
INDENT(-1);
OUT("};\n");
}
/*
* Print out asn_DEF_<type>_[all_]tags[] vectors.
*/
......@@ -1374,22 +1400,22 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
p, expr->_type_unique_index);
} else {
OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p);
if (etd_spec == ETD_HAS_SPECIFICS) {
if((expr->expr_type == ASN_BASIC_ENUMERATED) ||
(expr->expr_type == ASN_BASIC_INTEGER)) {
if(expr->_type_referenced) {
OUT("extern const asn_INTEGER_specifics_t "
"asn_SPC_%s_specs_%d;\n", c_name(arg).base_name, expr->_type_unique_index);
}
} else {
if(etd_spec == ETD_HAS_SPECIFICS && expr->_type_referenced) {
if((expr->expr_type == ASN_BASIC_ENUMERATED)
|| (expr->expr_type == ASN_BASIC_INTEGER)) {
OUT("extern const asn_INTEGER_specifics_t "
"asn_SPC_%s_specs_%d;\n",
c_name(arg).base_name, expr->_type_unique_index);
} else {
asn1p_expr_t *terminal = WITH_MODULE_NAMESPACE(
expr->module, expr_ns,
asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
OUT("extern asn_%s_specifics_t ", asn1c_type_name(arg, terminal, TNF_SAFE));
OUT("asn_SPC_%s_specs_%d;\n", MKID(expr), expr->_type_unique_index);
}
}
OUT("extern const asn_%s_specifics_t ",
asn1c_type_name(arg, terminal, TNF_SAFE));
OUT("asn_SPC_%s_specs_%d;\n", MKID(expr),
expr->_type_unique_index);
}
}
OUT("asn_struct_free_f %s_free;\n", p);
OUT("asn_struct_print_f %s_print;\n", p);
OUT("asn_constr_check_f %s_constraint;\n", p);
......@@ -1846,14 +1872,6 @@ emit_single_member_OER_constraint_value(arg_t *arg, asn1cnst_range_t *range) {
if(range->incompatible || range->not_OER_visible) {
OUT("{ 0, 0 }");
} else if(expr_get_type(arg, arg->expr) == ASN_BASIC_REAL) {
if(range->narrowing == NARROW_FLOAT32) {
OUT("{ 4, 0 }");
} else if(range->narrowing == NARROW_FLOAT64) {
OUT("{ 8, 0 }");
} else {
OUT("{ 0, 0 }");
}
} else if(range->left.type == ARE_VALUE && range->left.value >= 0
&& range->right.type == ARE_MAX) {
OUT("{ 0, 1 }");
......
......@@ -2,6 +2,7 @@
#include "asn1c_constraint.h"
#include "asn1c_misc.h"
#include "asn1c_out.h"
#include "asn1c_naming.h"
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
#include <asn1fix_export.h> /* other exportables from libasn1fix */
......@@ -114,7 +115,7 @@ asn1c_emit_constraint_checking_code(arg_t *arg) {
}
break;
case ASN_BASIC_REAL:
OUT("double value;\n");
OUT("%s value;\n", c_name(arg).type.constrained_c_name);
break;
case ASN_BASIC_BOOLEAN:
OUT("BOOLEAN_t value;\n");
......@@ -676,7 +677,7 @@ emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype, asn1cnst_rang
INDENT(-1);
OUT("}\n");
} else {
OUT("value = *(const double *)sptr;\n");
OUT("value = *(const %s *)sptr;\n", c_name(arg).type.c_name);
}
break;
case ASN_BASIC_BOOLEAN:
......
......@@ -215,7 +215,7 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
}
}
if(_format == TNF_CTYPE) {
if(_format == TNF_CTYPE || _format == TNF_CONSTYPE) {
/*
* If the component references the type itself,
* switch to a recursion-safe type naming
......@@ -236,18 +236,36 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
case ASN_BASIC_ENUMERATED:
case ASN_BASIC_REAL:
if((expr->expr_type == ASN_BASIC_REAL
&& !(arg->flags & A1C_USE_WIDE_TYPES))
&& (_format == TNF_CONSTYPE || !(arg->flags & A1C_USE_WIDE_TYPES)))
|| asn1c_type_fits_long(arg, expr)) {
switch(_format) {
case TNF_CTYPE:
case TNF_RSAFE:
if(expr->expr_type == ASN_BASIC_REAL)
return "double";
else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
return "unsigned long";
else
return "long";
default:
case TNF_CONSTYPE:
if(expr->expr_type == ASN_BASIC_REAL) {
return "double";
} else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) {
return "unsigned long";
} else {
return "long";
}
case TNF_CTYPE:
case TNF_RSAFE:
if(expr->expr_type == ASN_BASIC_REAL) {
asn1cnst_range_t *range = asn1constraint_compute_OER_range(
expr->Identifier, ASN_BASIC_REAL,
expr->combined_constraints, ACT_EL_RANGE, 0, 0, 0);
if(range->narrowing == NARROW_FLOAT32) {
asn1constraint_range_free(range);
return "float";
} else {
asn1constraint_range_free(range);
return "double";
}
} else if(asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) {
return "unsigned long";
} else {
return "long";
}
default:
typename = 0;
switch(expr->expr_type) {
case ASN_BASIC_INTEGER:
......@@ -298,6 +316,7 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
case TNF_SAFE:
return asn1c_make_identifier(0, exprid, typename, (char*)0);
case TNF_CTYPE: /* C type */
case TNF_CONSTYPE: /* C type */
return asn1c_make_identifier(0, exprid,
exprid?"t":typename, exprid?0:"t", (char*)0);
case TNF_RSAFE: /* Recursion-safe type */
......
......@@ -23,8 +23,9 @@ enum tnfmt {
TNF_UNMODIFIED = 0x10, /* Return unmodified type name */
TNF_INCLUDE = 0x20, /* Format for #include <> */
TNF_CTYPE = 0x30, /* Format as normal C-ish type (append "_t") */
TNF_SAFE = 0x40, /* Replace unsafe characters with _ */
TNF_RSAFE = 0x50, /* Recursion-safe C type format */
TNF_CONSTYPE = 0x40, /* Replace unsafe characters with _ */
TNF_SAFE = 0x50, /* Replace unsafe characters with _ */
TNF_RSAFE = 0x60, /* Recursion-safe C type format */
};
const char *asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format);
......
......@@ -121,6 +121,7 @@ c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
static abuf b_type_part_name;
static abuf b_type_base_name;
static abuf b_type_c_name;
static abuf b_type_constrained_c_name;
static abuf b_asn_name;
static abuf b_part_name;
static abuf b_base_name;
......@@ -136,6 +137,7 @@ c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
abuf_clear(&b_type_part_name);
abuf_clear(&b_type_base_name);
abuf_clear(&b_type_c_name);
abuf_clear(&b_type_constrained_c_name);
abuf_clear(&b_asn_name);
abuf_clear(&b_base_name);
abuf_clear(&b_part_name);
......@@ -152,6 +154,8 @@ c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
abuf_str(&b_type_part_name, asn1c_type_name(arg, expr, TNF_SAFE));
abuf_str(&b_type_base_name, asn1c_type_name(arg, expr, TNF_SAFE));
abuf_str(&b_type_c_name, asn1c_type_name(arg, expr, TNF_CTYPE));
abuf_str(&b_type_constrained_c_name,
asn1c_type_name(arg, expr, TNF_CONSTYPE));
if((arg->flags & A1C_COMPOUND_NAMES)) {
......@@ -189,6 +193,7 @@ c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
names.type.base_name = b_type_base_name.buffer;
names.type.part_name = b_type_part_name.buffer;
names.type.c_name = b_type_c_name.buffer;
names.type.constrained_c_name = b_type_constrained_c_name.buffer;
names.asn_name = b_asn_name.buffer;
names.part_name = b_part_name.buffer;
names.base_name = b_base_name.buffer;
......@@ -269,6 +274,7 @@ c_names_format(struct c_names ns) {
FMT_COMPONENT(type.part_name);
FMT_COMPONENT(type.base_name);
FMT_COMPONENT(type.c_name);
FMT_COMPONENT(type.constrained_c_name);
FMT_COMPONENT(asn_name);
FMT_COMPONENT(part_name);
FMT_COMPONENT(base_name);
......
......@@ -11,6 +11,7 @@ struct c_names {
const char *part_name; /* "T_Rex" */
const char *base_name; /* "T_Rex" */
const char *c_name; /* "T_Rex_t" */
const char *constrained_c_name; /* "long" */
} type;
const char *asn_name; /* "foo" */
const char *part_name; /* "foo", "signed" */
......
This diff is collapsed.
......@@ -17,6 +17,10 @@
extern "C" {
#endif
typedef struct asn_NativeReal_specifics_s {
unsigned float_size; /* 4 for 'float', not 4 for 'double'. */
} asn_NativeReal_specifics_t;
extern asn_TYPE_descriptor_t asn_DEF_NativeReal;
extern asn_TYPE_operation_t asn_OP_NativeReal;
......
......@@ -14,6 +14,10 @@ DEFINITIONS ::= BEGIN
WeirdlyConstrainedREAL ::= REAL (3, ...) -- Not really constrained
Indirect-IEEE-binary32 ::= UnconstrainedREAL (WITH COMPONENTS {
mantissa (-16777215..16777215),
base (2), exponent (-126..126)})
-- X.696 (08/2005) #12.2 and #12.3
-- IEEE 754 encoding single precision
......@@ -42,4 +46,14 @@ DEFINITIONS ::= BEGIN
mantissa (-9007199254740991..9007199254740991),
base (2), exponent (-1022..1023)} | 0)
Test ::= SEQUENCE {
indirect-ieee-binary32 Indirect-IEEE-binary32,
ieee-binary32-w IEEE-binary32-w,
ieee-binary32-0w IEEE-binary32-0w,
ieee-binary32-w0 IEEE-binary32-w0,
ieee-binary64-w IEEE-binary64-w,
ieee-binary64-0w IEEE-binary64-0w,
ieee-binary64-w0 IEEE-binary64-w0
}
END
-- Test the REAL (floating point) type.
T ::= REAL
T ::= REAL (WITH COMPONENTS { mantissa (-16777215..16777215), base (2), exponent (-126..126)})
T ::= REAL (WITH COMPONENTS { mantissa (-9007199254740991..9007199254740991), base (2), exponent (-1022..1023)})
T ::= Real32 Real32 ::= REAL (WITH COMPONENTS { mantissa (-16777215..16777215), base (2), exponent (-126..126)})
T ::= Real64 Real64 ::= REAL (WITH COMPONENTS { mantissa (-9007199254740991..9007199254740991), base (2), exponent (-1022..1023)})
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment