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

1.7k Views Asked by At

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?

2

There are 2 best solutions below

9
On BEST ANSWER

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.

0
On

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).