Marc, I would like to ask your opinion on an implementation question.
If I want to load a 8 or 16 bit machine from memory into a 32/64 bit register, it seems I would have to do a mov from memory to the lower 8 or 16 bits of the register. However, one problem presents itself: possibly, the remainder of the register was already storing some other 32/64 bit value, and so the upper bits might be nonzero. This would imply that if I want to load a value smaller than the register, I would have to zero-out the register with xor first.
Do you know of a more efficient way of achieving this with just one instruction?
- Maxime
Afficher les réponses par date
On 2010-10-07, at 5:32 PM, Maxime Chevalier-Boisvert wrote:
Marc, I would like to ask your opinion on an implementation question.
If I want to load a 8 or 16 bit machine from memory into a 32/64 bit register, it seems I would have to do a mov from memory to the lower 8 or 16 bits of the register. However, one problem presents itself: possibly, the remainder of the register was already storing some other 32/64 bit value, and so the upper bits might be nonzero. This would imply that if I want to load a value smaller than the register, I would have to zero-out the register with xor first.
Do you know of a more efficient way of achieving this with just one instruction?
Yes... one instruction... reverse engineering can be fun!
% gcc -arch x86_64 -S -fomit-frame-pointer -O3 load.c;fgrep "(%rdi)" load.s movsbl (%rdi),%eax movswl (%rdi),%eax movl (%rdi), %eax movsbq (%rdi),%rax movswq (%rdi),%rax movslq (%rdi),%rax movq (%rdi), %rax % gcc -arch i386 -S -fomit-frame-pointer -O3 load.c;fgrep "(%eax)" load.s movsbl (%eax),%eax movswl (%eax),%eax movl (%eax), %eax % cat load.c typedef char s8; typedef short s16; typedef int s32; typedef long long s64;
s32 load_s8_s32(s8 *ptr) { return *ptr; } s32 load_s16_s32(s16 *ptr) { return *ptr; } s32 load_s32_s32(s32 *ptr) { return *ptr; } #ifndef i386 s64 load_s8_s64(s8 *ptr) { return *ptr; } s64 load_s16_s64(s16 *ptr) { return *ptr; } s64 load_s32_s64(s32 *ptr) { return *ptr; } s64 load_s64_s64(s64 *ptr) { return *ptr; } #endif
Those names didn't bring up much relevant information on Google, but I assume they're these:
http://pdos.csail.mit.edu/6.828/2009/readings/i386/MOVZX.htm http://pdos.csail.mit.edu/6.828/2009/readings/i386/MOVSX.htm
We'd need both the zero and sign extended variants into the back-end. I guess those should be added to Erick's TODO list, with a lesser priority than imul and the register allocator glitch.
- Maxime
On 10-10-07 11:19 PM, Marc Feeley wrote:
On 2010-10-07, at 5:32 PM, Maxime Chevalier-Boisvert wrote:
Marc, I would like to ask your opinion on an implementation question.
If I want to load a 8 or 16 bit machine from memory into a 32/64 bit register, it seems I would have to do a mov from memory to the lower 8 or 16 bits of the register. However, one problem presents itself: possibly, the remainder of the register was already storing some other 32/64 bit value, and so the upper bits might be nonzero. This would imply that if I want to load a value smaller than the register, I would have to zero-out the register with xor first.
Do you know of a more efficient way of achieving this with just one instruction?
Yes... one instruction... reverse engineering can be fun!
% gcc -arch x86_64 -S -fomit-frame-pointer -O3 load.c;fgrep "(%rdi)" load.s movsbl (%rdi),%eax movswl (%rdi),%eax movl (%rdi), %eax movsbq (%rdi),%rax movswq (%rdi),%rax movslq (%rdi),%rax movq (%rdi), %rax % gcc -arch i386 -S -fomit-frame-pointer -O3 load.c;fgrep "(%eax)" load.s movsbl (%eax),%eax movswl (%eax),%eax movl (%eax), %eax % cat load.c typedef char s8; typedef short s16; typedef int s32; typedef long long s64;
s32 load_s8_s32(s8 *ptr) { return *ptr; } s32 load_s16_s32(s16 *ptr) { return *ptr; } s32 load_s32_s32(s32 *ptr) { return *ptr; } #ifndef i386 s64 load_s8_s64(s8 *ptr) { return *ptr; } s64 load_s16_s64(s16 *ptr) { return *ptr; } s64 load_s32_s64(s32 *ptr) { return *ptr; } s64 load_s64_s64(s64 *ptr) { return *ptr; } #endif
Tachyon-list mailing list Tachyon-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/tachyon-list
On 2010-10-07, at 11:36 PM, Maxime Chevalier-Boisvert wrote:
Those names didn't bring up much relevant information on Google, but I assume they're these:
http://pdos.csail.mit.edu/6.828/2009/readings/i386/MOVZX.htm http://pdos.csail.mit.edu/6.828/2009/readings/i386/MOVSX.htm
Yes.
Marc
On 2010-10-08, at 12:05 AM, Marc Feeley wrote:
On 2010-10-07, at 11:36 PM, Maxime Chevalier-Boisvert wrote:
Those names didn't bring up much relevant information on Google, but I assume they're these:
http://pdos.csail.mit.edu/6.828/2009/readings/i386/MOVZX.htm http://pdos.csail.mit.edu/6.828/2009/readings/i386/MOVSX.htm
Yes.
Marc
By the way, I prefer this documentation from Intel:
http://www3.intel.com/Assets/PDF/manual/253666.pdf http://www3.intel.com/Assets/PDF/manual/253667.pdf
and I sometimes use these tables as a quick reference:
http://ref.x86asm.net/geek32.html http://ref.x86asm.net/geek64.html
Marc