Bit Reduction in C ++

Suppose we have a binary file containing 32-bit numbers. Each 32-bit number is an instruction. My question is: is it possible to cut these bits into pieces 6 + 5 + 5 + 16 directly. Something like:

typedef struct _instruction { int op_code : 6; int reg_dest : 5; int reg_s1 : 5; int offset : 16; } INST, *PINST; int read_32_bits = read_next_instr(); INST i = (INST)read_32_bit; /* this would cut the bits into chunks*/ 
+7
source share
3 answers

Here is an answer that will work, be portable, and not cause undefined behavior on any compiler and be optimized efficiently enough:

 struct instruction { typedef unsigned int uint_t; explicit instruction(uint_t val) : val_(val) {} instruction(uint_t op_code, uint_t reg_dest, uint_t reg_s1, uint_t offset) : val_((op_code & 0x3fu << 26) | (reg_dest & 0x1fu << 21) | (reg_s1 & 0x1fu << 16) | (offset & 0xffffu)) { } uint_t op_code() const { return (val_ >> 26) & 0x3fu; } void op_code(uint_t newval) { val_ = (newval & 0x3fu << 26) | (val_ & 0x3ffffffu); } uint_t reg_dest() const { return (val_ >> 21) & 0x1fu; } void reg_dest(uint_t newval) { val_ = (newval & 0x1fu << 21) | (val_ & 0xfc1fffffu); } uint_t reg_s1() const { return (val_ >> 16) & 0x1fu; } void reg_s1(uint_t newval) { val_ = (newval & 0x1fu) << 16) | (val_ & 0xffe0ffffu); } uint_t offset() const { return (val_ >> 16) & 0xffffu; } void offset(uint_t newval) const { val_ = (newval & 0xffffu) | (val & 0xffff0000u); } uint_t &int_ref() { return val_; } uint_t int_ref() const { return val_; } private: uint_t val_; }; 

This allows access to all bit fields with very convenient notation. I think this is also a POD, which allows you to use it in several interesting ways. And a good compiler will do a pretty decent job of optimizing bit-sorting operations, especially if you have several calls to convenience functions in a string.

This is almost as good as having an overlay bit field. Firstly, this is a little more to determine.

Also, I changed the type to unsigned int , because if you play with bits, you really need just a represented number without a signed bit or something like that. Ideally, you should include the <cstdint> header and use ::std::uint32_t or something in the typedef at the top.

+3
source

Why not create a bit structure like yours and then place it inside the union? I reset the typedef, so it uses C ++ style definitions.

 struct instruction { int op_code : 6; int reg_dest : 5; int reg_s1 : 5; int offset :16; }; union INST { instruction a; uint32_t b; }; 

You can store / load 32-bit values โ€‹โ€‹using network functions:

 INST i; ib = ntohl(value); 

And now you can refer to bit fields without typecasting.

 if (iaop_code == XXX) 
+6
source

You can simply specify your structure as a pointer to the address of your 32-bit data.

 INST* i = (INST*)&read_32_bit; 

Then you can access your fields, for example:

 printf("opcode = %x", i->op_code); 
+4
source

All Articles