Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine 4 uint32_t ints into a whole 128 bit int and return

As part of a struct(let's call it ASM) in a header file there are declared four uint32_t ints.

uint32_t Result1; 
uint32_t Result2; 
uint32_t Result3; 
uint32_t Result4; 

I want to access these like this: ASM->Result1, ASM->Result2 etc and combine them into one 128 bit int with Result1 being bits 0-31 from the left, so in the end I'd have:

return 128bitint = Result1Result2Result3Result4;

How can this be done?

like image 382
Django Avatar asked Oct 21 '25 08:10

Django


2 Answers

I'd use union:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void) {
    union {
        struct {
            uint32_t v1;
            uint32_t v2;
            uint32_t v3;
            uint32_t v4;
        } __attribute__((packed));
        unsigned __int128 i128;
    } t128;
    t128.v1 = 0x22221111;
    t128.v2 = 0x44443333;
    t128.v3 = 0x66665555;
    t128.v4 = 0x88887777;

    printf("0x%016"PRIx64"%016"PRIx64"\n", (uint64_t)(t128.i128 >> 64), (uint64_t)t128.i128);

    return 0;
}

This gives:

0x88887777666655554444333322221111

as a result on intel (little-endian) architecture.

like image 179
nsilent22 Avatar answered Oct 22 '25 22:10

nsilent22


You need support for 128 bit integers for this.

with gcc on appropriate platforms, you can write this:

__uint128_t getval(const struct ASM *s) {
    return ((__uint128_t)s->Result1 <<  0) |
           ((__uint128_t)s->Result2 << 32) |
           ((__uint128_t)s->Result3 << 64) |
           ((__uint128_t)s->Result4 << 96);
}

Note that it is unclear what you mean by Result1 being bits 0-31 from the left. To clarify your specification, you must decide it Result1 are the low order 32 bits (intel architecture, little endian, my code above), or the high order 32 bits (big endian architecture).

like image 36
chqrlie Avatar answered Oct 22 '25 22:10

chqrlie