Skip to content

Commit

Permalink
fix(stdlib): Endian conversion functions (PLC-lang#1029)
Browse files Browse the repository at this point in the history
Currently endian conversion functions work mostly very wrong. Also most
of the test would also break in BE system.

Only TO_*_ENDIAN() for other than float types does what they should.
FROM_*_ENDIAN() for other than float types does conversion totally
wrong. Normally we would do in IEC something like this (PSEUDO):

address := FROM_LITTLE_ENDIAN(READ_MODBUS_ADDRESS_DWORD());

Now we would get big endian address even if we just wanted to document
that we have checked that address should be little endian. In companies
it is happit that every time they read/write to/from fieldbus they use
FROM_*_ENDIAN/TO_*_ENDIAN conversion functions so it is obvious that it
has been taken to account.

Also floating points did not do any conversions as they first convert to
x endian and then convert back to native.

I also improve unittests so it is now obvious that when we do not touch
res we should do same conversion for the some value.

Co-authored-by: Kari Argillander <[email protected]>
Co-authored-by: Michael <[email protected]>
  • Loading branch information
3 people authored Nov 24, 2023
1 parent ea718d2 commit 2da66ec
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 112 deletions.
44 changes: 24 additions & 20 deletions libs/stdlib/iec61131-st/endianness_conversion_functions.st
Original file line number Diff line number Diff line change
@@ -1,44 +1,48 @@
(********************
*
* Converts little endian data format to big endian data format
*
*********************)
(******************************************************************************
Description: Converts data to big endian format from native endian format.
Input:
- in: The input value in native endian format.
Return: The value converted to big endian format.
******************************************************************************)
{external}
FUNCTION TO_BIG_ENDIAN<T: ANY> : T
VAR_INPUT
in : T;
END_VAR
END_FUNCTION

(********************
*
* Converts big endian data format to little endian data format
*
*********************)
(******************************************************************************
Description: Converts data to little endian format from big endian format.
Input:
- in: The input value in native endian format.
Return: The value converted to little endian format.
******************************************************************************)
{external}
FUNCTION TO_LITTLE_ENDIAN<T: ANY> : T
VAR_INPUT
in : T;
END_VAR
END_FUNCTION

(********************
*
* Converts to little endian data format from big endian data format
*
*********************)
(******************************************************************************
Description: Converts data from big endian format to native endian format.
Input:
- in: The input value in big endian format.
Return: The value converted to native endian format.
******************************************************************************)
{external}
FUNCTION FROM_BIG_ENDIAN<T: ANY> : T
VAR_INPUT
in : T;
END_VAR
END_FUNCTION

(********************
*
* Converts to big endian data format from little endian data format
*
*********************)
(******************************************************************************
Description: Converts data from little endian format to native endian format.
Input:
- in: The input value in little endian format.
Return: The value converted to native endian format.
******************************************************************************)
{external}
FUNCTION FROM_LITTLE_ENDIAN<T: ANY> : T
VAR_INPUT
Expand Down
48 changes: 24 additions & 24 deletions libs/stdlib/src/endianness_conversion_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,39 @@ macro_rules! define_endianness_for_int_types {
( $st_type:tt, $t:ty ) => {
paste! {
/// .
/// Converts given integer type from little endian data format to big endian data format
/// Converts given integer type from native endian data format to big endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn [<TO_BIG_ENDIAN__ $st_type>](input: $t) -> $t {
return input.to_be();
input.to_be()
}

/// .
/// Converts given integer type from big endian data format to little endian data format
/// Converts given integer type from native endian data format to little endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn [<TO_LITTLE_ENDIAN__ $st_type>](input: $t) -> $t {
return input.to_le();
input.to_le()
}

/// .
/// Converts given integer type from big endian data format to little endian data format
/// Converts given integer type from big endian data format to native endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn [<FROM_BIG_ENDIAN__ $st_type>](input: $t) -> $t {
return input.to_le();
<$t>::from_be(input)
}

/// .
/// Converts given integer type from little endian data format to big endian data format
/// Converts given integer type from little endian data format to native endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn [<FROM_LITTLE_ENDIAN__ $st_type>](input: $t) -> $t {
return input.to_be();
<$t>::from_le(input)
}
}
};
Expand All @@ -57,73 +57,73 @@ define_endianness_for_int_types!(TIME_OF_DAY, i64);
define_endianness_for_int_types!(DATE_AND_TIME, i64);

/// .
/// Converts given f32 from little endian data format to big endian data format
/// Converts given f32 from native endian data format to big endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn TO_BIG_ENDIAN__REAL(input: f32) -> f32 {
f32::from_be_bytes(input.to_be_bytes())
f32::from_ne_bytes(input.to_be_bytes())
}

/// .
/// Converts given f32 from big endian data format to little endian data format
/// Converts given f32 from native endian data format to little endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn TO_LITTLE_ENDIAN__REAL(input: f32) -> f32 {
f32::from_le_bytes(input.to_le_bytes())
f32::from_ne_bytes(input.to_le_bytes())
}

/// .
/// Converts given f32 from big endian data format to little endian data format
/// Converts given f32 from big endian data format to native endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn FROM_BIG_ENDIAN__REAL(input: f32) -> f32 {
f32::from_le_bytes(input.to_le_bytes())
f32::from_be_bytes(input.to_ne_bytes())
}

/// .
/// Converts given f32 from little endian data format to big endian data format
/// Converts given f32 from little endian data format to native endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn FROM_LITTLE_ENDIAN__REAL(input: f32) -> f32 {
f32::from_be_bytes(input.to_be_bytes())
f32::from_le_bytes(input.to_ne_bytes())
}

/// .
/// Converts given f64 from little endian data format to big endian data format
/// Converts given f64 from native endian data format to big endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn TO_BIG_ENDIAN__LREAL(input: f64) -> f64 {
f64::from_be_bytes(input.to_be_bytes())
f64::from_ne_bytes(input.to_be_bytes())
}

/// .
/// Converts given f64 from big endian data format to little endian data format
/// Converts given f64 from native endian data format to little endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn TO_LITTLE_ENDIAN__LREAL(input: f64) -> f64 {
f64::from_le_bytes(input.to_le_bytes())
f64::from_ne_bytes(input.to_le_bytes())
}

/// .
/// Converts given f64 from big endian data format to little endian data format
/// Converts given f64 from big endian data format to native endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn FROM_BIG_ENDIAN__LREAL(input: f64) -> f64 {
f64::from_le_bytes(input.to_le_bytes())
f64::from_be_bytes(input.to_ne_bytes())
}

/// .
/// Converts given f64 from little endian data format to big endian data format
/// Converts given f64 from little endian data format to native endian data format
///
#[allow(non_snake_case)]
#[no_mangle]
pub fn FROM_LITTLE_ENDIAN__LREAL(input: f64) -> f64 {
f64::from_be_bytes(input.to_be_bytes())
f64::from_le_bytes(input.to_ne_bytes())
}
Loading

0 comments on commit 2da66ec

Please sign in to comment.