Is there any way to get a non 8-bit multiple data type?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I understand that this is sort of bizarre question, but I have a few thoughts about and it made me interested.
example:
how can I get 31 bit data type or something?)
right now I think that the answer is a flat out NO, you cannot.
maybe I'm wrong?
assembly memory types cpu-architecture low-level
|
show 2 more comments
I understand that this is sort of bizarre question, but I have a few thoughts about and it made me interested.
example:
how can I get 31 bit data type or something?)
right now I think that the answer is a flat out NO, you cannot.
maybe I'm wrong?
assembly memory types cpu-architecture low-level
1
You can always implement wrapping to whatever width manually. Do you have a specific high-level language in mind? Or assembly language? There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. en.wikipedia.org/wiki/36-bit On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
– Peter Cordes
Nov 16 '18 at 12:29
@PeterCordes I have x86 architecture and C in mind, how can I implement this type of wrapping, could you please share some keys for google?
– stronk_kisik
Nov 16 '18 at 12:31
1
Likea++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive.
– Peter Cordes
Nov 16 '18 at 12:33
@PeterCordes hmm, no this is not exactly what I was thinking about. could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit. so for transfer from one location to another it will transfer it like 16bit + (16 bit with shift by one bit) or something?
– stronk_kisik
Nov 16 '18 at 12:35
1
No, you can't do that. x86 has byte-addressable memory, not bit-addressable. There are machines with word-addressable memory, but none I've ever heard of with bit-addressable memory where you could just do a 16-bit load or store that wasn't aligned to byte boundaries. C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
– Peter Cordes
Nov 16 '18 at 12:43
|
show 2 more comments
I understand that this is sort of bizarre question, but I have a few thoughts about and it made me interested.
example:
how can I get 31 bit data type or something?)
right now I think that the answer is a flat out NO, you cannot.
maybe I'm wrong?
assembly memory types cpu-architecture low-level
I understand that this is sort of bizarre question, but I have a few thoughts about and it made me interested.
example:
how can I get 31 bit data type or something?)
right now I think that the answer is a flat out NO, you cannot.
maybe I'm wrong?
assembly memory types cpu-architecture low-level
assembly memory types cpu-architecture low-level
edited Nov 16 '18 at 15:01
Peter Cordes
134k18203342
134k18203342
asked Nov 16 '18 at 11:46
stronk_kisikstronk_kisik
296
296
1
You can always implement wrapping to whatever width manually. Do you have a specific high-level language in mind? Or assembly language? There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. en.wikipedia.org/wiki/36-bit On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
– Peter Cordes
Nov 16 '18 at 12:29
@PeterCordes I have x86 architecture and C in mind, how can I implement this type of wrapping, could you please share some keys for google?
– stronk_kisik
Nov 16 '18 at 12:31
1
Likea++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive.
– Peter Cordes
Nov 16 '18 at 12:33
@PeterCordes hmm, no this is not exactly what I was thinking about. could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit. so for transfer from one location to another it will transfer it like 16bit + (16 bit with shift by one bit) or something?
– stronk_kisik
Nov 16 '18 at 12:35
1
No, you can't do that. x86 has byte-addressable memory, not bit-addressable. There are machines with word-addressable memory, but none I've ever heard of with bit-addressable memory where you could just do a 16-bit load or store that wasn't aligned to byte boundaries. C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
– Peter Cordes
Nov 16 '18 at 12:43
|
show 2 more comments
1
You can always implement wrapping to whatever width manually. Do you have a specific high-level language in mind? Or assembly language? There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. en.wikipedia.org/wiki/36-bit On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
– Peter Cordes
Nov 16 '18 at 12:29
@PeterCordes I have x86 architecture and C in mind, how can I implement this type of wrapping, could you please share some keys for google?
– stronk_kisik
Nov 16 '18 at 12:31
1
Likea++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive.
– Peter Cordes
Nov 16 '18 at 12:33
@PeterCordes hmm, no this is not exactly what I was thinking about. could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit. so for transfer from one location to another it will transfer it like 16bit + (16 bit with shift by one bit) or something?
– stronk_kisik
Nov 16 '18 at 12:35
1
No, you can't do that. x86 has byte-addressable memory, not bit-addressable. There are machines with word-addressable memory, but none I've ever heard of with bit-addressable memory where you could just do a 16-bit load or store that wasn't aligned to byte boundaries. C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
– Peter Cordes
Nov 16 '18 at 12:43
1
1
You can always implement wrapping to whatever width manually. Do you have a specific high-level language in mind? Or assembly language? There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. en.wikipedia.org/wiki/36-bit On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
– Peter Cordes
Nov 16 '18 at 12:29
You can always implement wrapping to whatever width manually. Do you have a specific high-level language in mind? Or assembly language? There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. en.wikipedia.org/wiki/36-bit On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
– Peter Cordes
Nov 16 '18 at 12:29
@PeterCordes I have x86 architecture and C in mind, how can I implement this type of wrapping, could you please share some keys for google?
– stronk_kisik
Nov 16 '18 at 12:31
@PeterCordes I have x86 architecture and C in mind, how can I implement this type of wrapping, could you please share some keys for google?
– stronk_kisik
Nov 16 '18 at 12:31
1
1
Like
a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive.– Peter Cordes
Nov 16 '18 at 12:33
Like
a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive.– Peter Cordes
Nov 16 '18 at 12:33
@PeterCordes hmm, no this is not exactly what I was thinking about. could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit. so for transfer from one location to another it will transfer it like 16bit + (16 bit with shift by one bit) or something?
– stronk_kisik
Nov 16 '18 at 12:35
@PeterCordes hmm, no this is not exactly what I was thinking about. could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit. so for transfer from one location to another it will transfer it like 16bit + (16 bit with shift by one bit) or something?
– stronk_kisik
Nov 16 '18 at 12:35
1
1
No, you can't do that. x86 has byte-addressable memory, not bit-addressable. There are machines with word-addressable memory, but none I've ever heard of with bit-addressable memory where you could just do a 16-bit load or store that wasn't aligned to byte boundaries. C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
– Peter Cordes
Nov 16 '18 at 12:43
No, you can't do that. x86 has byte-addressable memory, not bit-addressable. There are machines with word-addressable memory, but none I've ever heard of with bit-addressable memory where you could just do a 16-bit load or store that wasn't aligned to byte boundaries. C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
– Peter Cordes
Nov 16 '18 at 12:43
|
show 2 more comments
1 Answer
1
active
oldest
votes
You can always implement wrapping to whatever width manually, like a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive, typically left-shift then arithmetic right shift unless the source width is supported specially by the language and/or hardware. (e.g. ARM has a signed-bitfield-extend instruction that can extract and sign-extend an arbitrary bitfield into a full integer register).
There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. https://en.wikipedia.org/wiki/36-bit. On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit.
No, you can't do that. There are no CPUs I'm aware of with bit-addressable memory. Any load/store has to be aligned to at least byte boundaries. (Byte-addressable memory is nearly universal these days, but some DSPs and some older CPUs like DEC Alpha only have/had word-addressable memory).
C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
e.g.
struct i31 {
int i:31; // note *signed* int
// 1 bit of padding is implicit on targets with 32-bit int
};
struct i31 inc(struct i31 x) {
x.i++;
return x;
}
int extend_to_int(struct i31 x) {
return x.i;
}
compiles for x86-64 to this (on the Godbolt compiler explorer).
I should probably have used gcc -fwrapv
to define the behaviour of signed overflow as 2's complement wraparound. I'm not sure what the C rules are for bitfields, whether assignment of a signed result to a signed bitfield still triggers signed overflow undefined-behaviour in ISO C and C++.
# gcc8.2 -O3
inc(i31):
lea eax, [rdi+1]
and edi, -2147483648 # keep the top bit of the input
and eax, 2147483647 # keep the low 31 bits of i++
or eax, edi # merge.
# IDK why it can't / doesn't just leave the carry-out in the padding
ret
extend_to_int(i31):
lea eax, [rdi+rdi] # left shift by 1 (and copy)
sar eax # shift arithmetic right (by 1)
ret
But ARM is neat and has better bitfield instructions than x86. (Nearly everything has better bitfield instructions than x86).
# ARM gcc7.2 -march=armv8-a -O3
inc(i31):
add r3, r0, #1
bfi r0, r3, #0, #31 # bitfield insert to preserve the high bit of the struct
bx lr
extend_to_int(i31):
sbfx r0, r0, #0, #31 # signed bitfield extract
bx lr
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
1
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
1
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337246%2fis-there-any-way-to-get-a-non-8-bit-multiple-data-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can always implement wrapping to whatever width manually, like a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive, typically left-shift then arithmetic right shift unless the source width is supported specially by the language and/or hardware. (e.g. ARM has a signed-bitfield-extend instruction that can extract and sign-extend an arbitrary bitfield into a full integer register).
There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. https://en.wikipedia.org/wiki/36-bit. On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit.
No, you can't do that. There are no CPUs I'm aware of with bit-addressable memory. Any load/store has to be aligned to at least byte boundaries. (Byte-addressable memory is nearly universal these days, but some DSPs and some older CPUs like DEC Alpha only have/had word-addressable memory).
C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
e.g.
struct i31 {
int i:31; // note *signed* int
// 1 bit of padding is implicit on targets with 32-bit int
};
struct i31 inc(struct i31 x) {
x.i++;
return x;
}
int extend_to_int(struct i31 x) {
return x.i;
}
compiles for x86-64 to this (on the Godbolt compiler explorer).
I should probably have used gcc -fwrapv
to define the behaviour of signed overflow as 2's complement wraparound. I'm not sure what the C rules are for bitfields, whether assignment of a signed result to a signed bitfield still triggers signed overflow undefined-behaviour in ISO C and C++.
# gcc8.2 -O3
inc(i31):
lea eax, [rdi+1]
and edi, -2147483648 # keep the top bit of the input
and eax, 2147483647 # keep the low 31 bits of i++
or eax, edi # merge.
# IDK why it can't / doesn't just leave the carry-out in the padding
ret
extend_to_int(i31):
lea eax, [rdi+rdi] # left shift by 1 (and copy)
sar eax # shift arithmetic right (by 1)
ret
But ARM is neat and has better bitfield instructions than x86. (Nearly everything has better bitfield instructions than x86).
# ARM gcc7.2 -march=armv8-a -O3
inc(i31):
add r3, r0, #1
bfi r0, r3, #0, #31 # bitfield insert to preserve the high bit of the struct
bx lr
extend_to_int(i31):
sbfx r0, r0, #0, #31 # signed bitfield extract
bx lr
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
1
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
1
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
add a comment |
You can always implement wrapping to whatever width manually, like a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive, typically left-shift then arithmetic right shift unless the source width is supported specially by the language and/or hardware. (e.g. ARM has a signed-bitfield-extend instruction that can extract and sign-extend an arbitrary bitfield into a full integer register).
There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. https://en.wikipedia.org/wiki/36-bit. On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit.
No, you can't do that. There are no CPUs I'm aware of with bit-addressable memory. Any load/store has to be aligned to at least byte boundaries. (Byte-addressable memory is nearly universal these days, but some DSPs and some older CPUs like DEC Alpha only have/had word-addressable memory).
C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
e.g.
struct i31 {
int i:31; // note *signed* int
// 1 bit of padding is implicit on targets with 32-bit int
};
struct i31 inc(struct i31 x) {
x.i++;
return x;
}
int extend_to_int(struct i31 x) {
return x.i;
}
compiles for x86-64 to this (on the Godbolt compiler explorer).
I should probably have used gcc -fwrapv
to define the behaviour of signed overflow as 2's complement wraparound. I'm not sure what the C rules are for bitfields, whether assignment of a signed result to a signed bitfield still triggers signed overflow undefined-behaviour in ISO C and C++.
# gcc8.2 -O3
inc(i31):
lea eax, [rdi+1]
and edi, -2147483648 # keep the top bit of the input
and eax, 2147483647 # keep the low 31 bits of i++
or eax, edi # merge.
# IDK why it can't / doesn't just leave the carry-out in the padding
ret
extend_to_int(i31):
lea eax, [rdi+rdi] # left shift by 1 (and copy)
sar eax # shift arithmetic right (by 1)
ret
But ARM is neat and has better bitfield instructions than x86. (Nearly everything has better bitfield instructions than x86).
# ARM gcc7.2 -march=armv8-a -O3
inc(i31):
add r3, r0, #1
bfi r0, r3, #0, #31 # bitfield insert to preserve the high bit of the struct
bx lr
extend_to_int(i31):
sbfx r0, r0, #0, #31 # signed bitfield extract
bx lr
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
1
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
1
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
add a comment |
You can always implement wrapping to whatever width manually, like a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive, typically left-shift then arithmetic right shift unless the source width is supported specially by the language and/or hardware. (e.g. ARM has a signed-bitfield-extend instruction that can extract and sign-extend an arbitrary bitfield into a full integer register).
There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. https://en.wikipedia.org/wiki/36-bit. On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit.
No, you can't do that. There are no CPUs I'm aware of with bit-addressable memory. Any load/store has to be aligned to at least byte boundaries. (Byte-addressable memory is nearly universal these days, but some DSPs and some older CPUs like DEC Alpha only have/had word-addressable memory).
C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
e.g.
struct i31 {
int i:31; // note *signed* int
// 1 bit of padding is implicit on targets with 32-bit int
};
struct i31 inc(struct i31 x) {
x.i++;
return x;
}
int extend_to_int(struct i31 x) {
return x.i;
}
compiles for x86-64 to this (on the Godbolt compiler explorer).
I should probably have used gcc -fwrapv
to define the behaviour of signed overflow as 2's complement wraparound. I'm not sure what the C rules are for bitfields, whether assignment of a signed result to a signed bitfield still triggers signed overflow undefined-behaviour in ISO C and C++.
# gcc8.2 -O3
inc(i31):
lea eax, [rdi+1]
and edi, -2147483648 # keep the top bit of the input
and eax, 2147483647 # keep the low 31 bits of i++
or eax, edi # merge.
# IDK why it can't / doesn't just leave the carry-out in the padding
ret
extend_to_int(i31):
lea eax, [rdi+rdi] # left shift by 1 (and copy)
sar eax # shift arithmetic right (by 1)
ret
But ARM is neat and has better bitfield instructions than x86. (Nearly everything has better bitfield instructions than x86).
# ARM gcc7.2 -march=armv8-a -O3
inc(i31):
add r3, r0, #1
bfi r0, r3, #0, #31 # bitfield insert to preserve the high bit of the struct
bx lr
extend_to_int(i31):
sbfx r0, r0, #0, #31 # signed bitfield extract
bx lr
You can always implement wrapping to whatever width manually, like a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive, typically left-shift then arithmetic right shift unless the source width is supported specially by the language and/or hardware. (e.g. ARM has a signed-bitfield-extend instruction that can extract and sign-extend an arbitrary bitfield into a full integer register).
There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. https://en.wikipedia.org/wiki/36-bit. On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit.
No, you can't do that. There are no CPUs I'm aware of with bit-addressable memory. Any load/store has to be aligned to at least byte boundaries. (Byte-addressable memory is nearly universal these days, but some DSPs and some older CPUs like DEC Alpha only have/had word-addressable memory).
C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
e.g.
struct i31 {
int i:31; // note *signed* int
// 1 bit of padding is implicit on targets with 32-bit int
};
struct i31 inc(struct i31 x) {
x.i++;
return x;
}
int extend_to_int(struct i31 x) {
return x.i;
}
compiles for x86-64 to this (on the Godbolt compiler explorer).
I should probably have used gcc -fwrapv
to define the behaviour of signed overflow as 2's complement wraparound. I'm not sure what the C rules are for bitfields, whether assignment of a signed result to a signed bitfield still triggers signed overflow undefined-behaviour in ISO C and C++.
# gcc8.2 -O3
inc(i31):
lea eax, [rdi+1]
and edi, -2147483648 # keep the top bit of the input
and eax, 2147483647 # keep the low 31 bits of i++
or eax, edi # merge.
# IDK why it can't / doesn't just leave the carry-out in the padding
ret
extend_to_int(i31):
lea eax, [rdi+rdi] # left shift by 1 (and copy)
sar eax # shift arithmetic right (by 1)
ret
But ARM is neat and has better bitfield instructions than x86. (Nearly everything has better bitfield instructions than x86).
# ARM gcc7.2 -march=armv8-a -O3
inc(i31):
add r3, r0, #1
bfi r0, r3, #0, #31 # bitfield insert to preserve the high bit of the struct
bx lr
extend_to_int(i31):
sbfx r0, r0, #0, #31 # signed bitfield extract
bx lr
edited Nov 16 '18 at 13:32
answered Nov 16 '18 at 13:19
Peter CordesPeter Cordes
134k18203342
134k18203342
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
1
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
1
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
add a comment |
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
1
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
1
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
Wow, this is awesome answer!
– stronk_kisik
Nov 16 '18 at 13:22
1
1
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
there are many microcontrollers with bit-addressable memory. For example Intel 8051 has a special 128-bit region that are bit-addressable
– phuclv
Nov 16 '18 at 16:22
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
@phuclv: and you can do byte or word loads from it? Not just single-element bitfield stuff?
– Peter Cordes
Nov 16 '18 at 16:25
1
1
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
that 128-bit region is a subset of the address space, so you can still load a byte from it like normal. 8051 is an 8-bit MCU so it can't load any types wider than that
– phuclv
Nov 16 '18 at 16:38
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337246%2fis-there-any-way-to-get-a-non-8-bit-multiple-data-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You can always implement wrapping to whatever width manually. Do you have a specific high-level language in mind? Or assembly language? There are CPUs with words and/or bytes that aren't multiples of 8 bits, e.g. PDP-10 has 36-bit words. en.wikipedia.org/wiki/36-bit On that system, the natural size is 36 bits, and 32 bits would be a non-standard type that requires extra instructions.
– Peter Cordes
Nov 16 '18 at 12:29
@PeterCordes I have x86 architecture and C in mind, how can I implement this type of wrapping, could you please share some keys for google?
– stronk_kisik
Nov 16 '18 at 12:31
1
Like
a++; a&=0x7fffffff;
to mask the result to 31 bits and implement an unsigned 31-bit type. Redoing sign-extension to a wider type is more expensive.– Peter Cordes
Nov 16 '18 at 12:33
@PeterCordes hmm, no this is not exactly what I was thinking about. could I have some kind of data structures that will be store in memory like 31 bit -> 31 bit -> 31 bit and can I made CPU work with them as 31 bit. so for transfer from one location to another it will transfer it like 16bit + (16 bit with shift by one bit) or something?
– stronk_kisik
Nov 16 '18 at 12:35
1
No, you can't do that. x86 has byte-addressable memory, not bit-addressable. There are machines with word-addressable memory, but none I've ever heard of with bit-addressable memory where you could just do a 16-bit load or store that wasn't aligned to byte boundaries. C with bitfields will emulate narrower types but with padding; you can't avoid having the compiler-generated asm touch the padding.
– Peter Cordes
Nov 16 '18 at 12:43