I am using Ubuntu on x86_64. I first generate non-optimized WebAssembly code from clang. The WebAssembly code is compiled into machine code using wasmtime which uses cranelift as compiling backend.
I am doing a simple matrix multiplication:
int first[m][n], second[p][q], multiply[m][q];
Here is the machine code for the first loop out of the three loops
for ( int c = 0 ; c < m ; c++ ){}
generated by wasmtime. I found many necessary instructions, but I cannot find a calling convention from cranelift to necessitate these instructions.
- My questions are mainly around - esiregister, does the compiler has to use it for get- c's value using- esi. Must- esi's value be preserved? Otherwise why not directly use it to do- cmp. If yes, why in- 1adwe use esi to store 0 which is from- r14dwhich is from- eax? Also, the 0 value is preserved in- eax, is eax also a non-volatile register?
- In - 1b0, if we directly- cmp esi, r12dand set esi 0 or 1 according to results, there is no need to complicated steps- 1ba-- 1c3Right?
- If I generate optimized machine code from optimized WebAssembly using - wasm32-wasi-clang -O2- I dont think cranelift by itself provides an optimization flag though, I find the machine code much shorter but also hard to understand. Are there any ways to help me read optimized machine code? AND Also, if my machine code is from the non-optimized wasm. According to the analysis we just did on this for loop example, is it ok to say that I have found the flaws of wasm compiler, cranelift? 
Thank you so much for your help! I know the code may not be enjoyable to read, you can zoom in the page to see the picture
  195: rex mov DWORD PTR [rbx+rdx*1+0xc],eax         ;int c = 0, eax preserves 0. 
  19a: rex mov edx,ecx                              ; edx = ecx = [rdi+0x60]  + 0xffffffc0  
  19d: rex mov esi,DWORD PTR [rbx+rdx*1+0xc]         ; esi = [0xc]  = c,  get c into register? 
  1a2: mov    r12d,DWORD PTR [rbx+rdx*1+0x38]       ; r12d = m 
  1a7: mov    r14d,eax               ;r14d = eax = 0         
  
  1aa: rex mov eax,esi               ;     eax = esi = [c] = c [[!!! abuse register, you can directly use esi for cmp, eax remains 0, instead of store eax value 0 in r14d, 
                                                        ;use eax for cmp, and at the end restore eax value 0 by esi (esi = r14d)]
  1ad: mov    esi,r14d               ; esi = r14d = 0;  
  1b0: cmp    eax,r12d               ; cmp if eax (c) < r12d (m), if yes, al = 1, otherwise al = 0; {can use esi?? cmp usage ?}
  1b3: setl   al               
  1b6: movzx  eax,al               ; eax = al = 1 (if <)   [movzx already uses zero-extension!!]
  1ba: and    eax,0x1              ; eax = 1 if (if <). [al is low 8 bits, set only supports one byte, Byte Set On Condition (setcc), why not directrly set r12d also has low 8 bit !!!! ]
  1bd: mov    r12d,eax             ; r12d = eax = 1 (if <)
  1c0: rex mov eax,esi                ;eax = esi =  r14d = 0;   [restore eax = 0, but why use esi rather than r14d, actually you dont even need to restore eax 
                                                        ;if choose to replace eax with another register in CMP   ]
  1c3: mov    esi,r12d             ; esi = r12d =  eax = 1 (if <) [!!if directly use esi for CMP, there is no need of mov 12d, eax then mov esi, r12d]
  1c6: rex test esi,esi ;if esi=0 jump
  1c9: je     2f0 <_wasm_function_3+0x227>
