I made a few tests on Ubuntu 64 bits (arch x86_64) with variations on a
small test program:
var
E2: Byte= 3;
E1: LongWord= 1;
E: QWord;
begin
E:= (1000*E1) shl E2;
writeln( 'E2', E2);
writeln( 'E1', E1);
writeln( 'E', E);
end.
In the assembly window, shl is computed on 64 bits %rax, I get :
project1.lpr:132 E:= (1000*E1) shl E2;
00000000004011B2 8b05d8f50c00 mov 0xcf5d8(%rip),%eax # 0x4d0790 <TC_$P$PROJECT1_$$_E1>
00000000004011B8 4869c0e8030000 imul $0x3e8,%rax,%rax 00000000004011BF 0fb60dbaf50c00 movzbl 0xcf5ba(%rip),%ecx # 0x4d0780 <TC_$P$PROJECT1_$$_E2> 00000000004011C6 48d3e0 shl %cl,%rax 00000000004011C9 48890580b51000 mov %rax,0x10b580(%rip) # 0x50c750 <U_$P$PROJECT1_$$_E>
Changing the formula to E:= E1 shl E2, shl computed on 32 bits %edx, (I don't understand the "and %edx,%edx", may be just to clear the carry ?) I get :
project1.lpr:132 E:= E1 shl E2;
00000000004011B2 0fb605c7f50c00 movzbl 0xcf5c7(%rip),%eax # 0x4d0780 <TC_$P$PROJECT1_$$_E2> 00000000004011B9 8b15d1f50c00 mov 0xcf5d1(%rip),%edx # 0x4d0790 <TC_$P$PROJECT1_$$_E1>
00000000004011BF 89c1 mov %eax,%ecx 00000000004011C1 d3e2 shl %cl,%edx 00000000004011C3 21d2 and %edx,%edx 00000000004011C5 48891584b51000 mov %rdx,0x10b584(%rip) # 0x50c750 <U_$P$PROJECT1_$$_E>
Changing E1 to QWord ( E1: QWord= 1; ), shl is computed on 64 bits %rax, I get :
project1.lpr:132 E:= E1 shl E2;
00000000004011B2 0fb605c7f50c00 movzbl 0xcf5c7(%rip),%eax # 0x4d0780 <TC_$P$PROJECT1_$$_E2> 00000000004011B9 488b15d0f50c00 mov 0xcf5d0(%rip),%rdx # 0x4d0790 <TC_$P$PROJECT1_$$_E1>
00000000004011C0 4889c1 mov %rax,%rcx 00000000004011C3 48d3e2 shl %cl,%rdx 00000000004011C6 48891583b51000 mov %rdx,0x10b583(%rip) # 0x50c750 <U_$P$PROJECT1_$$_E>