<div dir="ltr"><div class="gmail_quote"><div class="HOEnZb"><div class="h5"><div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div><div class="m_7732079787046340095m_-2329744927696985779gmail_signature"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Good Day<br></div><div><br></div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial">Is any work in the LLVM development community are pointed to expanding IR model to support bit fields and arbitrary endianness manipulations?</div><br></div><div>I'm looking on LLVM as a backend for data language compilator. </div><div><br></div><div>I'm working with IoT (Lora) and has a problem with data format specification for a wide variety of end-node devices (M2M/SmartHome).<br></div><div>Due to the fact that the size of the package is small (50..200 bytes), it is only permissible to apply maximally compact binary data exchange protocols.<br></div><div><br></div><div><div>As an example, here some sample in C:</div></div><div><br></div><div><div>#include <stdint.h></div><div>#include <stdbool.h></div><div><br></div><div><div>struct __attribute__((packed)) {</div><div><span style="white-space:pre-wrap">       </span>uint8_t <span style="white-space:pre-wrap">                </span>A;</div><div><span style="white-space:pre-wrap">       </span>__attribute__((scalar_storage_<wbr>order("big")))</div><div><span style="white-space:pre-wrap">        </span>int16_t <span style="white-space:pre-wrap">                </span>B;</div><div><span style="white-space:pre-wrap">       </span>float   <span style="white-space:pre-wrap">              </span>C;</div><div><span style="white-space:pre-wrap">       </span>unsigned int<span style="white-space:pre-wrap">    </span>D:3;</div><div><span style="white-space:pre-wrap">     </span>  signed int<span style="white-space:pre-wrap">   </span>E:7;</div><div><span style="white-space:pre-wrap">     </span>  bool<span style="white-space:pre-wrap">                 </span>F;</div><div>} Packet;</div></div><div><br></div><div>void encode() {</div><div><span style="white-space:pre-wrap">    </span>Packet.A=1; Packet.B=2; <span style="white-space:pre-wrap">        </span>// integers</div><div><span style="white-space:pre-wrap">      </span>Packet.C=3; <span style="white-space:pre-wrap">                            </span>// float</div><div><span style="white-space:pre-wrap"> </span>Packet.E=4; Packet.E=-5;<span style="white-space:pre-wrap">        </span>// bit field integers</div><div><span style="white-space:pre-wrap">    </span>Packet.F = true;<span style="white-space:pre-wrap">                        </span>// boolean</div><div>}</div></div><div><br></div><div>The problem is this definition must be really platform independent: the same code must work identically on Cortex-M, ARM9 and MIPS, and north side (x86_64 primarily).</div><div>So I need <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">attributes supported by </span>GCC6: __attribute__((packed)) for structures and <span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">__attribute__((big/littlee<wbr>ndian)) for struct fields.</span><br></div><div><span style="text-align:start;text-indent:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">As a variant, I'm going to write some special DDL scheme compiler alike ASN.1 compilers (with a human-readable syntax for 1C programmers).</span></div><div><br></div><div><div dir="ltr">Looking on code generated by clang, it looks like LLVM IR not only has no support for endianness attributes</div><div dir="ltr">but also has pure support for bit fields manipulations widely used in most embedded software</div><div dir="ltr">(and some MCU and  FPGA-synthesized cores have bit field operations in hardware).</div></div><div>As an example, generated IR uses in-compiled and/or bitmasking should be replaced with special bit-fields operations with ui3, si7 arbitrary length integers.</div><div><br></div><div><br></div><div><div>; ModuleID = 'bitstruct.c'</div><div>target datalayout = "e-m:e-i64:64-f80:128-n8:16:32<wbr>:64-S128"</div><div>target triple = "x86_64-pc-linux-gnu"</div><div><br></div><div>%struct.anon = type <{ i8, i16, float, i16, i8 }></div><div><br></div><div>@Packet = common global %struct.anon zeroinitializer, align 1</div><div><br></div><div>; Function Attrs: nounwind uwtable</div><div>define void @encode() #0 {</div><div>  store i8 1, i8* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 0), align 1</div><div>  store i16 2, i16* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 1), align 1</div><div>  store float 3.000000e+00, float* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 2), align 1</div><div>  %1 = load i16, i16* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 3), align 1</div><div>  %2 = and i16 %1, -1017</div><div>  %3 = or i16 %2, 32</div><div>  store i16 %3, i16* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 3), align 1</div><div>  %4 = load i16, i16* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 3), align 1</div><div>  %5 = and i16 %4, -1017</div><div>  %6 = or i16 %5, 984</div><div>  store i16 %6, i16* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 3), align 1</div><div>  store i8 1, i8* getelementptr inbounds (%struct.anon, %struct.anon* @Packet, i32 0, i32 4), align 1</div><div>  ret void</div><div>}</div><div><br></div><div>!0 = !{!"clang version 3.8.1-24 (tags/RELEASE_381/final)"}<br></div></div><div><br></div><div><br></div><div>------------------------------<br><span style="font-size:12.8px">With best regards, Dmitry Ponyatov, </span>Icbcom, IoT/embedded engineer, tel. +7 917 10 10 818</div></div></div></div></div></div></div></div>
</div>
</div><br></div>
</div></div></div><br></div>